历史上的今天
返回首页

历史上的今天

今天是:2024年09月11日(星期三)

正在发生

2020年09月11日 | 基于MSP430F5系列的硬件I2C的使用分享

2020-09-11 来源:elecfans

0.前言

对于大多数单片机来说,I2C成了一个老大难问题。从51时代开始,软件模拟I2C成了主流,甚至到ARMCortex M3大行其道的今天,软件模拟I2C依然是使用最广的方法。虽然软件模拟可以解决所有的问题,但是总感觉没有充分发挥MCU内部的硬件资源。查阅了所有关于MSP430F5系列的图书,没有关于硬件I2C的应用代码,自己通过调试摸索,把经验总结之后和大家分享,希望大家喜欢。同时,I2C的使用可以分为等待法和中断法,从理解的角度来说等待法思路清晰易于上手,从功耗的角度出发,中断法可以灵活的进入低功耗模式,但是不易理解。本文先从等待法入手。


MSP430F5系列的硬件I2C使用大致会有以下问题:

【I2C地址设定】一般情况下I2C的7位地址被写成了8位长度,最低位无效。例如AT24C02的I2C地址为0xA0,其实真正的7位地址为0x50。而MSP430正是需要填入这7位地址0x50。


【I2C停止位发送】在I2C读操作过程中,读取最后一个字节之后MCU应向从机发送无应答,MSP430F5系列的MCU发送无应答的操作将自动完成,这就以为在读取最后一个字节内容时,应先操作停止位相关寄存器。


【I2C起始位发送】如果仔细分析MSP430F5参考手册,将会发现读操作和写操作发送I2C起始位时略有不同。写操作时需要先向TXBUF中写入数据,之后才可以等待TXSTT标志位变为0,而读操作和写操作稍有不同。


【AT24C02操作时序图】

基于MSP430F5系列的硬件I2C的使用分享

1.初始化设置1.1代码实现

voiducb0_config(void)

{

P3SEL&=~BIT2;//P3.2@UCB0SCL

P3DIR|=BIT2;

P3OUT|=BIT2;

//输出9个时钟以恢复I2C总线状态

for(uint8_ti=0;i《9;i++)

{

P3OUT|=BIT2;

__delay_cycles(8000);

P3OUT&=~BIT2;

__delay_cycles(8000);

}

P3SEL|=(BIT1+BIT2);//P3.1@UCB0SDAP3.2@UCB0SCL

//P3.1@ISP.1P3.2@ISP.5

UCB0CTL1|=UCSWRST;

UCB0CTL0=UCMST+UCMODE_3+UCSYNC;//I2C主机模式

UCB0CTL1|=UCSSEL_2;//选择SMCLK

UCB0BR0=40;

UCB0BR1=0;

UCB0CTL0&=~UCSLA10;//7位地址模式

UCB0I2CSA=EEPROM_ADDRESS;//EEPROM地址

UCB0CTL1&=~UCSWRST;

}


1.2代码分析

I2C从设备的地址一般有以下通俗说法——7位地址,写地址(写控制字)和读地址(读控制字)。1个I2C通信的控制字节(I2C启动之后传送的第一个字节)由7位I2C地址和1位读写标志位组成,7位I2C地址即7位地址,若读写标志位为读标志(读写标志位置位)加上7位I2C地址便组成了读地址(读控制字),若读写标志位为写标志(读写标志位清零)加上7位地址便组成了写地址(写控制字)。例如AT24C02的I2C7位地址为0x50,读地址(读控制字)为0xA1,写地址(写控制字)为0xA1。


在MSP430F5系列中,I2CSA地址寄存器应写入7位地址,参照上面的例子应写入0X50。至于I2C读写位的控制由CTL1寄存器完成,用户无需干预。


在I2C设置开始之前,可以先通过SCL端口发送9个时钟信号,该时钟信号可以是I2C从机芯片从一种错误的通信状态恢复,虽然这9个时钟信号不起眼但是对于调试过程来说非常有用。例如在调试过程中,错误的发送了停止位,若再次启动调试则I2C从设备仍处于一种错误的状态,这9个时钟信号可以把I2C从设备从错误的状态“拉”回来。


2.写单个字节

