应用McBSP实现I2C总线控制器
发布时间:2008/6/3 0:00:00 访问次数:431
作者email: dick_ligg@sohu.com
摘 要:提出了在tms320c6000系列dsp上应用mcbsp实现i2c总线接口协议的方法,使dsp可以接入其他需要i2c总线配置的智能器件,系统结构简单,硬件设计容易,资源消耗小。
关键字:i2c总线 gpio mcbsp dsp
1 引 言
ti公司的tms320c6000[1,2]系列是高性能的dsp,可广泛的用于xdsl、无线基站、数字图像处理等方面。在进行数字图像处理时,通常需要视频解码器诸如saa7111a之类的模拟视频前端,而大多数的视频解码器进行初始化通常是通过两线的i2c总线接口,但是现在的dsp和mcu大部分都没有i2c总线接口,在这种情况下我们可以应用两个通用的io线,通过软件的方法来模拟i2c总线的协议,继而完成i2c总线的接口。在tms320c6000中通常都有两个或两个以上的多通道缓冲串行接口mcbsp,mcbsp不仅可以配制成串行接口还可以独立的配制成通用的输入(gpi)、输出(gpo)和输入输出端口(gpio)。
i2c[3]串行总线是用双向数据线(sda)和串行时钟线(scl)两根信号线,在连接到该总线的器件之间传送信息。总线上的每个器件均可设置一个唯一地址,然后根据所设的功能进行信息的发送或接收。除了作为发送器和接收器以外,在执行数据传输时,总线的器件还可以设定为主控器和受控器。通常由主控器启动总线上的数据传输,并产生数据传输所需的时钟信号。而被其寻址的其它器件均为受控器,这意味着总线上可连接多个有控制总线的器件。
i2c总线上的数据传输率为100kbit/s,快速方式下可达400kbit/s。连接到总线上的器件数仅受400pf的总线电容的限制。同时,为了避免总线信号的混乱,要求连接到总线上的各器件输出端必须是集电极开路或漏极开路,以便产生“线与”功能。i2c总线上的sda和scl线都是双向传输线,它们可通过一个电阻连接到正电源端,当总线处于空闲状态时,两条线均为高电平。
2 硬件设计
i2c总线的硬件设计非常方便,只需要将sda 和scl连接即可,在i2c总线上只允许有一个主控器,其余的都是受控器。当节点的个数大于了400pf的限制时,可以通过总线驱动器如82b715来进行总线扩展。连接见图1
3 软件设计
3.1 mcbsp的配置
i2c总线应用mcbsp的两个管脚,首先禁用mcbsp功能以便将mcbsp的管脚配制成gpi、gpo、gpio。本文应用mcbsp0的clkx0作为i2c总线的scl,fsx0作为i2c总线的sda,mcbsp的dx,dr,通常不能配置成i2c的sda,因为sda是双向的,而dx,dr只能配制成单一的输入或输出。
配置代码如下:
mcbsp0_spcr=0x00000000;//mcbsp0 发送和接收复位
mcbsp0_pcr=0x00003f00;// mcbsp0的所有的管脚都配置为gpio,clkx0和fsx0为输出
对于主机来说scl总是输出,所以它的方向是保持不变的,scl应该输出0,1作为接口的时钟,为了实现此功能我们定义一个宏(macros):set_sclhi( ) set_scllo( )
#define set_sclhi( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000002
#define set_scllo( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffffffd
i2c总线的数据线sda当写的时候是输入,读的时候是输出。为了改变sda的方向可以定义set_sdadirout( ) set_sdadirin( )
#define set_sdadirout( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000800
#define set_sdadirin( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffff7ff
sda应该依照数据位的0,1来变化,为了输出1,0定义set_sdahi( ) set_sdalo( )
#define set_sdahi( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000008
#define set_sdalo( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffffff7
定义好之后可以模拟i2c总线的协议进行传送,例如在saa7111a上的i2c总线接口是用来对saa7111a进行初始化用的,scl的频率可以从0到400khz,为了控制scl的频率可以应用dsp的timer0来控制。
当cpu为100mhz时:
tcr = 0x00000010; // 停止 timer0 and tddr=0
prd = 6249; // timer0 rate = cpu-frequency/(pdr+1) = 100mhz/6250 = 16khz
...
tcr &= 0xffffffef; // 开始 timer0
3.2 i2c总线协议编程
3.2.1 i2c总线协议读写数据流的编程
为了进行i2c总线的通讯,我们选用每位数据流4帧(frames),以便延迟和噪声干扰最小,4帧每位的数据流保证了sda不会变化在scl的边沿处,仅仅允许数据变化在frame0,读仅在frame2。如图2所示
i2c总线的写程序如下
void i2cwrite(unsigned int writebit)
{set_sdadirout( ); // 设置sda为输出
switch(framecount)
{
case(0): // 起始帧
set_scllo( ); // scl 为 0
if (writebit == 0) //
作者email: dick_ligg@sohu.com
摘 要:提出了在tms320c6000系列dsp上应用mcbsp实现i2c总线接口协议的方法,使dsp可以接入其他需要i2c总线配置的智能器件,系统结构简单,硬件设计容易,资源消耗小。
关键字:i2c总线 gpio mcbsp dsp
1 引 言
ti公司的tms320c6000[1,2]系列是高性能的dsp,可广泛的用于xdsl、无线基站、数字图像处理等方面。在进行数字图像处理时,通常需要视频解码器诸如saa7111a之类的模拟视频前端,而大多数的视频解码器进行初始化通常是通过两线的i2c总线接口,但是现在的dsp和mcu大部分都没有i2c总线接口,在这种情况下我们可以应用两个通用的io线,通过软件的方法来模拟i2c总线的协议,继而完成i2c总线的接口。在tms320c6000中通常都有两个或两个以上的多通道缓冲串行接口mcbsp,mcbsp不仅可以配制成串行接口还可以独立的配制成通用的输入(gpi)、输出(gpo)和输入输出端口(gpio)。
i2c[3]串行总线是用双向数据线(sda)和串行时钟线(scl)两根信号线,在连接到该总线的器件之间传送信息。总线上的每个器件均可设置一个唯一地址,然后根据所设的功能进行信息的发送或接收。除了作为发送器和接收器以外,在执行数据传输时,总线的器件还可以设定为主控器和受控器。通常由主控器启动总线上的数据传输,并产生数据传输所需的时钟信号。而被其寻址的其它器件均为受控器,这意味着总线上可连接多个有控制总线的器件。
i2c总线上的数据传输率为100kbit/s,快速方式下可达400kbit/s。连接到总线上的器件数仅受400pf的总线电容的限制。同时,为了避免总线信号的混乱,要求连接到总线上的各器件输出端必须是集电极开路或漏极开路,以便产生“线与”功能。i2c总线上的sda和scl线都是双向传输线,它们可通过一个电阻连接到正电源端,当总线处于空闲状态时,两条线均为高电平。
2 硬件设计
i2c总线的硬件设计非常方便,只需要将sda 和scl连接即可,在i2c总线上只允许有一个主控器,其余的都是受控器。当节点的个数大于了400pf的限制时,可以通过总线驱动器如82b715来进行总线扩展。连接见图1
3 软件设计
3.1 mcbsp的配置
i2c总线应用mcbsp的两个管脚,首先禁用mcbsp功能以便将mcbsp的管脚配制成gpi、gpo、gpio。本文应用mcbsp0的clkx0作为i2c总线的scl,fsx0作为i2c总线的sda,mcbsp的dx,dr,通常不能配置成i2c的sda,因为sda是双向的,而dx,dr只能配制成单一的输入或输出。
配置代码如下:
mcbsp0_spcr=0x00000000;//mcbsp0 发送和接收复位
mcbsp0_pcr=0x00003f00;// mcbsp0的所有的管脚都配置为gpio,clkx0和fsx0为输出
对于主机来说scl总是输出,所以它的方向是保持不变的,scl应该输出0,1作为接口的时钟,为了实现此功能我们定义一个宏(macros):set_sclhi( ) set_scllo( )
#define set_sclhi( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000002
#define set_scllo( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffffffd
i2c总线的数据线sda当写的时候是输入,读的时候是输出。为了改变sda的方向可以定义set_sdadirout( ) set_sdadirin( )
#define set_sdadirout( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000800
#define set_sdadirin( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffff7ff
sda应该依照数据位的0,1来变化,为了输出1,0定义set_sdahi( ) set_sdalo( )
#define set_sdahi( ) mcbsp0_spsa = pcr; mcbsp0_spsa = 0x00000008
#define set_sdalo( ) mcbsp0_spsa = pcr; mcbsp0_spsa &= 0xfffffff7
定义好之后可以模拟i2c总线的协议进行传送,例如在saa7111a上的i2c总线接口是用来对saa7111a进行初始化用的,scl的频率可以从0到400khz,为了控制scl的频率可以应用dsp的timer0来控制。
当cpu为100mhz时:
tcr = 0x00000010; // 停止 timer0 and tddr=0
prd = 6249; // timer0 rate = cpu-frequency/(pdr+1) = 100mhz/6250 = 16khz
...
tcr &= 0xffffffef; // 开始 timer0
3.2 i2c总线协议编程
3.2.1 i2c总线协议读写数据流的编程
为了进行i2c总线的通讯,我们选用每位数据流4帧(frames),以便延迟和噪声干扰最小,4帧每位的数据流保证了sda不会变化在scl的边沿处,仅仅允许数据变化在frame0,读仅在frame2。如图2所示
i2c总线的写程序如下
void i2cwrite(unsigned int writebit)
{set_sdadirout( ); // 设置sda为输出
switch(framecount)
{
case(0): // 起始帧
set_scllo( ); // scl 为 0
if (writebit == 0) //