[笔记]学习I2C总线

任务:AmbiGlow从XILINX器件上移植到Altera器件上

AmbiGlow从XILINX器件上移植到Altera器件上,要注意加法器和除法器IP核上的不同,尽量使它们输出的信号一致,这样就可以不用改程序,保持整体不变。除法器,Altera器件是可以一个时钟就算法商和余数,而Xilinx则要latency8个时钟,因此Altera需要添加使能信号使输出信号保持一致。而加法器,Altera器件采用组合逻辑实现时没有使能信号和复位信号,若用时序逻辑实现时就可以添加但结果就与Xilinx的不一样,不过后面看了仿真觉得组合逻辑缺少两个信号还是可以实现相同功能。


2013-03-22   08:46:09

对于I2C的Master和Slave模式的程序,我编写如附件所示:http://www.cnblogs.com/zlh840/admin/Files.aspx。希望对园友有帮助!

编写I2C Slave模块时,我一心想的是FPGA作为从器件,内部需要定义几个寄存器,看了下面这张表后,我想应该也定义15个寄存器。这样地址参数15个,写数据寄存器15个,读数据寄存器15个。整个程序就用到大量的寄存器,功能虽然实现了,但资料占用情况不理想,且内部有许多地方是重复的,因此有必要对程序进行优化处理。后面在Ronnie的指引下,他说下面这些I2C指令最长的也就用到3个寄存器,其他寄存器可以重复用这3个。所以Slave模块的输出端口只需要地址寄存器和3个数据寄存器及指令结束脉冲即可,有了这些,Ronnie那边自然会根据需要的去处理。

Slave的读写过程是(1)Start(2)Chip地址[6:0], w_r_flag, A(3)Reg地址[7:0], A(4)Reg1地址[7:0], A(5)Reg_Data1[7:0], A(6)Reg_Data2[7:0], A(7)Reg_Data3[7:0], A(8)Stop  其中步骤6,7是根据Reg1地址[7:0]来判断是否需要。

sLD3 set IIC command to FPGA    
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
0x34 17 2 6    
0x34 17 40 3    
0x34 17 0 1    
0x34 17 0 2    
0x34 17 50 XX XX XX
           
0x34 17 0 2    
0x34 17 51 XX XX XX
0x34 17 52 XX XX XX
0x34 17 53 XX XX XX
           
0x34 17 0 0    

2013-03-21    11:27:43

比起ISE工具,我更喜欢Quartus的编辑方式,感觉查找和替换特别好用。其他编辑工具如gVim7.3之前没用过,有点用不来,不习惯。文件对比工具BCompare也没经常用。还有一个C语言查看工具。

最近完成了AmbiGlow中I2C的Master部分,代码主要是参考夏宇闻《数字系统设计-verilog实现》第245页,书中的代码CLK与SCL的关系是固定的(2倍),需要修改成适合任何外部时钟进行采样处理,其中SCL的范围是100KHZ到400KHZ。修改方法是对外部时钟CLK进行分频处理,同时标出SCL的高电平、低电平、上升沿和下降沿,再将程序中的相关部分做修改就可用,部分代码如下所示。

/---------------------------------------------  
//分频部分:根据外部时钟产生串行时钟SCL。 
//---------------------------------------------
//`include "scl_gen.v"
//parameter CNT_DVI=8;
//scl_gen
//#(.CNT_DVI(CNT_DVI))
//scl_gen_inst(
//  .clk(clk),
//  .rst_n(rst_n),
//  .scl(scl)
//);
reg[2:0] cnt; // cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间
reg[9:0] cnt_delay; //250循环计数,产生iic所需要的时钟400KHZ--100MHZ
reg scl_r;  //时钟脉冲寄存器

//`define CNT_DIV 8//1000//When clk is 100MHZ, scl is 100KHZ by 1000 //default 500
//parameter CNT_DIV = 16;
parameter CNT_HIG = (CNT_DIV>>2)-1'b1; //125-1=124 by 500
parameter CNT_NEG = (CNT_DIV>>1)-1'b1; //250-1=249 by 500
parameter CNT_LOW = (CNT_DIV>>2)+(CNT_DIV>>1)-1'b1; //125+250-1=374 by 500
parameter CNT_POS = CNT_DIV - 1'b1;   //500-1=499 by 500