向I2C从设备写入单个字节应该是最为简单的一个操作,因为所有的控制权都在主机手中。写单个字节实际包括了2个重要部分,一个便是写寄存器地址,另一个便是写寄存器内容。对于AT24C02而言,存储内容的字节长度为一个字节,而对于容量更大的EEPROM而言,存储地址可为两个字节。


2.1 代码实现

uint8_teeprom_writebyte(uint8_tword_addr,uint8_tword_value)

{

while(UCB0CTL1&UCTXSTP);

UCB0CTL1|=UCTR;//写模式

UCB0CTL1|=UCTXSTT;//发送启动位

UCB0TXBUF=word_addr;//发送字节地址

//等待UCTXIFG=1与UCTXSTT=0同时变化等待一个标志位即可

while(!(UCB0IFG&UCTXIFG))

{

if(UCB0IFG&UCNACKIFG)//若无应答UCNACKIFG=1

{

return1;

}

}

UCB0TXBUF=word_value;//发送字节内容

while(!(UCB0IFG&UCTXIFG));//等待UCTXIFG=1

UCB0CTL1|=UCTXSTP;

while(UCB0CTL1&UCTXSTP);//等待发送完成

return0;

}


2.2 代码分析

关于代码出口的说明,关于I2C的读写函数,若返回值为0说明所有的操作正常,若返回值为非0说明操作有误,例如1代表从机无应答。这种组合方式可能与各位的编程习惯有出入,一般认为返回1表示操作成功,而返回0表示操作失败。这种方式的问题便是无法有效的表达错误原因,因为“0”只有一个,而非“0”却有很多。


写单个字节可以划分为——从机写地址发送、寄存器地址发送、寄存器内容发送。寄存器地址的发送由MSP430自动完成,这和软件模拟的操作有所区别。请勿发送I2C从机地址,若操作AT24C02发送需要写入的存储字节的首地址即可。


在单字节和多字节写操作过程中,尤其要注意UCTXSTT标志位的变化位置。UCTXSTT标志位会在从机接收完写控制字节或读控制字节之后变化,但是在写控制字节发送之后,必须先填充TXBUF,再尝试等待STT标志位复位,此时STT标志位和TXIFG标志位会同时变化。若从机没有应答,那么NACK标志位也会发生变化。再次强调需要先填充TXBUF,在等待STT标志位复位。以下代码将导致程序一直停留在while(UCB0IFG & UCTXSTT)处,具体的原因可查看MSP430参考手册。


while(UCB0CTL1&UCTXSTP);

UCB0CTL1|=UCTR;//写模式

UCB0CTL1|=UCTXSTT;//发送启动位

//等待UCTXSTT=0同时变化,但是很遗憾该变化不会发送

while(UCB0IFG&UCTXSTT);

UCB0TXBUF=word_addr;//发送字节地址


3.写多个字节3.1代码实现

uint8_teeprom_writepage(uint8_tword_addr,uint8_t*pword_buf,uint8_tlen)

