⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic_ad75.v

📁 I2C温度传感器ADT75的控制源码 使用verilog 状态机实现 易入门
💻 V
📖 第 1 页 / 共 2 页
字号:
module IIC_AD75(CLK,EN,SCL,SDA,DATA_OUT,END_IIC,ST,MT,i2c_state); 

input CLK,EN; 
output SCL;
inout SDA; 
output	[7:0]	DATA_OUT;
output	END_IIC,ST,MT;
output	[3:0] i2c_state;

reg SCL;
reg SDA_buf;//SDA输入输出数据缓存 
reg	END_IIC,ST,MT; 

reg link; //SDA输出标志 
reg phase0,phase1,phase2,phase3;//一个scl时钟周期的四个相位阶段,将一个scl周期分为4段 phase0对应scl的上升沿时刻,phase2对应scl的下降沿时刻,phase1对应scl高电平的中间时刻,phase3对应scl低电平的中间时刻, 

reg[7:0] clk_div;//分频计数器
reg[20:0] delay_60ms;//延时计数器 
reg h_delay;//延时开始

reg	[1:0] main_state; 

reg	[2:0] state_cnt; 
reg	[3:0] i2c_state;//对i2c操作的状态 W_tos,  W_ths,   W_con,   W_add,  R_tep
reg	[5:0] inner_state;//i2c每一操作阶段内部状态 

reg[7:0] readData_reg;//读回数据的寄存

reg [15:0] r16_tos;//0110 0100 0000 0000;//100C
reg [15:0] r16_ths;//0000 0000 0000 0000;//0C
reg [7:0] r8_con;//8'b0010 0110;
reg [7:0] r8_mod;//8'b0000 0100;
reg [14:0]	d_cnt;
//---------------------------------------------------------------------------------------------------------------------------------------------

parameter   stt	=6'b000000, //开始 
			w1		=6'b000001, //第1位 
			w2		=6'b000010,//第2位 
			w3		=6'b000011, //第3位 
			w4		=6'b000100, //第4位 
			w5		=6'b000101, //第5位 
			w6		=6'b000110, //第6位 
			w7		=6'b000111, //第7位 
			w8		=6'b001000, //第8位 	
			
			ack		=6'b001001, //确认位 
			
			R1		=6'b001010,
			R2		=6'b001011,
			R3		=6'b001100,
			R4		=6'b001101,
			R5		=6'b001110,
			R6		=6'b001111,
			R7		=6'b010000,
			R8		=6'b010001,
							
			D1		=6'b010010,
			D2		=6'b010011,
			D3		=6'b010100,
			D4		=6'b010101,
			D5		=6'b010110,
			D6		=6'b010111,
			D7		=6'b011000,
			D8		=6'b011001,	
			D9		=6'b011010,
			D10		=6'b011011,
			D11		=6'b011100,
			D12		=6'b011101,
			D13		=6'b011110,
			D14		=6'b011111,
			D15		=6'b100000,
			D16		=6'b100001,
			
						
			RDdata1		=6'b100010,
			RDdata2		=6'b100011,
			RDdata3		=6'b100100,
			RDdata4		=6'b100101,
			RDdata5		=6'b100110,
			RDdata6		=6'b100111,
			RDdata7		=6'b101000,
			RDdata8		=6'b101001,	
			RDdata9		=6'b101010,
			RDdata10	=6'b101011,
			RDdata11	=6'b101100,
			RDdata12	=6'b101101,
			RDdata13	=6'b101110,
			RDdata14	=6'b101111,
			RDdata15	=6'b110000,
			RDdata16	=6'b110001,
								
			ack_1		=6'b110010,	
			ack_2		=6'b110011,
			ack_3		=6'b110100,
			ack_4		=6'b110101,		
			stop		=6'b110110; //结束位 
			
parameter div_parameter = 100;// 分频系数,ADT75最大支持400K时钟速率 					
//---------------------------------------------------------------------------------------------------------------------------------------------

assign SDA=link ? SDA_buf:1'bz;
assign DATA_OUT =  readData_reg ;

//------------------------------------------------------SCL-----------------------------------------------------------------------------------


always@(posedge CLK or negedge EN) 
begin 
	if(!EN) 
		begin 
			clk_div<=0;
			phase0<=0; 
			phase1<=0; 
			phase2<=0; 
			phase3<=0; 
		end 
	else 
		begin 
				if(clk_div!=div_parameter-1) 
						clk_div<=clk_div+1; 
			else 
				clk_div<=0; 
				if(phase0) 
					phase0<=0; 
			else 
				if(clk_div==99) 
					phase0<=1; 
				if(phase1) 
					phase1<=0; 
			else 
				if(clk_div==24) 
					phase1<=1; 
				if(phase2) 
					phase2<=0; 
			else 
				if(clk_div==49) 
					phase2<=1; 
				if(phase3) 
					phase3<=0; 
			else 
				if(clk_div==74) 
					phase3<=1; 
		end 
