qiuxiangkai 发表于 2009-12-3 13:03:37

感谢傻孩子,你的X档案救我出苦海,哈哈

前两周买了本你的书,读了一下很爽。
参考了你写工程结构的twi程序,想做m8双机通信。protues上仿真通过,烧板子上没调通,比较郁闷,想想twi就那么回事,就偏偏调不好。找了N多原因,如上拉,时钟,线路,程序怎么也没找出问题,后来干脆用主机程序读写24C64看看能否通过,结果都是一个奇怪的问题:

主机能寻址到从机,从机也能被寻址到,但接着问题就来了,主机竟然重新发起start 信号,对状态机
//清零控制位,方便后面的操作,同时应将TWINT清零,否则将等同
//“向TWINT写1清零”操作,将误启动总线,陷阱

TWCR &= ~(1 << TWINT)|(1 << TWEA)|(1 << TWSTO)|(1 << TWSTA);
case SLA_ADDRESS_ACK:
                        if(flag2 == 0)      //发送单字节数据
                        {
                                TWDR = byte;

                        }
                       
                        else if(flag2 == 1)//发送多字节数据
                        {
                                TWDR = *(data + data_counter);
                                data_counter += 1;//发送数据串的第一个数据
                               
                        }
                       
                                        //sla_w ack

                break;



                     TWCR |= (1 << TWEN)|(1 << TWINT);
中发送数据的操作不理睬,检查了下我的操作没有问题吧。如果我在从机寻址应答后发送一个stop信号则能够正常响应。但是响应过后马上又一个start信号

坦白地说,这个问题搞了好久,好痛苦。
昨晚看了你的X档案,提到对TWCR寄存器的如
TWCR |= (1 << TWEN)|操作实质是一个读-修改-写的过程(在你书上看到过,但只重视了twint位的影响)。今天再次调试了下,正常发现进入case SLA_ADDRESS_ACK: 操作完毕后,执行
TWCR |= (1 << TWEN)|(1 << TWINT);状态寄存器的标志位为0x10,说明TWSTA位早已神不知鬼不觉地置一了,火大,在
TWCR |= (1 << TWEN)|(1 << TWINT);前加一句TWCR &= ~(1 << TWSTA);之后一切搞定,通信成功的指示灯终于亮了。

即便是这样小小的问题,要深入思考才会有结果。像之前一样的无头苍蝇真是太可悲了。

http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_510299.jpg
波形 (原文件名:PIC_1866.jpg)

http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_510300.jpg
现在终于知道问题的根源了 (原文件名:PIC_8088.jpg)

oldfang 发表于 2009-12-3 16:04:11

MARK

Gorgon_Meducer 发表于 2009-12-4 09:36:55

感觉你遇到的问题可能不是那么简单……

oldfang 发表于 2009-12-4 09:47:38

才发现2楼的笑容有点那个~~

looker 发表于 2009-12-4 09:48:23

mark

qiuxiangkai 发表于 2009-12-4 15:47:59

坦白地说我还不知道为什么start会置一,但问题就是出在这里,把新加的一句请零start注释掉就不能通信了。
还请傻孩子指教。我的操作都是按常规来的,被这问题卡了好久。

Gorgon_Meducer 发表于 2009-12-4 16:09:33

把你的通讯状态机贴出来……
最好能做一个 复现 问题的最小化工程……不然无法帮你分析啊……

qiuxiangkai 发表于 2009-12-9 12:42:39

原来是我的位操作出了问题,
在进入twi中断的时候我是这样写的:

TWCR &= ~(1 << TWINT)|(1 << TWEA)|(1 << TWSTO)|(1 << TWSTA);
结果是后面的位无法清零。

加个大括号

TWCR &= ~((1 << TWINT)|(1 << TWEA)|(1 << TWSTO)|(1 << TWSTA)); 就好了。

谢谢傻孩子,菜鸟的问题总是比较雷人。

Gorgon_Meducer 发表于 2009-12-10 00:01:04

不过至少通过这个问题,让你对TWI TWCR寄存器有了一个比较深刻的认识。
页: [1]
查看完整版本: 感谢傻孩子,你的X档案救我出苦海,哈哈