{

while(UCB0CTL1&UCTXSTP);

UCB0CTL1|=UCTR;//写模式

UCB0CTL1|=UCTXSTT;//发送启动位

UCB0TXBUF=word_addr;//发送字节地址

//等待UCTXIFG=1与UCTXSTT=0同时变化等待一个标志位即可

while(!(UCB0IFG&UCTXIFG))

{

if(UCB0IFG&UCNACKIFG)//若无应答UCNACKIFG=1

推荐阅读

史海拾趣

鑫雁公司的发展小趣事

聚洵半导体始终坚持以市场为导向、以创新为驱动的发展理念。公司不断加大新产品研发投入,致力于在低功耗运放、高速运放、仪表放大器等领域取得更多技术突破。同时,聚洵还积极关注行业动态和市场趋势,针对医疗电子、工业控制、汽车电子等新兴领域推出了一系列创新产品。展望未来,聚洵将继续保持专注和创新精神,致力于成为国内领先的信号链模拟芯片设计公司之一,为电子行业的发展贡献更多力量。

Dielectric Laboratories公司的发展小趣事

1955年,一家名为Dielectric Laboratories(DLI)的公司正式成立,它以其独特的电子元件研发能力在电子行业中崭露头角。起初,DLI专注于电容器的研发和生产,以其高品质和稳定性赢得了市场的认可。随着业务的逐步扩大,DLI不断投入研发资金,探索新的技术领域,为公司的长远发展奠定了坚实的基础。

FEI Microwave Inc公司的发展小趣事

FEI Microwave Inc公司自成立以来,始终致力于微波技术的创新与发展。在早期,公司研发团队成功研发出了一款具有突破性的微波收发模块,该模块以其高频率、低噪声和出色的稳定性迅速在市场上崭露头角。随着技术的不断完善,FEI Microwave Inc公司逐渐在微波通信领域建立了自己的技术壁垒,成为业界的佼佼者。

Gennum ( Semtech )公司的发展小趣事
如果电路不工作,可以逐步断开或替换部分元件,以确定问题所在。
EMMICRO公司的发展小趣事

面对竞争激烈的电子市场,EMMICRO公司制定了精准的市场拓展策略。公司根据市场需求和客户需求,不断调整产品结构和市场定位,积极开拓新的销售渠道和合作伙伴。同时,公司还加大了对新兴市场的投入和布局,通过差异化竞争策略,成功打开了多个新的市场领域。

Deutron Electronics Corp公司的发展小趣事

随着环保意识的日益提高,Deutron Electronics Corp也积极响应环保号召,致力于实现绿色生产和可持续发展。公司采用环保材料和生产工艺,减少了对环境的污染。同时,公司还加大了对节能减排的投入,提高了资源利用效率。这些努力使得Deutron Electronics Corp在行业内树立了良好的环保形象,也为公司的长期发展奠定了坚实基础。

问答坊 | AI 解惑

汽车导航系统电源设计

现代汽车不断增加越来越复杂的电子系统。市场调研公司 Allied Business Intelligence 预测,到 2007 年,汽车半导体市场将增长到一年超过 170 亿美元,而去年这一市场为 123 亿美元。另一家市场调研公司 Strategy Analytics 也持有同样乐观的看法: ...…

查看全部问答>

有谁用过用单片机控制SHT15温湿度传感器啊?

有谁用过用单片机控制SHT15温湿度传感器啊? 求助通信时序问题?…

查看全部问答>

菜鸟请教D12驱动应用程序问题

菜鸟请教D12驱动应用程序问题 小弟使用D12和51做一个大量数据传输的东西。 固件使用ZLG的,驱动是用DriverStudio3.1直接生成的。 使用DS里面的函数OpenByInterf()打开USB设备,用ReadFile()阻塞模式来读取USB数据 因为在51那里是连续发的,所 ...…

查看全部问答>

有需要IC芯片的可以找我啊,呵呵

各位朋友好,本人现在在北京一家公司做IC销售,我们家一般都是从国外订货,质量有保证,如果没有库存,订货一般7-10天,我们家常做的厂家有altera, intel,on,maxim,atmel,st,ad,ti等等的。欢迎各位朋友给小女子我捧场啊,在这里我先谢谢各位朋友啦 ...…

查看全部问答>

THS3201放大后整体偏置呢?

本帖最后由 dontium 于 2015-1-23 13:23 编辑 我做了关于THS3201的放大电路,反向放大时整体偏置,同相放大时会自激振荡也会整体偏置。请问有人使用过吗?有高见么? …

查看全部问答>

LM3S2B93的内部LDO问题

做了两块LM3S2B93的板子,结果全部因为2B93的内部LDO问题失效,第一块板运行成功一段时间后,突然失效,最后检测结果2B93中LDO短路,第二块板运行成功一段时间后,同样失效,检测2B93中LDO电压降为0.8V,3.3V电路正常。 1.2V电路仅接了去耦电容X5R ...…

查看全部问答>

求科普

有一段用keil运行的代码怎么移植到cc2530上?…

查看全部问答>

正反随便插!USB 3.1接口长这样

本帖最后由 jameswangsynnex 于 2015-3-3 19:50 编辑 USB3.1采用全新的接口设计,传输带宽从USB 3.0 5Gbps翻番到了10Gbps,供电电流从1.5A大幅增加到了3-5A。其中USB 3.1 Type-C是全新设计的接口样式,上下两端是完全一样的,类似苹果的Lightning ...…

查看全部问答>

ADXL345快速指南数据是否有误?

ADXL345快速指南第四页表2,为什么输出0FFF时加速度值是1599,而不是4095*3.9=15970?是我理解错还是指南有问题? 我认为设置在16G模式下,应该是15970mg,15970mg/1000≈16G。不知这样理解有误?如果真是1599,那么ADXL345输出不是线性的,应如何 ...…

查看全部问答>