两个STM8S103单片机如何用iic总线时序通讯

查看: 306|回复: 0
STM8S003F3关于IIC的STVD例子
& & STM8S003的IIC总是令人头大。现在附上一个STVD的例子。验证可以通过的
对于stm8,用库函数操作,上手容易,但是有好也有坏。这次手头上用到的是8S003这个芯片,如果上库函数,8M的内存很快就会被消耗殆尽,所以只能上寄存器操作,其实自己本人是比较喜欢直接操作寄存器的,对于stm8来说,寄存器也不是特别的多,一个一个来配置也不是特别麻烦,对于底层,也能有一个较好的了解,而除了前边所说的内存优势,执行效率也是有所差别。& & stm8的iic,网上可谓是骂声一片啊,哈哈,这次调试之后发现确实是不够优秀,操作繁琐,而最重要的一点便是通讯速度的控制,通过对时钟寄存器的操作,来选择通讯速度,可是却和通过手册公式所计算出来的有很大差别,而最要命的一点是时钟上升沿时间,在寄存器中有一控制上升时间的寄存器,可是实际中通过示波器观察波形发现却是没有多大效果,或者说是没有效果(我的电路连接是iic引脚挂载一个24C02从设备,上拉电阻4K7)。
&&实际测试中,上升时间非常慢,对于100K的速度来说,这个上升时间太长了,再加上干扰或其他因素,极有可能大大降低通讯的可靠性。测试了一下,100K的速度,能正常驱动24C02(未长时间大数据量测试),而上400K的速度,通讯失败是常有的事。而手册中却是说着支持100K和400K的速度,且还有寄存器位专门来设置400K速度下的配置,正常来说是应该能上400K的速度才对。不知是否是我理解有误,配置的不好...!
& & 谁弄过这个iic的,交流一下...!
& & 上传我的工程文件,STVD,程序中各种while()的等待均没有设置超时退出。
& & 程序是通过运行后在仿真窗口中观察变量来确认对24C02的读写。
单片机源程序如下:
/*
STM8硬件IIC,不用库的例子。&&
有空想试试STM8的硬件IIC读写24C02,结果不像软件模拟那么简单。。
为了一步一步验证读写程序,先用编程器把数据写到EEPROM内。然后就调试读的程序。。。
漫漫长的一天。。。终于成功。
//记得配置选项字。
//SDA,SCL要上拉4.7K-10K的电阻。。
//相应端口要配置成默认的浮动输入。。。一定要。。
void IIC_Init(void)
{
//I2C_FREQR和I2C_CCRL,CCRH ,I2C_TRISER要对应fMASTER频率计算。。但测试的效果来看好像又没什么影响。
I2C_FREQR |= 0x0c; //输入外设时钟频率为11.0592MHz
I2C_CR1& & = 0x00; //禁止I2C外设
I2C_TRISER = 0x0c;
I2C_CCRL& &= 0x37;
I2C_CCRH& &= 0x00;
I2C_CR1& &|= 0x01; //开启I2C外设
I2C_CR2& &|= 0x04; //应答使能
I2C_OARL& &= 0& && && && && && &//自身地址
I2C_OARH& &= 0x40;
}
//读写之间插入3.5ms以上的延时,24C02写的时候不能应答。
//写24c02,参数:地址,长度1-16,数据缓冲
void Write_24c02(unsigned char address,unsigned char number,unsigned char *data)
{
unsigned char temp,i;
I2C_CR2 &=~ 0x04; //不返回应答
while(I2C_SR3 & 0x02); //等待总线空闲
I2C_CR2 |= 0x01; //产生起始位
while(!(I2C_SR1 & 0x01)); //等待START发送完
I2C_DR = 0xa0; //发24c02器件地址
while(!(I2C_SR1 & 0x02)); //等特7位器件地址发送完
temp = I2C_SR1;
temp = I2C_SR3;
while(!(I2C_SR1 & 0x04));
for(i=0;i&i++)
{
&&I2C_DR = *(data+i);
&&while(!(I2C_SR1 & 0x04));
I2C_CR2 |= 0x02; //产生停止位
I2C_CR2 |= 0x04; //返回应答
}
//读24C02,参数:返回的字节缓冲,开始地址,要读的字节数。
void Read_24c02(unsigned char *pBuffer,unsigned char address,unsigned char Number)
{
unsigned char temp,r_
while(I2C_SR3 & 0x02); //等待总线空闲
I2C_CR2 |= 0x01; //产生起始位
while(!(I2C_SR1 & 0x01)); //等待START发送完
I2C_DR = 0xa0; //发24c02器件地址
while(!(I2C_SR1 & 0x02)); //等特7位器件地址发送完
temp = I2C_SR1;
temp = I2C_SR3;
while(!(I2C_SR1 & 0x84));
I2C_CR2 |= 0x01; //产生重复起始位
while(!(I2C_SR1 & 0x01)); //等待START发送完
I2C_DR = 0xa1; //读
while(!(I2C_SR1 & 0x02)); //等特7位器件地址发送完
temp = I2C_SR1;
temp = I2C_SR3;
while(Number) //要读几个字节
{
&&if(Number== 1)
&&{
& &I2C_CR2 &= ~0x04; //不返回应答
& &I2C_CR2 |= 0x02; //产生停止位
&&}
&&if(I2C_SR1 & 0x40)
&&{
& &temp = I2C_SR1;
& &*pBuffer = I2C_DR;
& &pBuffer++;
& &Number--;
&&}
I2C_CR2 |= 0x04;
I2C_CR2 &= ~0x08;
}
IIC_Init();
Read_24c02(buffer,0x0f,5);
for(i=0;i&5;i++)
{
& &while(!(UART2_SR&0x80)); //检测发送寄存器为空
& &UART2_DR = buffer[i];
& &while(!(UART2_SR&0x40)); //发送完成*/
}&&
for(vti=0;vti&5000;vti++); //延时一段时间再读呀。。。注意!!
buffer[0]=0
buffer[1]=0
buffer[2]=0
buffer[3]=0
buffer[4]=0
Write_24c02(0x00,5,buffer);
for(vti=0;vti&5000;vti++); //延时一段时间再读呀。。。注意!!
Read_24c02(buffer,0x00,5);
for(i=0;i&5;i++)
{
& &while(!(UART2_SR&0x80)); //检测发送寄存器为空
& &UART2_DR = buffer[i];
& &while(!(UART2_SR&0x40)); //发送完成*/
}&&
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DE:IAR
MCU:STM8S105C6
外设IC:PLGRF)
下面贡献一下两个关键函数
void Write2Byte(u8 RomAddress,u8 v1,u8 v2)
{
&&SS_ENABLE;
&&I2C_GenerateSTART(ENABLE);
&&while(!I2C_GetFlagStatus(I2C_FLAG_STARTDETECTION));
&&I2C_Send7bitAddress(DeviceAddress, I2C_DIRECTION_TX);
&&while(!I2C_GetFlagStatus(I2C_FLAG_ADDRESSSENTMATCHED));
&&I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);// must add
&&I2C_SendData(RomAddress);
&&while(!I2C_GetFlagStatus(I2C_FLAG_TXEMPTY));
&&I2C_SendData(v1);
&&while(!I2C_GetFlagStatus(I2C_FLAG_TXEMPTY));
&&I2C_SendData(v2);
&&while(!I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED));
&&I2C_GenerateSTOP(ENABLE);
&&SS_DISABLE;
}
u16 PL1167_Read2Byte(u8 RomAddress)
{
&&u8 dat1,dat2;
&&u16
&&dat1=0;
&&dat2=0;
&&dat=0;
&&SS_ENABLE;
&&I2C_GenerateSTART(ENABLE);
&&while(!I2C_GetFlagStatus(I2C_FLAG_STARTDETECTION));
&&I2C_Send7bitAddress(DeviceAddress, I2C_DIRECTION_TX);
&&while(!I2C_GetFlagStatus(I2C_FLAG_ADDRESSSENTMATCHED));
I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);// must add
&&I2C_SendData(RomAddress);
&&while(!I2C_GetFlagStatus(I2C_FLAG_TXEMPTY));
&&I2C_GenerateSTART(ENABLE);
&&while(!I2C_GetFlagStatus(I2C_FLAG_STARTDETECTION));&&
&&I2C_Send7bitAddress(DeviceAddress, I2C_DIRECTION_RX);&&
&&while(!I2C_GetFlagStatus(I2C_FLAG_ADDRESSSENTMATCHED));
&&I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);// must add
&&while(!I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY));
&&I2C_AcknowledgeConfig(I2C_ACK_CURR);
&&dat1=I2C_ReceiveData();& &
&&I2C_AcknowledgeConfig(I2C_ACK_NONE);
&&while(!I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY));
&&dat2=I2C_ReceiveData();
&&I2C_GenerateSTOP(ENABLE);
&&dat|=dat1;
&&dat&&=8;
&&dat|=dat2;
&&SS_DISABLE;& && &&&
&&&&
}
复制代码
所有资料51hei提供下载:
(51.92 KB, 下载次数: 5)
18:35 上传
点击文件名下载附件
IIC例程 STVD
Powered by单片机、电路板
连接器、接插件
其他元器件
用MAX517实现与单片机IIC总线数据的通信
用MAX517实现与单片机IIC总线数据的通信
  IIC总线是PhilipsSEMIconductors在20世纪80年代中期开发的,最初用于音频和视频目的。将IIC扩展为系统管理总线SMBus后可用于电源管理及CPU与其它组件的通信。IIC支持多主控模式,2.1版规定的传输速率在标准模式下为最高1OOkbit/s,快速模式下为400kbit/s,高速模式下为3.4Mbit/s。由于只需要微控制器的两个端口引脚就可以传输
  IIC总线是PhilipsSEMIconductors在20世纪80年代中期开发的,最初用于音频和视频目的。将IIC扩展为系统管理总线SMBus后可用于电源管理及CPU与其它组件的通信。IIC支持多主控模式,2.1版规定的传输速率在标准模式下为最高1OOkbit/s,快速模式下为400kbit/s,高速模式下为3.4Mbit/s。由于只需要微控制器的两个端口引脚就可以传输任意特性的数据,所以IIC总线协议得到了广泛的应用,并促进了大量的IIC外部芯片的开发,下面所用到的MAX517既是其中一种。    由于51系列的单片机没有IIC总线接口,从而限制了具有IIC总线接口的器件在51单片机系统中的使用。通过对IIC总线时序的分析,可以用51单片机的两根I/0线来实现IIC总线的功能。电路原理见下图,PCB图见右图。
  IIC总线是PhilipsSemiconductors在20世纪80年代中期开发的,最初用于音频和视频目的。将IIC扩展为系统管理总线SMBus后可用于电源管理及CPU与其它组件的通信。IIC支持多主控模式,2.1版规定的传输速率在标准模式下为最高1OOkbit/s,快速模式下为400kbit/s,高速模式下为3.4Mbit/s。由于只需要微控制器的两个端口引脚就可以传输任意特性的数据,所以IIC总线协议得到了广泛的应用,并促进了大量的IIC外部芯片的开发,下面所用到的MAX517既是其中一种。    由于51系列的单片机没有IIC总线接口,从而限制了具有IIC总线接口的器件在51单片机系统中的使用。通过对IIC总线时序的分析,可以用51单片机的两根I/0线来实现IIC总线的功能。电路原理见下图,PCB图见右图。
    用AT89C2O5l的p1.0、P1,1两引脚,分别与MAX517的sda、scl两引脚相连接。单片机按照MAX517的工作时序,通过p1.1产生的脉冲,作为MAX517时钟信号,然后从pl,0引脚逐个地输出地址字节、命令字节和数据字节。数据的传送过程必须遵守以下的步骤:    (1)起始条件    传送没有开始的时候,单片机先将P1.1置高,使得MAX517的scl=1;然后控制pl.0由高变低,使得MAX517的sda产生负跳变,传送开始。    (2)中间过程    中间过程需要传送地址字节、命令字节和数据字节。根据MAX517的工作时序,当且仅当scl=0(即pl.0=0)时,sda的高低电平转换才有效;当scl=1时,sda电平状态保持。    (3)终止条件    当传送快结束时,单片机先将p1.1置高,使得sc1=1;然后控制p1.0由低变高,使得sda产生正跳变,标志着传送的结束该设计将89C2O51作为主设备,MAX517作为从设备。首先主设备发送起始命令接着向从设备发送一个地址字节58H,之后从设备则发一个应答信号,主设备接到应答后,再发给从设备一个控制字节OOH,当从设备接到该控制字节后,再发给主设备一个应答。主设备便可发给从设备要转换的8位数据,最后等待完成本次的D/A转换。流程图见下图。
    电路中单片机P1.7脚检测输入脉冲,定时器初始值45536,预留20MS的余量,因为输入脉冲高电平时间为1~2MS,则低电平的时间为18~l9MS。    19MS(64536)-计时值=脉冲高电平时间t(us)。得高电平t时间为Ous~lO00us。T&4&30H,则30H中的数据为OOH~OFAH(0~250)。    D/A转换电压变化范围为:0&(5V&256)-250&(5V&1256)=OV~4.88V    (4)电压转换电路
  此电路完成电压值O~4.88V对应-1OV~+1OV的转换。    第一级为同相比例放大电路,因而
  利用叠加原理,第二级电路的输出为:
  本设计使Rf2=3.1R2=3.1K(其它电阻值也可需满足3.1倍关系),调节R3使U11=2.44V则公式变为Uo2=(1+3.1)(U12-2.44)=4.1(U12-2.44)当Ul2从O~4.88V变化时,对应输出电压Uo2从-1O~+1OV变化。见下图
