打印
[AVR单片机]

关于USART通信的一个问题,,,,,,,,,,,,,,,,

[复制链接]
2069|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
大钟看台|  楼主 | 2012-8-14 11:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
从上位机发送一串超过一个字节的数据,比如:EE FF EC EA A8 EC FA AB
是从串口一起发送的
但是UDR一次只能接收一个字节,比如开头字节EE,剩下的字节FF EC EA A8 EC FA AB 会不会丢掉?还是暂存在哪里?

ps 有些转牛角尖 入门水平

相关帖子

沙发
大钟看台|  楼主 | 2012-8-14 11:01 | 只看该作者
求高手 谢了

使用特权

评论回复
板凳
mohanwei| | 2012-8-14 11:05 | 只看该作者
不会掉,在收完下一个字节之前,足够你读取几千次这个字节了

使用特权

评论回复
地板
大钟看台|  楼主 | 2012-8-14 11:26 | 只看该作者
3# mohanwei
谢谢回复啊

问题是这样:
               想做一个简单的485实验,就是上位机发送一串指令,单片机接受并返回给上位机

用中断方式接受,程序是这样,问题是我发送的时候,只返回第一个字节,而且第一次发送才能返回第一个字节,第二次以后什么返回都没了

ISR(USART_RXC_vect)
{

uchar data;

CLR(UCSRB,7);    //关闭接收中断允许开关

data=UDR;  //接收数据

NOP();

NOP();

NOP();   //#define NOP() asm("nop")

TX_485; //#define TX_485PORTD|=(1<<2) PD2为485发送控制端

while(!(UCSRA&(1<<UDRE)));

UDR=data; //将接收到的数据发送回原串口

while(!(UCSRA&(1<<6))); //等待发送完毕

SET(UCSRB,7);  //开启接收中断允许开关

RX_485;//#define RX_485 PORTD&=(~(1<<2)) PD2为485接受控制端
}

使用特权

评论回复
5
大钟看台|  楼主 | 2012-8-14 11:28 | 只看该作者
还有,如果单片机RXD TXD直接通过max232接上位机串口,这个程序正常
但是用485通讯就不行了

使用特权

评论回复
6
coldra| | 2012-8-14 11:55 | 只看该作者
485是半双工的,全都收完了再发回去

使用特权

评论回复
7
大钟看台|  楼主 | 2012-8-14 12:30 | 只看该作者
6# coldra
对啊 我试一试

使用特权

评论回复
8
joyme| | 2012-8-14 16:11 | 只看该作者
即使是全双工的,LZ的写法也很糟糕,在接收中断里用查询法(while)去发送?

使用特权

评论回复
9
aaron96031| | 2012-8-14 20:38 | 只看该作者
直接依次接收就是了

使用特权

评论回复
10
大钟看台|  楼主 | 2012-8-14 22:26 | 只看该作者
8# joyme
while(!(UCSRA&(1<<UDRE))); 这句是多余的后来加的 想试一下 但证明是多余的

使用特权

评论回复
11
大钟看台|  楼主 | 2012-8-14 22:44 | 只看该作者
6# coldra
还是不行
程序改成这样
command_buffer[]是暂存的数组 command_index为下标

ISR(USART_RXC_vect)
{

CLR(UCSRB,7);    //关闭接收中断允许开关

command_buffer[command_index++]=UDR;  //接收数据

if(command_index==8)

{

command_send();

command_index=0;

}

SET(UCSRB,7);//开启中断接收
}

void command_send(void)
{

uchar i;

TX_485;

for(i=0;i<8;i++)

{

UDR=command_buffer;

while(!(UCSRA&(1<<TXC)));

CLR(UCSRA,TXC);


}

RX_485;

}

使用特权

评论回复
12
大钟看台|  楼主 | 2012-8-14 22:45 | 只看该作者
9# aaron96031
怎么说呢???

使用特权

评论回复
13
大钟看台|  楼主 | 2012-8-14 22:48 | 只看该作者
调试的时候 是这样
第一次发送:c0 00 01 00 00 00 01 c0
返回的是:c0 ff
第二次以后发送:c0 00 01 00 00 00 01 c0
返回的是:ff

使用特权

评论回复
14
大钟看台|  楼主 | 2012-8-14 23:28 | 只看该作者
还是没找到原因
为什么用232就可以
换了485就不行呢

使用特权

评论回复
15
joyme| | 2012-8-15 11:07 | 只看该作者
为什么非要把发送放在接收中断里呢?半双工发送时会把接收disable,上位机接下来发送的数据就丢了。
你都已经用了缓冲了,等接收完再一次发送就好了,中断里少做事(除非是实时要求)

使用特权

评论回复
16
coldra| | 2012-8-15 11:53 | 只看该作者
同意16楼,发送放在中断外面,在主程序做就可以了。而且在中断里关中断开中断的很多余,没有必要。
另外,发送也可以用中断来做。

使用特权

评论回复
17
njaplid| | 2012-8-17 09:37 | 只看该作者
发送也应该采用串口中断的方式,不过最好的办法是采用队列缓冲。(有的单片机自带缓冲)

使用特权

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

本版积分规则

4

主题

34

帖子

0

粉丝