本帖最后由 小小小菜 于 2014-3-4 19:45 编辑
对于stm8,用库函数操作,上手容易,但是有好也有坏。这次手头上用到的是8S003这个芯片,如果上库函数,8M的内存很快就会被消耗殆尽,所以只能上寄存器操作,其实自己本人是比较喜欢直接操作寄存器的,对于stm8来说,寄存器也不是特别的多,一个一个来配置也不是特别麻烦,对于底层,也能有一个较好的了解,而除了前边所说的内存优势,执行效率也是有所差别。 stm8的iic,网上可谓是骂声一片啊,哈哈,这次调试之后发现确实是不够优秀,操作繁琐,而最重要的一点便是通讯速度的控制,通过对时钟寄存器的操作,来选择通讯速度,可是却和通过手册公式所计算出来的有很大差别,而最要命的一点是时钟上升沿时间,在寄存器中有一控制上升时间的寄存器,可是实际中通过示波器观察波形发现却是没有多大效果,或者说是没有效果(我的 电路连接是iic引脚挂载一个24C02从设备,上拉电阻4K7)。
实际测试中,上升时间非常慢,对于100K的速度来说,这个上升时间太长了,再加上干扰或其他因素,极有可能大大降低通讯的可靠性。测试了一下,100K的速度,能正常驱动24C02(未长时间大数据量测试),而上400K的速度,通讯失败是常有的事。而手册中却是说着支持100K和400K的速度,且还有寄存器位专门来设置400K速度下的配置,正常来说是应该能上400K的速度才对。不知是否是我理解有误,配置的不好...!
谁弄过这个iic的,交流一下...!
上传我的工程文件,STVD,程序中各种while()的等待均没有设置超时退出。
程序是通过运行后在 仿真窗口中观察变量来确认对24C02的读写。
3
评分
-
查看全部评分
|
|
|
|
STM8驱动IIC的例子挺多的 楼主找一下
STM8硬件IIC:
http://bh7kqk.blog.163.com/blog/static/1274122912010102422751666/
STM8S硬件I2C读写2个24C02
http://www.amobbs.com/archiver/tid-5458920.html
- #include "iostm8s105c4.h"
- #include "2AT2402.h"
- #defineAT2402_10xa0 //第1个AT24C02子地址 A0、A1、A2 ,为 0 0 0
- #defineAT2402_20xae //第2个AT24C02子地址 A0、A1、A2 ,为 1 1 1
- ///////////////////////////////////////////////
- void IIC_Init(void);
- void read(unsigned char g,unsigned char *pBuffer,unsigned char address,unsigned char Number);
- void write(unsigned char g,unsigned char address,unsigned char number,unsigned char *data);
- /////////////////////////////////////////////
- unsigned char temp;
- //硬I2C口要配置成默认的浮动输入
- 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 = 0xfe; //自身地址
- I2C_OARH = 0x40;
- }
- //读写之间插入3.5ms以上的延时,24C02写的时候不能应答。
- //写24c02,参数:地址,长度1-16,数据缓冲
- // Number:写入的字节数
- // address :写入数据对应的地址
- // *data: 要写入的数据到对
- // g : 选取AT24C02
- void write(unsigned char g,unsigned char address,unsigned char number,unsigned char *data)
- {
- unsigned char i;
- I2C_CR2 &=~ 0x04; //不返回应答
- while(I2C_SR3 & 0x02); //等待总线空闲
- I2C_CR2 |= 0x01; //产生起始位
- while(!(I2C_SR1 & 0x01)); //等待START发送完
- //I2C_DR = 0xa0; //发24c02器件地址
- I2C_DR = g; //发24c02器件地址
- while(!(I2C_SR1 & 0x02)); //等特7位器件地址发送完
- temp = I2C_SR1;
- temp = I2C_SR3;
- I2C_DR = address;
- while(!(I2C_SR1 & 0x04));
- for(i=0;i
- {
- I2C_DR = *(data+i);
- while(!(I2C_SR1 & 0x04));
- }
- I2C_CR2 |= 0x02; //产生停止位
- I2C_CR2 |= 0x04; //返回应答
- }
- //读24C02,参数:返回的字节缓冲,开始地址,要读的字节数。
- // Number:读取的字节数
- // address :数据储存的地址
- // pBuffer : 读出的数据
- // g : 选取AT24C02
- void read(unsigned char g,unsigned char *pBuffer,unsigned char address,unsigned char Number)
- {
- while(I2C_SR3 & 0x02); //等待总线空闲
- I2C_CR2 |= 0x01; //产生起始位
- while(!(I2C_SR1 & 0x01)); //等待START发送完
- //I2C_DR = 0xa0; //发24c02器件地址
- I2C_DR = g; //发24c02器件地址
- while(!(I2C_SR1 & 0x02)); //等特7位器件地址发送完
- temp = I2C_SR1;
- temp = I2C_SR3;
- I2C_DR = address;
- while(!(I2C_SR1 & 0x84));
- I2C_CR2 |= 0x01; //产生重复起始位
- while(!(I2C_SR1 & 0x01)); //等待START发送完
- //I2C_DR = 0xa1; //读
- I2C_DR = g+1; //读
- 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能够驱动,只是对于信号上升沿有点异常,上升时间较为缓慢...!
|
|
|
|
|
检查下你的外部硬件,能读到ff至少说明你的标志位全部走了一遍,没被卡死···!
|
|
|
|
|
我用的库函数,倒是没有被卡死,不过读数不正确,有时候能读一部分,有时候就没有?示波器上面显示就是高电平,楼主你觉得这是怎么回事呢?》
|
|
|
|
|
ttttttttttttttttttttttttttt
|
|
|
|
|