型号/产品名
深圳市凯锐凌峰科技有限公司
深圳市福田区科鑫电子商行
上海森港电子科技有限公司
深圳东都技术有限公司单片机访问IIC总线技术
> 单片机访问IIC总线技术
单片机访问IIC总线技术
等所有器件数完了它们的低电平周期后,时钟线会被释放为高电平。之后所有器件开始数他们的高电平,最早数完高电平的器件会再次把SCL拉低,因此高电平周期是由高电平周期最短的器件决定的。总线仲裁 同步时钟时序图:仲裁:主机只能在总线空闲的时候启动传输。两个或多个主机可能在起始条件的最小持续时间内产生一个起始条件,结果在总线上产生一个规定的起始条件。当SCL线是高电平时,仲裁在SDA线发生:在其他主机发送低电平时,发送高电平的主机将断开它的数据输出级,因为总线上的电平与它自己的电平不同。仲裁可以持续多位。最开始是比较地址位,如果有相同主机尝试寻址相同的器件,仲裁会继续比较数据位(如果是主机-发送器),或者比较响应位(如果是主机-接收器)。因为IIC总线的地址和数据信息由赢得仲裁的主机决定,在仲裁过程中不会丢失信息。即最后赢得总线的主机是发送或接受的数据是正确的主机。丢失仲裁的主机可以产生时钟脉冲知道丢失仲裁的该字节末尾。由于HS模式的主机有一个唯一的8位主机码,因此一般在第一个字节就可以结束仲裁。如果主机也结合了从机的功能,而且在寻址阶段丢失仲裁,它很可能就是赢得仲裁的主机在寻址的器件。因此丢失仲裁的主机要立即切换到从机模式。两个主机抢总线的时序图:IIC总线的控制只由地址或主机码以及竞争主机发送的数据决定,没有中央主机,总线也没有任何定制的优先权。注意:在串口传输时,当重复起始条件或停止条件发送到IIC总线的时候,仲裁过程仍在进行。下面情况仲裁不发送:1. 重复其实条件和数据位2. 停止条件和数据位3. 重复起始条件和停止条件从机不会介入仲裁过程。用时钟同步机制作为握手在字节级的快速传输中,器件可以快速接受字节,但是需要更多的时间保存接受到的字节或准备另一个要发送的字节。因此,从机可以以一种握手过程在接受和响应一个字节后使SCL线保持低电平,迫使主机进入等待状态,直到从机准备好下一个要传输的字节。时序参考Fig.6。在位传输级可以通过延长每个时钟的低电平周期减慢总线时钟。从而使主机和从机都能适应器件内部的操作速率。HS模式,握手功能只能在字节级使用。数据格式:7位的地址格式:数据的传输如下图格式:在起始条件(S)后,发送了一个从机的地址。地址共7位,紧接着的第8位是数据方向位(R/W)-&0& 表示发送写,&1&表示请求数据读。数据传输一般由主机产生的停止位(P)终止。但是主机还希望在总线上通讯,它可以产生重复起始条件(Sr)和寻址另一个从机,而不是首先产生一个停止条件。在这种传输中,可能有不同的读/写格式组合。如下图:7位寻址:IIC总线的寻址过程是在起始条件后的第一个字节决定了主机选择哪个主机。广播呼叫&地址除外。使用这个地址,理论上所有器件都会发出一个响应。也可以使器件忽略这个地址。广播呼叫地址的第二个字节定义了要采取的行动。当主机在总线上发送了7个地址位之后,系统中的每个器件都在其实条件后讲头7位与自己的地址比较。如果一样,器件会被主机寻址,从机的工作模式有第八位觉得(接受/发送)。从机的地址位是由固定地址部分和可编程地址部分组成。如有4位固定的和3位通过芯片引脚可编程的那么可以挂载8个相同的芯片到IIC总线。IIC地址的分配由IIC总线委员会协调进行。起始位之后的第一个字节的一些特殊地址含义:如下表:
分享给小伙伴们:
我来说两句……
微信公众号二
微信公众号一STM8 I2C从模式 STM8应用笔记
STM8 I2C从模式
以下资料由微雪电子整理并发布,未经许可不得转载,否则追究相应责任!
STM8 I2C从模式
为了产生正确的时序,必须在I2C_FREQR寄存器中设定该模块的输入时钟。输入时钟的频率必须至少是:
标准模式下为:1MHz
快速模式下为:4MHz
一旦检测到起始条件,在SDA线上接收到的地址被送到移位寄存器。然后与STM8芯片自己的地址OARLSB和OAR2或者广播呼叫地址(如果ENGC=1)相比较。
注:在10位地址模式时,比较包括头段序列(11110xx0),其中的xx是地址的两个最高有效位。
头段或地址不匹配:I2C接口将其忽略并等待另一个起始条件。
头段匹配(仅10位模式):如果ACK位被置'1',I2C接口产生一个应答脉冲并等待8位从地址。
地址匹配:I2C接口产生以下时序:
如果ACK被置'1',则产生一个应答脉冲
硬件将ADDR位置为1;如果设置了ITEVFEN位,则产生一个中断
在10位模式,接收到地址序列后,从设备总是处于接收模式。当接收到重复的起始条件,接着后面跟随与地址匹配的头序列并且最低位为'1'(即11110xx1)后,设备进入发送模式。
在从模式下TRA位指示当前是处于接收模式还是发送模式。
从发送模式
在接收到地址和清除ADDR位后,从设备将字节从DR寄存器经由内部移位寄存器发送到SDA线上。
从设备保持SCL为低电平,直到ADDR位被清除并且待发送数据已写入DR寄存器。当收到应答脉冲时:
TxE位被硬件置为1,如果设置了ITEVFEN和ITBUFEN位,则产生一个中断。
如果写入到DR寄存器,TxE位为1,但在上一次数据发送结束之前没有新数据写入到DR寄存器,则BTF位被置为1,I2C接口将保持SCL为低电平,以等待DR寄存器写操作。
(图94:STM8从发送器的传送序列图)
从设备接收模式
在接收到地址并清除ADDR后,从接收器将通过内部移位寄存器从SDA线接收到的字节存进DR寄存器。I2C接口在接收到每个字节后都执行下列操作:
如果设置了ACK位,则产生一个应答脉冲
硬件设置RxNE=1。如果设置了ITEVFEN和ITBUFEN位,则产生一个中断。
如果RxNE为1,并且在接收新的数据结束之前DR寄存器未被读出,BTF位被置位,I2C接口保持SCL为低电平,等待DR寄存器读操作(见下图)。
(图95:STM8从接收器的传送序列图)
关闭从模式通信
在传输完最后一个数据字节后,主设备产生一个停止条件,I2C接口检测到这一条件时:
设置STOPF=1,如果设置了ITEVFEN位,则产生一个中断。
然后I2C接口等待读SR1寄存器,再写CR1寄存器。(见图95的EV4)。
STM8 I2C从模式51单片机IIC总线程序_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
51单片机IIC总线程序
&&IIC总线程序
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩1页未读,
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 iic总线时序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信