打印
[应用相关]

用了lut1lut的I2C函数,终于搞定,谢谢各位...

[复制链接]
2216|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LPcfANS|  楼主 | 2009-1-13 11:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
LPcfANS|  楼主 | 2009-1-13 11:54 | 只看该作者

情况如下:

如果设置SysTick_CounterCmd(SysTick_Counter_Clear);后运行不下去.但设置成SysTick_CounterCmd(SysTick_Counter_Enable);可以运行,但读出来的

re1=2
re2=3,
re3=3,
re4=3; 

使用特权

评论回复
板凳
lut1lut| | 2009-1-13 14:00 | 只看该作者

什么叫作“停在I2C_Comm_Init”

在I2C_Comm_Init()中执行了SysTick_CounterCmd(SysTick_Counter_Clear);运行不下去,是什么意思,函数不返回么?

使用特权

评论回复
地板
LPcfANS|  楼主 | 2009-1-13 14:08 | 只看该作者

现在情况如下:

1,因为我的 程序中有ADC,TIM,SYSTICK,所以在执行I2C_Comm_Init时就死了.
 后来把其他都删掉,就可以了,可能是和我开始的systick设置冲突了.
2,现在可以运行,但读出来的都是3(SEND_START_ERR = 3)

使用特权

评论回复
5
LPcfANS|  楼主 | 2009-1-13 14:11 | 只看该作者

图....STM32F103ZET6 ,PB6,PB7...

https://bbs.21ic.com/upfiles/img/20091/200911314737101.gif

使用特权

评论回复
6
lut1lut| | 2009-1-13 15:08 | 只看该作者

从返回参数来看

re1=2  --〉bus busy
re2=3, --> start send err
re3=3, --> start send err
re4=3; --> start send err

第一次通信时,I2C总线应该不是都为高电平的idle状态,所以Busy位一直被置位,函数返回re1=2 (bus busy)

余下的三次通信,按理如果总线不变的话,应该还是返回bus busy啊,但是实际是start send err。即MSL/SB/BUSY没有都被置位。看看此时寄存器的值,并且看看start condition的波形到底出来没有。

一般来说,如果start condtion发不出去的话,都是因为总线还是busy状态,但是你说没有返回bus busy,倒是有些奇怪。

使用特权

评论回复
7
LPcfANS|  楼主 | 2009-1-13 16:40 | 只看该作者

首先先谢谢您啊.我再试试.用了很多I2C的程序,都不能读写.

芯片是AT24C02....

使用特权

评论回复
8
lut1lut| | 2009-1-13 16:46 | 只看该作者

建议您看着波形来调试

使用特权

评论回复
9
LPcfANS|  楼主 | 2009-1-13 16:53 | 只看该作者

好的....谢谢...

上示波器了。..

使用特权

评论回复
10
LPcfANS|  楼主 | 2009-1-14 09:28 | 只看该作者

用万利199板子,返回的都是2..BUS BUSY..

用万利199板子,返回的都是2..BUS BUSY..

使用特权

评论回复
11
LPcfANS|  楼主 | 2009-1-14 11:12 | 只看该作者

把这个加进去,就可以了。谢谢各位了...

 chinabig 发表于 2008-12-23 17:50 ST MCU ←返回版面    

6楼: 基本搞定了 

这种"异常复位"确实会造成I2C死锁.是硬件I2C无法避免的.一旦发生,应先转到IO口方式,用IO口方式发出SCK脉冲.每发一次,检测SDA是否变高.高了就说明解锁了.退出,再转回硬件I2C方式.
简单的代码如下:
void CheckDeadLock(void)
{
    DWORD tem=     GPIOB->CRL;
    int i =0;
    I2C_Cmd(I2C1, DISABLE);
    RCC->APB1ENR &= ~RCC_APB1Periph_I2C1;
    tem = (tem&(~(0x0f<<24)))|(3<<24); // SCK ==> output
    tem = (tem&(~(0x0f<<28)))|(4<<28); // SDA ==> input
    GPIOB->CRL = tem;
    while(1){
        GPIOB->BSRR =  (0x1UL<<(6+16));
        Delay(0x2000);
        GPIOB->BSRR =  (0x1UL<<6);
        Delay(0x2000);
        i++;
        if(GPIOB->IDR& (0x1UL<<7))
        {
            printf("释放了%d ", i);
            break;
        }    
                else if(i>=9){ // 这里或许应该是8,待研究
                }
    }
}    
我编写的一个程序,不停地读EEPROM,之前一旦复位,基本就死了.现在多次测试,基本OK.之所以说基本,因为几十次还是有一两次,解锁后还是无法跑下去.在这里感谢香版 netjob lut1lut. 以及几位提供了自己代码的网友

如果哪位同学觉得有所帮助,请一起和我奚落一下ST公司的驱动开发能力. :) 初接触STM32,为它划时代的能力而震撼,深深感觉到这才是21世纪的单片机.再深入,在它提供的驱动包上开始栽跟斗.首先是不同版本的驱动包,同一个结构体,里面的成员变量居然是不同的(名字不同).再后来,发觉很多地方都充满了while(1)这种类型的死循环,一旦硬件出错,软件就死掉了.没有考虑错误的情况.退一步说,即使难以完美处理各种错误,起码也应该在旁边加相应的注释,例如来个fixme提示.让后来者少走弯路.
两个字评论: 业余 三个字:不专业  四个字:有待改进   五个字:望做得更好 
 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

1614

帖子

1

粉丝