差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
温度计 [2017/03/10 16:02]
zhijun 创建
温度计 [2017/03/13 14:55] (当前版本)
zhijun
行 1: 行 1:
 ======基于小脚丫STEP MXO2的温度显示系统====== ======基于小脚丫STEP MXO2的温度显示系统======
-=====项目简介=====+=====一、项目简介=====
 基于小脚丫STEP MXO2的温度显示系统的核心控制模块为小脚丫STEP MXO2开发板,采用由MicroUSB输入的5V供电,温度传感器选用的是DALLAS的经典传感器——DS18B20,一个封装和常见三极管(TO-92)相同的温度传感器,而显示模块采用LCD1602,相信读者对这两个模块一定是极为熟悉。 基于小脚丫STEP MXO2的温度显示系统的核心控制模块为小脚丫STEP MXO2开发板,采用由MicroUSB输入的5V供电,温度传感器选用的是DALLAS的经典传感器——DS18B20,一个封装和常见三极管(TO-92)相同的温度传感器,而显示模块采用LCD1602,相信读者对这两个模块一定是极为熟悉。
  
-=====项目框图=====+=====二、项目框图===== 
 +{{ ::​框图.png ?600 |}} 
 +====1.控制核心==== 
 +温度计项目控制核心为小脚丫STEP MXO2 V2版本FPGA开发板,FPGA芯片为Lattice Semiconductor的MachXO2 400HC系列FPGA。 
 +====2.温度采集模块==== 
 +温度采集模块采用Dallas的经典产品——DS18B20,是一个高精度,占用空间小,硬件连接简单,价格低廉的数字温度传感器,采用单总线驱动方式,更为节省开发板资源。 
 +====3.温度显示系统==== 
 +温度显示模块采用集成了ASCII字库的LCD1602,省去了自建字库的麻烦。 
 + 
 +=====三、硬件电路图===== 
 +{{ ::​电路图.png?​800 |}} 
 +温度计的硬件电路比较简单,首先在供电方面,作为控制核心的小脚丫开发板由于具备完善的下载与供电方案,故不必在设计下载电路,只需要一根MicroUSB数据线即可满足整体系统的供电与下载; 
 +\\ 
 +在温度采集部分,DS18B20共有三个引脚,我们参照硬件手册,可发现该芯片的1号引脚接地,2号引脚为数据信号DQ,接到小脚丫的任意引脚上(下图接到了小脚丫STEP MXO2的“SI”引脚上),3号引脚为电源脚,参照手册,DS18B20的输入电压为3.0V-5.5V,此处我们采用了3.3V供电。 
 +\\ 
 +温度显示部分,LCD1602共有16个引脚,下图为LCD1602的引脚简介,对应连接即可: 
 +{{ ::​lcd1602引脚定义.png?​400 |}} 
 + 
 +=====四、Verilog代码===== 
 +====1.Verilog代码:​LCD1602显示部分==== 
 +------ 
 +<code verilog>​ 
 + 
 +// -------------------------------------------------------------------- 
 +// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ 
 +// -------------------------------------------------------------------- 
 +// Module:​LCD1602  
 +//  
 +// Author: STEP 
 +//  
 +// Description:​ Display the temperature by LCD1602 
 +//  
 +// Web: www.stepfpga.com 
 +//      
 +// -------------------------------------------------------------------- 
 +// Code Revision History : 
 +// -------------------------------------------------------------------- 
 +// Version: |Mod. Date:   ​|Changes Made: 
 +// V1.0     ​|2017.3.8 ​    ​|Initial ver 
 +// -------------------------------------------------------------------- 
 + 
 +module LCD_1602(clk,​LCD_EN,​RS,​RW,​DB8,​one_wire,​rst);​ 
 + 
 + input ​  ​clk,​rst; ​       //​系统时钟与复位,系统时钟==12M  
 + output ​ LCD_EN;​ //​LCD_EN为LCD模块的使能信号(下降沿触发) 
 + output ​ RS;​ //​RS=0时为写指令;RS=1时为写数据 
 + output ​ RW;​ //​RW=0时对LCD模块执行写操作;RW=1时对LCD模块执行读操作 
 + output ​ [7:0] DB8; //​8位指令或数据总线  
 + inout one_wire;​ //​例化DS18B20模块单总线 
 +  
 + reg    RS; 
 + reg LCD_EN_Sel;​ 
 + reg [7:0] DB8; 
 + reg [127:​0] data_row1;​ 
 + reg [127:​0] data_row2;​ 
 +  
 + reg [7:​0] result_unit;​ 
 + reg [7:0] result_decade;​ 
 + reg [7:0]   ​result_hundred;​ 
 + reg [7:0]   ​result_dec;​ 
 + reg [7:​0] result_dec2;​ 
 + reg [7:​0] result_dec3;​ 
 + reg [7:0] result_dec4;​ 
 + reg [7:​0] sign;​ 
 +  
 + reg [3:0] num_unit; 
 + reg [3:0] num_decade;​ 
 + reg [3:0] num_hundred;​ 
 + reg [3:0] num_dec; 
 + reg [3:0] num_dec2; 
 + reg [3:0] num_dec3; 
 + reg [3:0] num_dec4;​ //​若想显示小数点第四位,添加至显示内容并调整即可 
 +  
 + reg[19:0] cnt_ref;​ //​LCD1602更新计数器 
 + reg ref;​ //​更新标志位 
 +  
 + always@(posedge clk_2ms) //​产生LCD1602更新所需信号 
 + begin  
 + if(cnt_ref==220)  
 + begin 
 + cnt_ref<​=0;​ 
 + ref<​=1;​ 
 + ref<​=0;​  
 + end 
 + else  
 + begin 
 + cnt_ref<​=cnt_ref+1;​ 
 + ref<​=1;​ 
 + end  
 + end 
 + 
 + always@(*) //​1602输入数据接口处理 
 + begin  
 + case(num_unit) //​个位 
 + 4'​d0:​result_unit<​=8'​b00110000;​ 
 + 4'​d1:​result_unit<​=8'​b00110001;​ 
 + 4'​d2:​result_unit<​=8'​b00110010;​ 
 + 4'​d3:​result_unit<​=8'​b00110011;​ 
 + 4'​d4:​result_unit<​=8'​b00110100;​ 
 + 4'​d5:​result_unit<​=8'​b00110101;​ 
 + 4'​d6:​result_unit<​=8'​b00110110;​ 
 + 4'​d7:​result_unit<​=8'​b00110111;​ 
 + 4'​d8:​result_unit<​=8'​b00111000;​ 
 + 4'​d9:​result_unit<​=8'​b00111001;​ 
 + default:​result_unit<​=result_unit;​ 
 + endcase 
 +  
 + case(num_decade) //​十位 
 + 4'​d0:​result_decade<​=8'​b00110000;​ 
 + 4'​d1:​result_decade<​=8'​b00110001;​ 
 + 4'​d2:​result_decade<​=8'​b00110010;​ 
 + 4'​d3:​result_decade<​=8'​b00110011;​ 
 + 4'​d4:​result_decade<​=8'​b00110100;​ 
 + 4'​d5:​result_decade<​=8'​b00110101;​ 
 + 4'​d6:​result_decade<​=8'​b00110110;​ 
 + 4'​d7:​result_decade<​=8'​b00110111;​ 
 + 4'​d8:​result_decade<​=8'​b00111000;​ 
 + 4'​d9:​result_decade<​=8'​b00111001;​ 
 + default:​result_decade<​=result_decade;​ 
 + endcase 
 +  
 + case(num_hundred) //​百位 
 + 4'​d0:​result_hundred<​=8'​b00110000;​ 
 + 4'​d1:​result_hundred<​=8'​b00110001;​ 
 + 4'​d2:​result_hundred<​=8'​b00110010;​ 
 + 4'​d3:​result_hundred<​=8'​b00110011;​ 
 + 4'​d4:​result_hundred<​=8'​b00110100;​ 
 + 4'​d5:​result_hundred<​=8'​b00110101;​ 
 + 4'​d6:​result_hundred<​=8'​b00110110;​ 
 + 4'​d7:​result_hundred<​=8'​b00110111;​ 
 + 4'​d8:​result_hundred<​=8'​b00111000;​ 
 + 4'​d9:​result_hundred<​=8'​b00111001;​ 
 + default:​result_hundred<​=result_hundred;​ 
 + endcase  
 +  
 + case(num_dec) //​小数位 
 + 4'​d0:​result_dec<​=8'​b00110000;​ 
 + 4'​d1:​result_dec<​=8'​b00110001;​ 
 + 4'​d2:​result_dec<​=8'​b00110010;​ 
 + 4'​d3:​result_dec<​=8'​b00110011;​ 
 + 4'​d4:​result_dec<​=8'​b00110100;​ 
 + 4'​d5:​result_dec<​=8'​b00110101;​ 
 + 4'​d6:​result_dec<​=8'​b00110110;​ 
 + 4'​d7:​result_dec<​=8'​b00110111;​ 
 + 4'​d8:​result_dec<​=8'​b00111000;​ 
 + 4'​d9:​result_dec<​=8'​b00111001;​ 
 + default:​result_dec<​=result_dec;​ 
 + endcase  
 +  
 + case(num_dec4) //​小数位 
 + 4'​d0:​result_dec4<​=8'​b00110000;​ 
 + 4'​d1:​result_dec4<​=8'​b00110001;​ 
 + 4'​d2:​result_dec4<​=8'​b00110010;​ 
 + 4'​d3:​result_dec4<​=8'​b00110011;​ 
 + 4'​d4:​result_dec4<​=8'​b00110100;​ 
 + 4'​d5:​result_dec4<​=8'​b00110101;​ 
 + 4'​d6:​result_dec4<​=8'​b00110110;​ 
 + 4'​d7:​result_dec4<​=8'​b00110111;​ 
 + 4'​d8:​result_dec4<​=8'​b00111000;​ 
 + 4'​d9:​result_dec4<​=8'​b00111001;​ 
 + default:​result_dec4<​=result_dec4;​ 
 + endcase  
 +  
 + case(num_dec2) //​小数位 
 + 4'​d0:​result_dec2<​=8'​b00110000;​ 
 + 4'​d1:​result_dec2<​=8'​b00110001;​ 
 + 4'​d2:​result_dec2<​=8'​b00110010;​ 
 + 4'​d3:​result_dec2<​=8'​b00110011;​ 
 + 4'​d4:​result_dec2<​=8'​b00110100;​ 
 + 4'​d5:​result_dec2<​=8'​b00110101;​ 
 + 4'​d6:​result_dec2<​=8'​b00110110;​ 
 + 4'​d7:​result_dec2<​=8'​b00110111;​ 
 + 4'​d8:​result_dec2<​=8'​b00111000;​ 
 + 4'​d9:​result_dec2<​=8'​b00111001;​ 
 + default:​result_dec2<​=result_dec2;​ 
 + endcase  
 +  
 + case(num_dec3) //​小数位 
 + 4'​d0:​result_dec3<​=8'​b00110000;​ 
 + 4'​d1:​result_dec3<​=8'​b00110001;​ 
 + 4'​d2:​result_dec3<​=8'​b00110010;​ 
 + 4'​d3:​result_dec3<​=8'​b00110011;​ 
 + 4'​d4:​result_dec3<​=8'​b00110100;​ 
 + 4'​d5:​result_dec3<​=8'​b00110101;​ 
 + 4'​d6:​result_dec3<​=8'​b00110110;​ 
 + 4'​d7:​result_dec3<​=8'​b00110111;​ 
 + 4'​d8:​result_dec3<​=8'​b00111000;​ 
 + 4'​d9:​result_dec3<​=8'​b00111001;​ 
 + default:​result_dec3<​=result_dec3;​ 
 + endcase  
 + end  
 + 
 + 
 +//​-------------------------------------//​ 
 +//​输入时钟12MHz ​ 输出周期2ms 
 +//​division12MHz_2ms.v 
 + reg [15:​0]count;​ 
 + reg clk_2ms; 
 + always @ (posedge clk) 
 + begin 
 + if(count == 16'​d12_000) 
 + begin 
 + count <= 16'​b1;​ 
 + clk_2ms <= ~clk_2ms; 
 + end 
 + else ​  
 + count <= count + 1'​b1;​ 
 + end 
 +//​---------------------------------------//​ 
 + 
 + reg     ​[127:​0] Data_Buf; ​  ​ //​液晶显示的数据缓存 
 + reg     [4:0] disp_count;​  
 + reg     [3:0] state;​ //​状态机 
 + 
 + parameter ​  ​Clear_Lcd = 4'​b0000; ​ //​清屏并光标复位  
 + parameter Set_Disp_Mode = 4'​b0001;​ //​设置显示模式:8位2行5x7点阵 ​   
 + parameter Disp_On = 4'​b0010;​ //​显示器开、光标不显示、光标不允许闪烁 
 + parameter Shift_Down = 4'​b0011; ​ //​文字不动,光标自动右移 
 + parameter Write_Addr = 4'​b0100; ​  ​ //​写入显示起始地址 
 + parameter Write_Data_First = 4'​b0101;​ //​写入第一行显示的数据 ​     
 + parameter Write_Data_Second = 4'​b0110;​ //​写入第二行显示的数据  
 + assign ​ RW = 1'​b0; ​ //​RW=0时对LCD模块执行写操作(一直保持写状态) 
 + assign ​ LCD_EN = LCD_EN_Sel ? clk_2ms : 1'​b0;​ //​通过LCD_EN_Sel信号来控制LCD_EN的开启与关闭 
 + 
 + 
 +//​--------------------------------显示模块----------------------------//​ 
 + always @(posedge clk_2ms ​ or negedge rst  or negedge ref) 
 + begin 
 +    //​-----------------------复位并更新显示数据--------------------//​ 
 + 
 + if(!rst || !ref) 
 + begin 
 + state <= Clear_Lcd; ​ //​复位:清屏并光标复位 ​   
 + RS <= 1'​b1; ​         //​复位:RS=1时为读指令; ​                       
 + DB8 <= 8'​b0; ​        ​ //​复位:使DB8总线输出全0 
 + LCD_EN_Sel <= 1'​b0; ​ //​复位:关夜晶使能信号 
 + disp_count <= 5'​b0;​  
 + data_row1 <= {   ​ //​输入第一行要显示的数据  
 + 8'​b01010011, ​   //S 
 + 8'​b01010100,​ //​T 
 + 8'​b01000101,​ //​E 
 + 8'​b01010000,​ //​P 
 + 8'​b00100000,​ //​SPACE 
 + 8'​b01000110,​ //​F 
 + 8'​b01010000,​ //​P 
 + 8'​b01000111,​ //​G 
 + 8'​b01000001,​ //​A 
 + 8'​b00100000,​ //​SPACE 
 + 8'​b00100000,​ //​SPACE  
 + 8'​b00100000,​ //​SPACE 
 + 8'​b00100000,​ //​SPACE 
 + 8'​b00100000, ​     //​SPACE ​      
 + 8'​b00100000,​ //​SPACE 
 + 8'​b00100000 //​SPACE 
 + };​ 
 + data_row2 <= { 8'​b00100000,​ //​输入第二行要显示的数据 
 + 8'​b00100000,​ //​SPACE 
 + 8'​b01010100,​ //T 
 + 8'​b01100101,​ //​e 
 + 8'​b01101101,​ //m 
 + 8'​b00111010,​ //​冒号 
 + sign,​  
 + result_unit,​  
 + result_decade, ​         
 + result_hundred, ​        
 + 8'​b00101110,​ //​. 
 + result_dec, ​        
 + result_dec2, ​    
 + result_dec3,​ 
 + 8'​hdf,​ //​℃ 
 + 8'​b01000011 
 + 
 + };​ 
 + end 
 + else  
 + begin 
 + case(state) ​  
 +//​-------------------------------初始化LCD------------------------------------// ​        
 + 
 +     Clear_Lcd : begin LCD_EN_Sel <= 1'​b1;​ //​开使能 
 +  ​ RS <= 1'​b0;​ //​写指令 
 +  ​ DB8 <= 8'​b00000001; ​ //​清屏并光标复位 
 +  ​     state <= Set_Disp_Mode;​ end 
 + Set_Disp_Mode : begin DB8 <= 8'​b00111000; ​ //​设置显示模式:8位2行5x8点阵  
 +  ​ state <= Disp_On; ​      end 
 +   Disp_On : begin DB8 <= 8'​b00001100; ​  ​ //​显示器开、光标不显示、光标不允许闪烁  
 +  ​ state <= Shift_Down;​  ​ end 
 +    ​Shift_Down : begin DB8 <= 8'​b00000110; ​   //​文字不动,光标自动右移 ​    
 +  ​ state <= Write_Addr; ​   end 
 +  ​  
 +//​---------------------------------显示循环------------------------------------//​  
 +     
 +    ​Write_Addr : begin RS <= 1'​b0;​ //​写指令 
 +  ​ DB8 <= 8'​b10000000; ​    //​写入第一行显示起始地址:第一行第1个位置 ​    
 +  ​ Data_Buf <= data_row1; ​    ​ //​将第一行显示的数据赋给Data_First_Buf 
 +  ​     state <= Write_Data_First;​ end  
 + Write_Data_First : begin //​写第一行数据  
 + if(disp_count == 16)    //​disp_count等于15时表示第一行数据已写完 
 + begin 
 + RS <= 1'​b0;​ //​写指令 
 + DB8 <= 8'​b11000000; ​    //​送入写第二行的指令,​第2行第1个位置 
 + disp_count <= 5'b0; //​计数清0 
 + Data_Buf ​  <= data_row2;​ //​将第2行显示的数据赋给Data_First_Buf 
 + state ​    <= Write_Data_Second;​end ​  //​写完第一行进入写第二行状态 
 + else //​没写够16字节 
 + begin 
 + RS <= 1'​b1; ​   //​RS=1表示写数据 
 + DB8 <= Data_Buf[127:​120];​ 
 + Data_Buf <= (Data_Buf << 8); 
 + disp_count <= disp_count + 1'​b1;​ 
 + state <= Write_Data_First;​ end end 
 + Write_Data_Second : begin //​写第二行数据 
 + if(disp_count == 16)//​数据发送完毕 
 + begin 
 + RS <= 1'​b0;​ //​写指令 
 + DB8 <= 8'​b10000000; ​    //​写入第一行显示起始地址:第一行第1个位置 
 + disp_count <= 5'b0;  
 + state <= Write_Addr; ​  ​ //​重新循环 
 + end 
 + else 
 + begin 
 + RS <= 1'​b1;​ 
 + DB8 <= Data_Buf[127:​120];​ 
 + Data_Buf <= (Data_Buf << 8); 
 + disp_count <= disp_count + 1'​b1;​ 
 + state <= Write_Data_Second;​  
 + end end 
 +//​--------------------------------------------------------------------------//​  
 +   default :  state <= Clear_Lcd; //​若state为其他值,则将state置为Clear_Lcd  
 + endcase  
 + end 
 + end 
 + 
 +//​--------------------------------------------------------------------------//​ 
 + 
 + 
 + 
 +wire clk_in; 
 +wire rst_n_in; 
 +wire [15:0] data_out;  
 +wire tem_flag=data_out[15:​11]?​1'​b0:​1'​b1;​ 
 +wire [10:0] tem_code=tem_flag?​data_out[10:​0]:​(~data_out[10:​0])+1'​b1;​  
 +wire [20:0] tem_data=tem_code*625;​ 
 +reg [27:0] bcd_code; 
 +DS18B20Z DS18B20Z_uut 
 +(     
 +.one_wire(one_wire),​ 
 +.clk_in(clk),​ 
 +.rst_n_in(rst),​ 
 +.data_out(data_out) 
 +); 
 + 
 + 
 + 
 + reg [48:0] shift_reg; ​   
 +always@(posedge clk or negedge rst)begin ​      
 +  
 + shift_reg= {28'​h0,​tem_data};​  
 + 
 + if(!rst) bcd_code = 0;       
 + else  
 + begin ​         
 + repeat(21)//​repeat B_SIZE times 
 + begin ​                                
 + if (shift_reg[24:​21] >= 5) shift_reg[24:​21] = shift_reg[24:​21] + 2'​b11;​ 
 + if (shift_reg[28:​25] >= 5) shift_reg[28:​25] = shift_reg[28:​25] + 2'​b11;​ 
 + if (shift_reg[32:​29] >= 5) shift_reg[32:​29] = shift_reg[32:​29] + 2'​b11;​ 
 + if (shift_reg[36:​33] >= 5) shift_reg[36:​33] = shift_reg[36:​33] + 2'​b11;​ 
 + if (shift_reg[40:​37] >= 5) shift_reg[40:​37] = shift_reg[40:​37] + 2'​b11;​ 
 + if (shift_reg[44:​41] >= 5) shift_reg[44:​41] = shift_reg[44:​41] + 2'​b11;​ 
 + if (shift_reg[48:​45] >= 5) shift_reg[48:​45] = shift_reg[48:​45] + 2'​b11;​ 
 + if (tem_flag==0) sign<​=8'​b00101101;​ 
 + if (tem_flag==1) sign<​=8'​b00100000;​ 
 + shift_reg = shift_reg << 1;  
 + end ​         
 + bcd_code=shift_reg[48:​21]; ​   
 + 
 + num_unit <​= bcd_code[27:​24];​ 
 + num_decade <​= bcd_code[23:​20];​ 
 + num_hundred<​= bcd_code[19:​16];​ 
 + num_dec <​= bcd_code[15:​12];​ 
 + num_dec2 <​= ​ bcd_code[11:​8];​ 
 + num_dec3 <​= ​ bcd_code[7:​4];​ 
 + num_dec4 <​= ​ bcd_code[3:​0];​ 
 +  
 +  
 + end   
 +end 
 +     
 + 
 +endmodule 
 + 
 +  
 + 
 + 
 +</​code>​ 
 + 
 + 
 + 
 + 
 + 
 +====2.温度采集部分==== 
 +------ 
 +<code verilog>​ 
 +// -------------------------------------------------------------------- 
 +// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ 
 +// -------------------------------------------------------------------- 
 +// Module:​DS18B20Z  
 +//  
 +// Author: Step 
 +//  
 +// Description:​ Drive DS18B20Z to get temperature code 
 +//  
 +// Web: www.stepfpga.com 
 +//  
 +// -------------------------------------------------------------------- 
 +// Code Revision History : 
 +// -------------------------------------------------------------------- 
 +// Version: |Mod. Date:   ​|Changes Made: 
 +// V1.0     ​|2015/​11/​11 ​  ​|Initial ver 
 +// -------------------------------------------------------------------- 
 +module DS18B20Z 
 +
 + input clk_in,​ //​ system clock 
 + input rst_n_in,​ //​ system reset, active low 
 + inout one_wire,​ //​ ds18b20z one-wire-bus 
 + output reg [15:​0] data_out //​ ds18b20z data_out 
 +); 
 +  
 + 
 +     
 + 
 + localparam IDLE = 3'​d0;​ 
 + localparam MAIN = 3'​d1;​ 
 + localparam INIT = 3'​d2;​ 
 + localparam WRITE = 3'​d3;​ 
 + localparam READ = 3'​d4;​ 
 + localparam DELAY = 3'​d5;​ 
 +  
 + //generate clk_1mhz clock 
 + reg clk_1mhz;​ 
 + reg [2:​0] cnt_1mhz;​ 
 + always@(posedge clk_in or negedge rst_n_in) begin 
 + if(!rst_n_in) begin 
 + cnt_1mhz <= 3'​d0;​ 
 + clk_1mhz <= 1'​b0;​ 
 + end else if(cnt_1mhz >= 3'd5) begin 
 + cnt_1mhz <= 3'​d0;​ 
 + clk_1mhz <= ~clk_1mhz;​ 
 + end else begin 
 + cnt_1mhz <= cnt_1mhz + 1'​b1;​ 
 + end 
 + end 
 +  
 + reg one_wire_buffer;​ 
 + reg [3:​0] cnt_main;​ 
 + reg [7:​0] data_wr;​ 
 + reg [7:​0] data_wr_buffer;​ 
 + reg [2:​0] cnt_init;​ 
 + reg [19:​0] cnt_delay;​ 
 + reg [19:​0] num_delay;​ 
 + reg [5:​0] cnt_write;​ 
 + reg [5:​0] cnt_read;​ 
 + reg [15:​0] temperature;​ 
 + reg [7:​0] temperature_buffer;​ 
 + reg [2:0] state = IDLE; 
 + reg [2:0] state_back = IDLE; 
 + always@(posedge clk_1mhz or negedge rst_n_in) begin 
 + if(!rst_n_in) begin 
 + state <= IDLE; 
 + state_back <= IDLE; 
 + cnt_main <= 4'​d0;​ 
 + cnt_init <= 3'​d0;​ 
 + cnt_write <= 6'​d0;​ 
 + cnt_read <= 6'​d0;​ 
 + cnt_delay <= 20'​d0;​ 
 + one_wire_buffer <= 1'​bz;​ 
 + temperature <= 16'​h0;​ 
 + end else begin 
 + case(state) 
 + IDLE:​begin 
 + state <= MAIN; 
 + state_back <= MAIN; 
 + cnt_main <= 4'​d0;​ 
 + cnt_init <= 3'​d0;​ 
 + cnt_write <= 6'​d0;​ 
 + cnt_read <= 6'​d0;​ 
 + cnt_delay <= 20'​d0;​ 
 + one_wire_buffer <= 1'​bz;​ 
 + end 
 + MAIN:​begin 
 + if(cnt_main >= 4'd11) cnt_main <= 1'​b0;​ 
 + else cnt_main <= cnt_main + 1'​b1;​ 
 + case(cnt_main) 
 + 4'​d0:​ begin state <= INIT; end 
 + 4'​d1:​ begin data_wr <= 8'​hcc;​state <= WRITE; end 
 + 4'​d2:​ begin data_wr <= 8'​h44;​state <= WRITE; end 
 + 4'​d3:​ begin num_delay <= 20'​d750000;​state <= DELAY;​state_back <= MAIN; end 
 +  
 + 4'​d4:​ begin state <= INIT; end 
 + 4'​d5:​ begin data_wr <= 8'​hcc;​state <= WRITE; end 
 + 4'​d6:​ begin data_wr <= 8'​hbe;​state <= WRITE; end 
 +  
 + 4'​d7:​ begin state <= READ; end 
 + 4'​d8:​ begin temperature[7:​0] <= temperature_buffer;​ end 
 +  
 + 4'​d9:​ begin state <= READ; end 
 + 4'​d10:​ begin temperature[15:​8] <= temperature_buffer;​ end 
 +  
 + 4'​d11:​ begin state <= IDLE;​data_out <= temperature;​ end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + INIT:​begin 
 + if(cnt_init >= 3'd6) cnt_init <= 1'​b0;​ 
 + else cnt_init <= cnt_init + 1'​b1;​ 
 + case(cnt_init) 
 + 3'​d0:​ begin one_wire_buffer <= 1'b0; end 
 + 3'​d1:​ begin num_delay <= 20'​d500;​state <= DELAY;​state_back <= INIT; end 
 + 3'​d2:​ begin one_wire_buffer <= 1'bz; end 
 + 3'​d3:​ begin num_delay <= 20'​d100;​state <= DELAY;​state_back <= INIT; end 
 + 3'​d4:​ begin if(one_wire) state <= IDLE; else state <= INIT; end 
 + 3'​d5:​ begin num_delay <= 20'​d400;​state <= DELAY;​state_back <= INIT; end 
 + 3'​d6:​ begin state <= MAIN; end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + WRITE:​begin 
 + if(cnt_write >= 6'd50) cnt_write <= 1'​b0;​ 
 + else cnt_write <= cnt_write + 1'​b1;​ 
 + case(cnt_write) 
 + //​lock data_wr 
 + 6'​d0:​ begin data_wr_buffer <= data_wr; end 
 + //​write bit 0 
 + 6'​d1:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d2:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d3:​ begin one_wire_buffer <= data_wr_buffer[0];​ end 
 + 6'​d4:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d5:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d6:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 1 
 + 6'​d7:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d8:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d9:​ begin one_wire_buffer <= data_wr_buffer[1];​ end 
 + 6'​d10:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d11:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d12:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 2 
 + 6'​d13:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d14:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d15:​ begin one_wire_buffer <= data_wr_buffer[2];​ end 
 + 6'​d16:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d17:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d18:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 3 
 + 6'​d19:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d20:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d21:​ begin one_wire_buffer <= data_wr_buffer[3];​ end 
 + 6'​d22:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d23:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d24:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 4 
 + 6'​d25:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d26:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d27:​ begin one_wire_buffer <= data_wr_buffer[4];​ end 
 + 6'​d28:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d29:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d30:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 5 
 + 6'​d31:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d32:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d33:​ begin one_wire_buffer <= data_wr_buffer[5];​ end 
 + 6'​d34:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d35:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d36:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 6 
 + 6'​d37:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d38:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d39:​ begin one_wire_buffer <= data_wr_buffer[6];​ end 
 + 6'​d40:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d41:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d42:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​write bit 7 
 + 6'​d43:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d44:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d45:​ begin one_wire_buffer <= data_wr_buffer[7];​ end 
 + 6'​d46:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d47:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d48:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= WRITE; end 
 + //​back to main 
 + 6'​d49:​ begin num_delay <= 20'​d80;​state <= DELAY;​state_back <= WRITE; end 
 + 6'​d50:​ begin state <= MAIN; end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + READ:​begin 
 + if(cnt_read >= 6'd48) cnt_read <= 1'​b0;​ 
 + else cnt_read <= cnt_read + 1'​b1;​ 
 + case(cnt_read) 
 + //​read bit 0 
 + 6'​d0:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d1:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d2:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d3:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d4:​ begin temperature_buffer[0] <= one_wire; end 
 + 6'​d5:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 1 
 + 6'​d6:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d7:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d8:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d9:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d10:​ begin temperature_buffer[1] <= one_wire; end 
 + 6'​d11:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 2 
 + 6'​d12:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d13:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d14:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d15:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d16:​ begin temperature_buffer[2] <= one_wire; end 
 + 6'​d17:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 3 
 + 6'​d18:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d19:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d20:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d21:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d22:​ begin temperature_buffer[3] <= one_wire; end 
 + 6'​d23:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 4 
 + 6'​d24:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d25:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d26:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d27:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d28:​ begin temperature_buffer[4] <= one_wire; end 
 + 6'​d29:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 5 
 + 6'​d30:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d31:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d32:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d33:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d34:​ begin temperature_buffer[5] <= one_wire; end 
 + 6'​d35:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 6 
 + 6'​d36:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d37:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d38:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d39:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d40:​ begin temperature_buffer[6] <= one_wire; end 
 + 6'​d41:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​read bit 7 
 + 6'​d42:​ begin one_wire_buffer <= 1'b0; end 
 + 6'​d43:​ begin num_delay <= 20'​d2;​state <= DELAY;​state_back <= READ; end 
 + 6'​d44:​ begin one_wire_buffer <= 1'bz; end 
 + 6'​d45:​ begin num_delay <= 20'​d10;​state <= DELAY;​state_back <= READ; end 
 + 6'​d46:​ begin temperature_buffer[7] <= one_wire; end 
 + 6'​d47:​ begin num_delay <= 20'​d55;​state <= DELAY;​state_back <= READ; end 
 + //​back to main 
 + 6'​d48:​ begin state <= MAIN; end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + DELAY:​begin 
 + if(cnt_delay >= num_delay) begin 
 + cnt_delay <= 1'​b0;​ 
 + state <= state_back;  
 + end else cnt_delay <= cnt_delay + 1'​b1;​ 
 + end 
 + endcase 
 + end 
 + end 
 +  
 + assign one_wire = one_wire_buffer;​ 
 +  
 +endmodule 
 + 
 +</​code>​