第1次看见所长给农校学生耐心"讲习"~~~实际我也遇到此事 hotpower 发表于 2006-12-27 21:04 侃单片机 ←返回版面 举报该贴 哈哈,最近一直在论战什么"狗论",故一直没空关心此帖~~~ 这个问题我实际遇到过,当时也很郁闷,发现主机时常被从机叼死... 后来编写了从机I2C程序后才明白了不少~~~(这对搞清I2C器件的内部状况很有帮助) 菜农I2C从机锁死的处理方法: 从机方USI实现的TWI即I2C) while (tmp = (PINB & (1 << SCL)));//等待SCL=0主机处理结束 PORTB &= ~(1 << SCL);//保持低电平 DDRB |= (1 << SCL);//占用SCL总线,以便长期处理 switch(Status) { ....... } DDRB &= ~(1 << SCL);//释放SCL总线 USISR |= (1 << USIOIF);//清除计数器溢出中断标志 这是因为从机要等待主机释放SCL为高电平后,再反向拉低SCL电平 以适应于不同的通讯速率,这不像异步通讯协议需要约定相同的通讯速率. 在从机处理完后,再释放SCL信号. 当然此时从机处理过程肯定要操作SDA总线的. 如果主机在这时读从机肯定会失败!!! 主机方硬件I2C,本例用的是AVR,也用ARM测试过) //不过三七二十一,主机在每次发送时都先放弃I2C功能,再在启动时开启I2C功能 DDRC &= ~((1 << SCL) | (1 << SDA));//SCL、SDA设置为输入方式 TWCR &= ~(1 << TWEN);//放弃I2C功能!!! PORTC |= (1 << SCL) | (1 << SDA);//SCL、SDA 引脚内部上拉电阻 if (Twi.Busy) {//I2C忙(因为用的是收发中断,有类FIFO) Twi.TWStop();//强行停止操作,本次操作失败,下次再运行 } else { ....................... Twi.TWStart();//注意里面的TWCR = ...(1 << TWEN);//选择I2C功能 } .............. inline void TwiObj::TWStart(void) { Busy = true; Status = 0;//主机准备发送启始位 Count = 0;//发送数据个数 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE); } 通过实战片段可以看出: 主机要模拟I2C时,要多考虑从机的接续机制,在主机发送时钟信号后, 即SCL的上跳沿时,从机肯定要拉低SCL以匹配速率. 主机要再次主机发送时钟信号前, 即SCL的下跳沿前,一定要等到SCL总线为高电平时才能发送低电平信号!!! 特别注意从机程序的: while (tmp = (PINB & (1 << SCL)));//等待SCL=0主机处理结束 PORTB &= ~(1 << SCL);//保持低电平 DDRB |= (1 << SCL);//占用SCL总线,以便长期处理 总而结之,拿我们村里的一句粗话:"没病不死人". 可能话不好听,但确实是句大实话~~~ 今天就忽悠到这里吧~~~ 我最近还要将"狗论"进行到底呢~~~也欢迎所长多拍砖~~~ |
__________________________ ●█〓██▄▄▄▄▄▄ ●●●●●●→ '''',,;; ▄▅██████▅▄▃▂ 灌水入坛,传播非典!; ██████████████ '''',,,;,.,,,;,;; ◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤ '''',,,;,.,,,;,;; ','''',''',,,;,.',''',,',,,'.╭⌒╮⌒╮,,',,;; ⌒╮'╭⌒╮⌒╮.╭WWWW╮'''',,',,',,.,.,,.,.;; ╱◥██◣'';',( ●_●),,,,东戳一下西顶一下;; ︱田︱田田| ⌒╮''/▇\ '','''',,,;,.,,,;,.,,;; ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ |
雁塔菜农 2007-1-2 03:13
倒塌了~~~有错才叫原创.无错叫抄袭~~~
菜农从来不遮羞~~~
用户185588 2007-1-1 19:26
菜农的TWI怎么不改正过来?
老帖子也要润色润色
象匠人一样,多加些酱油和醋