打印
[AVR单片机]

不喜欢9位模式~~~飞船受"**"影响太重---"程式"~~~村里叫"程

[复制链接]
7349|42
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lwking412|  楼主 | 2008-5-10 20:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
《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问了,但是没人教我,希望这里有好心人,教教我,我真的看不懂,并非偷懒,很着急,初学avr好难

相关帖子

沙发
宇宙飞船| | 2008-5-10 21:58 | 只看该作者

的确有错,resh应定义成16位unsigned int resh

unsigned int USART_Receive(void)
{unsigned char status,resh,resl;//才8位定义。
。。。。
Return ((resh<<8)|resl);//resh 原定义是8位,resh左移后变成0了,真垃圾!

使用特权

评论回复
板凳
dai_weis| | 2008-5-10 22:12 | 只看该作者

可以直接读取RB8(GCC中)不必读取寄存器值

使用特权

评论回复
地板
宇宙飞船| | 2008-5-10 23:25 | 只看该作者

这个程式有致命的逻辑错误,等所长的详细分析!

使用特权

评论回复
5
lwking412|  楼主 | 2008-5-10 23:42 | 只看该作者

麻烦解释详细点

谢谢各位帮我,可是貌似问题还是没解决啊,能否1.关于return -1代表什么意思啊,是不返回的意思么 
2.resh=(resh>>1)&0x01; 
Return ((resh<<8)|resl);是什么意思啊 
回答下啊,稍微详细点

使用特权

评论回复
6
宇宙飞船| | 2008-5-10 23:46 | 只看该作者

这个程式99%都能看懂,但有致命性的设计错误,

还是请所长来分析,这可不是俺的特长,呵。。。呵。。。

使用特权

评论回复
7
lwking412|  楼主 | 2008-5-10 23:49 | 只看该作者

难道现在的书都是错误频频么,对于初学者好难

如上,还请大家费点心,教教我,本人真的很急,哎,有不懂的问题,周围连个请教的人都没,只能上网靠大家帮忙了

使用特权

评论回复
8
hotpower| | 2008-5-10 23:51 | 只看该作者

不喜欢9位模式~~~飞船受"**"影响太重---"程式"~~~村里叫"程

使用特权

评论回复
9
宇宙飞船| | 2008-5-10 23:58 | 只看该作者

打漏了“人”字,这个程式99%的‘人’都能看懂

使用特权

评论回复
10
宇宙飞船| | 2008-5-11 00:00 | 只看该作者

所长的MCU比俺的三脚猫功夫精得多了,

宇宙飞船 发表于 2008-5-10 23:39 AVR 单片机  ←返回版面  

103楼: 比俺的三猫功夫还精,肯定发现以上的致命Bug的!

农民讲习所 发表于 2008-5-9 22:47 AVR 单片机  ←返回版面
66楼: 马甲zhousd说得太过分了
你不如说反对飞船就是反奥运、反D、不爱国。

起码俺就自认为比飞船学得精,飞船太爱面子了。

使用特权

评论回复
11
lwking412|  楼主 | 2008-5-11 00:02 | 只看该作者

再帮我看看吧

2位,能否帮我讲解一下,至少解释下resh=(resh>>1)&0x01; 
这句吧
我很着急呢

使用特权

评论回复
12
dai_weis| | 2008-5-11 00:07 | 只看该作者

求得RB9 的值而已

使用特权

评论回复
13
宇宙飞船| | 2008-5-11 00:07 | 只看该作者

把RX8第9位取出来,

resh=UCSRB; //UCSRB--b7,b6,b5,b4,b3,b2,RX8,b0
resh=(resh>>1)&0x01; 

使用特权

评论回复
14
dai_weis| | 2008-5-11 00:10 | 只看该作者

呵呵,俺求楼主您去看看手册好么

到处都有中文的,例如中文版(官方)的mega8手册第142页就写了关于寄存器的详细叙述。

使用特权

评论回复
15
hotpower| | 2008-5-11 00:15 | 只看该作者

马潮老师被21ic的高手忽悠出走前留下的7条裤头~~~

使用特权

评论回复
16
宇宙飞船| | 2008-5-11 00:15 | 只看该作者

程式的确有致命性的设计逻辑错误,还是请农讲所长分析,

使用特权

评论回复
17
dai_weis| | 2008-5-11 00:20 | 只看该作者

是不是这个错了?

while (!(UCSRA&(1<<RXC))); 
应该是:while (UCSRA & (1 << RXC));

呵呵还有我还是习惯使用习惯的称法 :

程序

使用特权

评论回复
18
lwking412|  楼主 | 2008-5-11 00:21 | 只看该作者

还是不懂,再帮我看看啊

手册我看了,我知道首先要先从RXB8读取第9位,  我不理解的是 如何把RX8第9位读取出来呢?
就好比这个句子
resh=(resh>>1)&0x01; 
 
既然之前已经有了resh=UCSRB,那么resh>>1就是把UCSRB的位1 RXB位右移1位,这样RXB位的数值就移动到了第0位上,在于0x01相&代表什么呢?这样一来,resh的值只有两种情况00000001或者00000000.这两种情况又能代表什么呢。RXB8是第一位,而不是第0位,而上面这个句子是第0位分别位0和1的情况
所以就不明白了 

使用特权

评论回复
19
lwking412|  楼主 | 2008-5-11 00:22 | 只看该作者

while (!(UCSRA&(1<
while (!(UCSRA&(1<<RXC))); 
应该是:while (UCSRA & (1 << RXC));
这个应该不会错,很多都是这种用法while (!(UCSRA&(1<<RXC))); 

使用特权

评论回复

20
dai_weis| | 2008-5-11 00:25 | 只看该作者

晕了,你需要的是第九位的结果,不想看到其他的

所以只要第九位的结果存在就行,于是乎,移位到第0位,然后按位与只保留第0位那个RB0 的结果。
晕乎,我学习语文去了,好像越说越糊涂,总也表述不清。

使用特权

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

本版积分规则

8

主题

32

帖子

0

粉丝