end 

//-----------------------------------ADT75操作部分-----------------------------------------------



always@(posedge CLK) 
begin 
		if(!EN) 
			begin 		
				main_state<=2'b00; 
				i2c_state<=4'b0000; 
				inner_state<=stt; 
				link<=0; 
				readData_reg<=0; 
				SCL <= 1'bz;
				SDA_buf<=1;
				state_cnt<=3'b000;			
				r16_tos<=16'b0110010000000000;//100C
				r16_ths<=16'b0000000000000000;//0C
				r8_con<=8'b00100110;
				r8_mod<=8'b00000100;
				ST<=0;
				MT<=0;

			end 
		else 
			begin 
				case(main_state) 
				2'b00: 	//等待读写要求 
						begin 
							SDA_buf<=1; 
							link<=0; 
							inner_state<=stt; 
							i2c_state<=4'b0000; 
							SCL <= 0;
														
								if(EN) 
									begin
										main_state<=2'b10;
									end
								else
									main_state<=2'b00;
						end
										
				2'b10: 
					begin //WRITE ADT75 
							if(phase0) 
								SCL<=1; 
						else 
							if(phase2)
								SCL<=0;	
		case(i2c_state)				
//iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii                                                                              
// 											W_add   state1                                                                                
                                                                                                                               			
	4'b0000: 	//ini_add						
		begin 
			case(inner_state) 
				
						stt: begin 						
								if(phase1) 
									begin 
										link<=1; 
										SDA_buf<=0; 
										
									end 
								if(phase3&link) 
									begin 							
										inner_state<=w1; 
										SDA_buf<=1; //------------------------------1
										link<=1; 
						
									end 
							end 
						w1: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------0
									link<=1; 
									inner_state<=w2; 
								end 
						w2: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------0
									link<=1; 
									inner_state<=w3; 
								end 
						w3: 
							if(phase3) 
								begin 
									SDA_buf<=1; //------------------------------1
									link<=1; 
									inner_state<=w4; 
								end 
						w4: 
							if(phase3) 
								begin 
									SDA_buf<=0; //-----------------------------A2
									link<=1; 
									inner_state<=w5; 
								end 
						w5: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------A1
									link<=1; 
									inner_state<=w6; 
								end 
						w6: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------A0
									link<=1; 
									inner_state<=w7; 
								end 
						w7: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------R/W
									link<=1; 
									inner_state<=w8; 
								end 
						w8: 
							if(phase3) 
								begin 
									link<=0; //SDA TURN 
									inner_state<=ack; 
								end 
						ack: 
							begin 
								if(phase0) 
									SDA_buf<=SDA; 
								if(phase1) 
									begin 
										if(SDA_buf==1) 
											begin
											main_state<=2'b00; 
											end
									end 
								if(phase3) 
									begin 
										link<=1; 
										SDA_buf<=0;//---------------------------------------------------------------------0 for the 4 register adder's NUM0 all 0 add[7]
										inner_state<=R1; 										
										i2c_state<=4'b0001;//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@	
		
																								
									end 
							end 
				endcase

	end

	//==========================================================

4'b0001: //w_add
		begin 
			
			case(inner_state) 
						R1: 
							if(phase3) 
								begin 
									link<=1; 
									SDA_buf<=0; //------------------------------add6
									inner_state<=R2;
									
								end 
						R2: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------add5
									link<=1; 
									inner_state<=R3; 
								end 
						R3: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------add4
									link<=1; 
									inner_state<=R4; 
								end 
						R4: 
							if(phase3) 
								begin 
									SDA_buf<=0; //-----------------------------add3
									link<=1; 
									inner_state<=R5; 
								end 
						R5: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------add2
									link<=1; 
									inner_state<=R6; 
								end 
						R6: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------add1
									link<=1; 
									inner_state<=R7; 
								end 
						R7: 
							if(phase3) 
								begin 
									SDA_buf<=0; //------------------------------add0
									link<=1; 
									inner_state<=R8; 
									
								end 
						R8: 
							if(phase3) 
								begin 
									link<=0; //SDA TURN 
									inner_state<=ack_2; 
									
								end 
	
						ack_2: 

								begin 
								
									if(phase0) 
										SDA_buf<=SDA; 
									if(phase1) 
										begin 
											if(SDA_buf==1) 
												begin
													main_state<=2'b00; //********************************
												end
										end 
									if(phase3) 
										begin 
											link<=1; 
											SDA_buf<=0; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2
											inner_state<=ack_4;
											
										end 
								end 														
						ack_4:		begin
								
									if(phase1)
									begin
										link<=1;
										SDA_buf<=1;
										end 
									if(phase3)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -