longd99 发表于 2009-2-19 14:43:26

马老师您的《AVR单片机嵌入式系统原理与应用实践》P404页中间的中断程序有处不理解,

http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_420338.JPG
(原文件名:AVR.JPG)
如在这种情况下:单片机复位后一直没有执行getchar(void)函数,8次接收中断后接收缓冲区刚好满,有8字节数据,现在开始执行getchar(void)函数,是不是必须再发生一次接收中断才可以?那岂不是前面接收的8字节数据都作废了?

machao 发表于 2009-2-19 16:17:22

具体解释如下,并请参考后面的程序。

1。缓冲区为8个字节,指针rx_index从0-7,一旦到8马上清另。如果不清掉的话,一旦下次数据写到指针为8指向的单元,就可能把内存中其它变量数据冲掉,形成一个隐藏的BUG,而且还不好找,因此使用指针,必须养成良好的编程习惯(本栏有个帖子“百思不解的问题”可能就是由于指针的问题造成的)。

2.在这个例子中rx_counter不能等于9,如果等于9的话,那么你多收的字节肯定已经冲出缓冲区了。这里实际保留了一个字节。当然你可以改动程序,把 rx_counter的判断放到前面,如果到9了,就放弃,不写入缓冲区,或从0开始写。

3。LZ贴的是个比较规范的例子,是CVAVR自动生成的代码。按规范的写法,上层应该在执行getchar()前,先检验rx_buffer_owerflow标志,如果为1的话,表明下面有溢出了,读到的数据是不可靠的,应该执行错误处理。这是轨范的处理方式。尤其是全双工通信的应用中(缓冲区中最大保证7个字节,后面一个作为保护)。

4。实际上这样轨范的通信过程和程序的编写还是比较复杂的,而且对于实际的许多应用中也不需要,因此可以进行简化的处理。我后面实际使用例子就是这样做的。

5。在实际应用中,为了保证通信的可靠,通常采用半双工的方式,也就是说,单片机的收发不是同时进行的。我们需要对实际的东西进行分析,指定一个合理的通信规程。比如一个收发的通信包长度定为10个字节。这样,上位机每次只发10个字节,然后等待回答。而单片机就只需要开10个字节的缓冲 ,每次收10个字节。10个字节的接收在中断中,收到10个后建立标志位(后面也不收了),上层代码检查标志位为1了,判断10个字节的含义,然后给出相应的回答。上位机收到回答后,再继续下发。这样就不会出现溢出了。

6。如果需要批量的传送数据如1K,最好也是采用上面的方式:比如定义一个发送包的长度为32,那么1K的数据就需要拆成32个字节一组,发送一组后,等待回答,如果对方回答正确收到了,再继续发下32个字节....。

7。这样的处理方式在书中后面的实用例子里都体现了出来。所以我希望是掌握思想和方法,而不是机械的照搬照抄代码。

8。UART和RS232是最简单的通信接口了,USB,TCP/IP要复杂的多。因此在学习8位的应用过程中,要不断掌握和加强其它方面的基础知识学习,比如数字通信方面课程的学习。这样才有可能去使用32位等更高级和复杂的东西。

longd99 发表于 2009-2-19 17:21:35

谢谢马老师的回答!
页: [1]
查看完整版本: 马老师您的《AVR单片机嵌入式系统原理与应用实践》P404页中间的中断程序有处不理解,