lwking412 发表于 2008-5-10 18:30:08

关于马老师《atmega128原理与开发应用指南》USART接收9位数据的例子139页,看不懂

马老师《atmega128原理与开发应用指南》上的例子,接收9个数据位的帧
马老师给的例子如下:
unsigned int USART_Receive(void)
{unsigned char status,resh,resl;
/*Wait for data to be received*/
while (!(UCSRA&(1<<RXC)));
/*Get status and 9th bit,then data from buffer*/
status=UCSRA;
resh=UCSRB;
resl=UDR;
/*IF error,return -1*/
if(status&(1<<FE)|(1<<DOR)|(1<<PE)
return -1;
/*Filter the 9th bit,then return*/
resh=(resh>>1)&0x01;
Return ((resh<<8)|resl);
}
这个例子不懂的地方有两个
1.关于return -1代表什么意思啊,是不返回的意思么
2.resh=(resh>>1)&0x01;
Return ((resh<<8)|resl);是什么意思啊
既然resh=UCSRB,那么resh>>1就是把UCSRB的位1 RXB位右移1位,这样RXB位的数值就移动到了第0位上,在于0x01相&代表什么呢?这样一来,resh的值只有两种情况00000001或者00000000.不明白这样有什么用
另外最后一步resh<<8的话,不就变成00000000.在于resl或,值不变啊。不是多余的么?干吗不直接写 Return resl

可能我的问题很幼稚,但是初学avr,对这个问题我刚想了很久,还是不明白,也许自己基础太差,也许真的没有天分把,呵呵,有点心灰意冷了。希望这次能得到大家的帮助。

machao 发表于 2008-5-11 12:48:53

这段程序是数据手册中的C代码示例,只是给出提示.整理清楚一点如下:

if(status&(1<<FE)|(1<<DOR)|(1<<PE)
    return -1;                           /*IF error,return -1*/
else
{
    resh=(resh>>1)&0x01;
    Return ((((int)resh)<<8)|resl);               /*Filter the 9th bit,then return*/   
}


1.关于return -1代表什么意思啊,是不返回的意思么
>> 返回-1,表示出现错误.

2.resh=(resh>>1)&0x01;
既然resh=UCSRB,那么resh>>1就是把UCSRB的位1 RXB位右移1位,这样RXB位的数值就移动到了第0位上,在于0x01相&代表什么呢?
>>这就是仅保留了第9位的值,

3.Return ((resh<<8)|resl);是什么意思啊
>> 返回16位的结果:低8位是数据帧中前8位的值,高8位中是第9位值(结果全部是正的):
   000000x xxxxxxxx
   注意:正确应该是:Return ((((int)resh)<<8)|resl),即将resh强行转换成16位后再移位.

lwking412 发表于 2008-5-12 11:39:51

谢谢马老师,非常感动,根本没想到您会亲自恢复指导我

lwking412 发表于 2008-5-12 11:43:03

但是还有一个小问题
就是 关于这句话
注意:正确应该是:Return ((((int)resh)<<8)|resl),即将resh强行转换成16位后再移位.

如果就按照Return ((resh<<8)|resl); 手册这种写法是不是也可以啊,因为已经定义了
unsigned int USART_Receive(void)
所以隐含了返回值自动转换为16位。所以即使不写成Return ((((int)resh)<<8)|resl),也能表达同样的意思,对么?

machao 发表于 2008-5-13 22:22:15

resh原定义是8位的,左移8位为0了,再与resl合并后,转换成16位已经没有用了.
先把resh转换成16位,左移8位,resh的值到了高8位,与resl(低8位)合并成结果才正确.

lwking412 发表于 2008-5-13 23:45:04

您这么说我反倒糊涂了,数据手册上是Return ((resh<<8)|resl); 您的意思是数据手册有问题,应该改成Return ((((int)resh)<<8)|resl),是么
但是不知为何,有网友说C语言<<自动将不满int型扩展成int型(这是C语言标准)。
可我感觉这标准怪怪的,只能请马老师给解释下了

machao 发表于 2008-5-13 23:59:23

是的.

我写的保证正确的.手册上按标准C给出.但在具体使用一个C环境时,可以写一个简单的程序测试一下,对于8位单片机的C,由于为了保证资源的使用,可能与标准的C有差别.

lwking412 发表于 2008-5-14 13:05:31

明白了,谢谢老师

machao 发表于 2008-5-14 13:29:34

希望你先把C语言基础打好,否则与AVR硬件混在一起话,你不明白的还要多.

lwking412 发表于 2008-5-15 00:13:14

我明白的。c最近看了一遍,不过感觉很多问题只有在用的时候才会发现
另外大部分时间电磁场还是要学习,毕竟要发_论文毕业,感觉跨专业学习avr还是很辛苦

lwking412 发表于 2008-5-15 00:14:28

总之我一定要坚持学好它,
页: [1]
查看完整版本: 关于马老师《atmega128原理与开发应用指南》USART接收9位数据的例子139页,看不懂