本帖最后由 小小小菜 于 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
评分
-
查看全部评分
|
|
|
|
//24C02忙返回1,空闲返回0
u8 Check_24C02_Busy(void)
{
u8 temp = 0;
u16 cnt_temp = 0;
while((I2C_SR3 & 0x02) != 0); //等待IIC总线空闲
I2C_Start();
while((I2C_SR1 & 0x01) == 0); //EV5,起始信号已经发送
I2C_DR = (0XA0 & 0xfe); // 发送iic从器件物理地址,最低位0,写操作
cnt_temp = 500;
while((I2C_SR1 & 0x02) == 0) //地址已经被发送
{
cnt_temp --;
if(cnt_temp == 0)
{
temp = I2C_SR1; //清除ADDR标志位
temp = I2C_SR3;
I2C_CR2 &= 0xfb;//读取数据下,发送stop必须禁止ack,才能释放从机
temp = I2C_SR1; //清零BTF标志位
temp = I2C_DR;
I2C_stop();
return 1;
}
}
temp = I2C_SR1; //清除ADDR标志位
temp = I2C_SR3;
I2C_CR2 &= 0xfb; //读取数据下,发送stop必须禁止ack,才能释放从机
temp = I2C_SR1; //清零BTF标志位
temp = I2C_DR;
I2C_stop();
return 0;
}
楼主的程序确实可用,问下楼主这段程序的作用是什么,不加上这一段就不行了
|
|
|
|
|
为什么我的iic发送器件地址后收不到应答信号就一直卡住了?
|
|
|
|
|
谢谢分享
|
|
|
|
|
粗略看了一下,过程确实还算是比较简单的,一般写的时候主要是寄存器引发的问题可能会多一些。值得参考。
|
|
|
|
|
程序查询了SB位,ADDR位及BTF位,清0前都要插入5个NOP,规格书上不是写了吗?而且你这程序容易死机吧
|
|
|
|
|