assign scl = scl_r; //产生iic所需要的时钟

always @ (posedge clk or negedge rst_n)
begin
 if(!rst_n) cnt_delay <= 8'd0;
 else if(cnt_delay == CNT_POS) cnt_delay <= 10'd0; //计数到500为scl的周期,即400KHz
 else cnt_delay <= cnt_delay+1'b1; //时钟计数
end 
 
always @ (posedge clk or negedge rst_n) begin
 if(!rst_n) cnt <= 3'd5;
 else begin
  case (cnt_delay)
   CNT_HIG: cnt <= 3'd1; //cnt=1:scl高电平中间,用于数据采样
   CNT_NEG: cnt <= 3'd2; //cnt=2:scl下降沿
   CNT_LOW: cnt <= 3'd3; //cnt=3:scl低电平中间,用于数据变化
   CNT_POS: cnt <= 3'd0; //cnt=0:scl上升沿
   default: cnt <= 3'd5;
   endcase
  end
end

`define SCL_POS  (cnt==3'd0)  //cnt=0:scl上升沿
`define SCL_HIG  (cnt==3'd1)  //cnt=1:scl高电平中间,用于数据采样
`define SCL_NEG  (cnt==3'd2)  //cnt=2:scl下降沿
`define SCL_LOW  (cnt==3'd3)  //cnt=3:scl低电平中间,用于数据变化
always @ (posedge clk or negedge rst_n)
begin
 if(!rst_n) scl_r <= 1'b0;
 else if(`SCL_POS) scl_r <= 1'b1; //scl信号上升沿
   else if(`SCL_NEG) scl_r <= 1'b0; //scl信号下降沿
end


 2013-03-06   20:33:52

参考资料:PCA9634.pdf文档的数据手册,里面归纳得很好!

Dear All:

针对CMI 4K2K中FPGA部分,我整理如下,部分信息未确定,还需要大家一起讨论,希望大家提出建议,以进一步完善FPGA部分。等通讯方式确定完后,就可以在FPGA上实现I2C中Master和Slave的控制模块。

1、FPGA通过I2C协议与PCA9634器件通讯。其中FPGA作为I2C主器件Master模式,PCA9634作为I2C从器件Slave模式。由于PCA9634的Data Sheet对I2C总线事务有详细的说明,因此FPGA只需按照PCA9634的规格对PCA9634进行控制。初步完成FPGA对PCA9634的简单控制,实现7色灯的循环显示,后续需要结合AmbiGlow算法进行控制。

2、Panasonic sLD3通过I2C协议与FPGA通讯。其中sLD3作为I2C主器件Master模式,FPGA作为I2C从器件Slave模式,双方需要事先协定好相关规格。

功能描述:(1)从器件地址定义:FPGA作为I2C从器件,需要定义从器件地址,方便Master识别。如从器件地址初步定为7’b1000000,需要确认是否与sLD3主板上的其他I2C地址冲突。

A6-A0代表7’b1000000

A6

A5

A4

A3

A2

A1

A0

R/!W

    

(2)控制寄存器的定义:C[1:0],D[5:0]。其中A[1]是功能选择的标志位,A[1]=1’b1表示sLD3开启AmbiSphere/AmbiMusic功能,只是简单地传送12个灯的值。A[1]=1’b0表示sLD3开启AmbiGlow功能,可以传送饱和度、亮度、暖色调、冷色调等参数。(一般用于A[1]为1情况)A[0]是寄存器地址是否自动增加的标志位,A[0]= 1’b1表示亮度寄存器地址从0自动增加到11,12个亮度寄存器地址存储12个灯的值。(一般用于A[1]为0情况)A[0]=1’b0表示只对当前寄存器地址进行读写操作。D[5:0]是寄存器地址,其中6’b000000到6’b001011是亮度寄存器地址,分别存储来自sLD3的12个灯值,其余的寄存器地址可以根据需要进行相应的定义。如可以设置AmibiGlow的相关参数--饱和度、亮度、暖色调、冷色调等。这些参数都需要软件给出。

其中A[1]可以定义也可以通过外部GPIO引脚判断。

C1-C0代表功能选择,D5-D0代表寄存器地址。

C1

C0

D5

D4

D3

D2

D1

D0

FPGA接收到的12个灯的值,需要事先与CMI面板上面的12个灯对应好,只有这样,第1步中FPGA才知道如何发送从sLD3那边得到的12个数据。

3、总线处理

(1)写到一个具体的寄存器:

 

(2)使用自动增加功能实现连续写到寄存器地址从0到11的寄存器:

 

(3)使用自动增加功能读所有寄存器地址的值(假设有17个寄存器,循环读的情况如下所示:)

 


2013-02-27

当器件选择Spartan3A and Spartan 3AN--xc3s400a-5fg320时,采用的编程工具是ISE。如果在布局布线中出错,则可以打开编译产生的文件*.par看看,对检查错误有帮助。   

if((ack_cnt==8'd0)||(ack_cnt==ACK_SIZE-1'b1)) begin

  if(ack) w_state<=Idle;

end

else if(ack) w_state <= Repeat;

以上代码也可以改成如下:

if(ack) begin

  if((ack_cnt==8'd0)||(ack_cnt==ACK_SIZE-1'b1))  w_state<=Idle;

  else w_state <= Repeat;

end


AmbiLight功能:流光溢彩(Ambilight)。自动依视讯内容调整,待机模式下完整操作。色设定:全彩。暗化功能:手动及透过光线感测器。预设模式:2种主动调整预设模式,6种预设模式及使用者预设。全彩环境灯光透过在电视机周围墙壁打上柔和光线,让您拥有能够轻松观赏电视的独特环境。研究显示,在经过调节的环境光线中观看电视,可以让人更为放松。AmbiLight  幻变环回灯光的色彩,可以配合屏幕影像自动进行调整,提供全新的视觉感受。您也可以采用固定的光线颜色或不同的白色阴影。至于在待机模式中,则可以任意控制光线颜色,以产生独特的室内灯光效果。

      I2C_Master和I2C_Slave两种控制方式。对于Slave而言,SCL是输入信号。对于Master而言,SCL是输出信号。都涉及到从器件地址、寄存器地址和数据(双向传输)。本设计中I2C_Master用于控制PCA9634芯片。

      PCA9634是一款通过I2C总线控制的8位LED驱动器,该驱动器特别为红/绿/蓝/琥珀(RGBA)色的混合应用进行了优化。每个LED输出都有自己的8位分辨率(256级)固定频率的独立PWM控制器,该控制器运行在97KHz的频率下,占空比可由0%到99.6%可调,用以将LED设置到一个特定的亮度值。除此之外,该驱动器还有一个8位分辨率(256级)的组PWM控制器,该控制器的工作频率可以为固定的190Hz,也可以在24Hz和每10.73秒一次(约0.093Hz)之间调整,其占空比为0%到99.6%可调,用于使所有LED以同样的值模糊(dim)或者闪烁。

      对于双向数据线,在控制其传输方式时,可以外加一根开关使能信号,例如:

assign SDA = (link_sda) ? sda_out : 1'bz;

assign DATA = (link_read) ? data_from_rm : 8'bzz;

分频时case语句中若用到变量式的参数需要用parameter进行定义。如下所示:

parameter CNT_DIV=8;parameter CNT_HIG=(CNT_DIV<<2)-1'b1;

若程序中反复用到一个判断语句,则可以用`define进行声明代替,简单方便。如下所示:

`define CNT_HIG  (CNT_DIV<<2)-1'b1

`define SCL_HIG  (cnt==3'd1)

原文地址:https://www.cnblogs.com/zlh840/p/2888881.html