打印

^异或?

[复制链接]
楼主: areshan
手机看帖
扫描二维码
随时随地手机跟帖
21
异或就是将某一位取反,没有任何问题

使用特权

评论回复
22
nongfuxu| | 2011-6-23 06:34 | 只看该作者
学习了.

使用特权

评论回复
23
linqing171| | 2011-6-23 06:48 | 只看该作者
port就是缓冲寄存器了,pin才是输入。
异或运算,逻辑上不存在问题。
编译器也不存在问题。

感觉最大的问题是你的管脚,可能默认是输入的,AVR应该是及其弱的1,被你瞬间电平变化给干扰了。
你可以看看电平变化的管脚是哪个,然后在继续分析。

使用特权

评论回复
24
linqing171| | 2011-6-23 06:50 | 只看该作者
不知道我说明白没有,你变化的这个管脚,干扰了隔壁的悬空的输入脚,所以它电平变化了。
AVR电平变化中断也是半个指令周期来滤波的,不存在数字电路的冒险触发的可能性。你时钟是多少M?

使用特权

评论回复
25
dqyubsh| | 2011-6-23 07:48 | 只看该作者
不管异或指令本身有没有问题,这绝对不是一个好习惯。明明要变化一个管脚,却把整个8位同时拿来运算,即便需要的那个位变对了,其它7位怎么办?

你可能会说,我那几位悬空没用啊!可是,老大,你今天悬空,明天可能就接上了外设,这个设计悬空不等于下个设计也悬空。难不成你每次设计都把这个端口的数值改来改去?吃饱了撑的?闲的蛋疼?

这不关乎你会不会用异或,而是最起码的技术素质。你要非常明确你要修改什么,然后直截了当地修改那个变量,而不是耦合上其它不相关的因素。一个没有移植性的C程序,跟汇编有什么区别?简直是倒退!

使用特权

评论回复
26
PaperKite| | 2011-6-23 08:19 | 只看该作者
学习了

使用特权

评论回复
27
xwj| | 2011-6-23 08:26 | 只看该作者
呵呵,25楼有点自相矛盾哦,偶帮板LZ说几句:P

1、异或、与、或等操作指令并没有什么问题,本身并不会出现“即便需要的那个位变对了,其它7位怎么办?”的问题或者烦恼,而不用管是否“那几位悬空没用啊!”否则C语言也就没法用也没人用了(比如电脑等没有位操作指令的);

2、LZ用异或可以说本身就是为了做一个“有移植性的C程序”,而不是没有。因为这是任何C编译器都支持的并应该直接编译通过的。(不过个人觉得这种和硬件直接相关的程序严格来说应该用宏,既保证可移植性也可随时根据硬件修改来更改端口,而不用去改动主体程序)

3、AVR的指令集有方便的地方,比如有单周期的读写端口指令IN、OUT,有位操作指令SBI、CBI可以直接操作IO端口寄存器,却偏偏没有端口取反的指令,所以要实现这个操作还非得用异或不可,这点实在是....:P

4、LZ 16楼的代码感觉不对劲,不知道你PORTD.OUT是咋定义的
areshan发表于 2011-6-22 17:24 | 只看该作者 回复 引用 屏蔽 评分 报告 返回版面 TOP  得分:0
16楼: 339:              PORTD.OUT^=PIN3_bm;
+0000038B:   91800000    LDS       R24,0x0000     Load direct from data space
+0000038D:   2789        EOR       R24,R25        Exclusive OR
+0000038E:   8384        STD       Z+4,R24        Store indirect with displacement

使用特权

评论回复
28
xwj| | 2011-6-23 08:32 | 只看该作者
赞同23、24楼的说法,有这种可能,
不然偶也想不出除了编译器BUG还能有什么了
(呵呵,当然,还可能是老x孤陋寡闻了:))

使用特权

评论回复
29
t.jm| | 2011-6-23 08:47 | 只看该作者
不管异或指令本身有没有问题,这绝对不是一个好习惯。明明要变化一个管脚,却把整个8位同时拿来运算,即便需要的那个位变对了,其它7位怎么办?

你可能会说,我那几位悬空没用啊!可是,老大,你今天悬空,明天可能 ...
dqyubsh 发表于 2011-6-23 07:48

对于 非读-修改-写的端口设计 这样操作没问题,
但是对于 读-修改-写的端口设计确实会有隐患!

使用特权

评论回复
30
xwj| | 2011-6-23 08:57 | 只看该作者
对于AVR,端口的输入输出寄存器是各自独立的,不存在隐患。

而且,AVR除了异或或者 对端口输出寄存器  读-修改-写,还真没别的方法。

至于说16楼的编译代码不对,是因为定义正确并且优化级别正确的话应该会被编译成端口寄存器操作,而不是地址操作,而且是间址操作

早期的MPU都没有位操作指令,执行位取反都使用异或操作!

例如:   C程序       PORTB ^= 0x01;           //  对PORTB口的0位取反

       汇编程序      IN        R20,PORTB           ;  读入PORTB口数据到R20
                               LDI       R21,0x01             ;  R21设置为0x01            
                               EOR      R20,R21               ;  R20,R21异或(将0位取反),值送R20               
                               OUT      PORTB,R20           ;  将R20的值送PORTB口123jj 发表于 2010-8-7 13:47

使用特权

评论回复
31
ZRL700424| | 2011-6-23 09:03 | 只看该作者
对于 非读-修改-写的端口设计 这样操作没问题,
但是对于 读-修改-写的端口设计确实会有隐患!
t.jm 发表于 2011-6-23 08:47


说反了,对于 读-修改-写的端口 使用异或指令才可靠,用位操作指令才有可能出问题。

使用特权

评论回复
32
t.jm| | 2011-6-23 09:11 | 只看该作者
说反了,对于 读-修改-写的端口 使用异或指令才可靠,用位操作指令才有可能出问题。
ZRL700424 发表于 2011-6-23 09:03

对于读-修改-写用异或也是不可靠的,对于置1、置0要看它怎么设计的,只是因为一般的置1、置0其实本质就是 读入-修改-写入。所以说异或也肯定是不可靠的。

使用特权

评论回复
33
areshan|  楼主 | 2011-6-23 09:15 | 只看该作者
本帖最后由 areshan 于 2011-6-23 09:25 编辑

下降沿中断pd2(输入),用来异或的管脚是pd3(输出)!,谢谢linqing,讲解的好深入!
用的是4M的时钟,通过PLL倍频到20M的! 24# linqing171

使用特权

评论回复
34
areshan|  楼主 | 2011-6-23 09:26 | 只看该作者
没有想到小小的端口里面还有这么多的门道!:lol,自己要努力!

使用特权

评论回复
35
eydj2008| | 2011-6-23 13:49 | 只看该作者
是的 一般都是20楼的写法

使用特权

评论回复
36
dqyubsh| | 2011-6-23 14:20 | 只看该作者
说过说端口可以用异或的,拜托找几个成熟的代码给大家展示一下,可以去看AVRLIB,去国外一些开源的网站去翻。

国内的代码我不认可,找到也别吭声。敢说编译器通过就没问题的人,赶紧收拾收拾,死了算了。

找到了,贴出来,我服气,给大伙道歉。找不到,拜托也说一声,免得祸害后人,殃及子孙。

使用特权

评论回复
37
ZALIN| | 2011-6-23 16:16 | 只看该作者
XMEGA有专门的反转寄存器的

后期的AVR也可以写PIN寄存器来实现反转端口的

看LZ的这句汇编代码好象确实有问题,“LDS       R24,0x0000”

使用特权

评论回复
38
gbchang| | 2011-6-23 17:08 | 只看该作者
本帖最后由 gbchang 于 2011-6-23 17:16 编辑

我不喜欢在端口上异或,
从定义上也可以看出,芯片厂商希望用户怎么用这个:PORTOUT
从前用51,突然有一天用AVR,发现这个定义,直叹高明。

使用特权

评论回复
39
dqyubsh| | 2011-6-24 08:03 | 只看该作者
我同意37,38楼。

端口异或是一种不负责任的“创新”,把单纯的软件思维照抄照搬到硬件上,这种惯性思维只图自己快活,不管硬件死活,是彻头彻尾的错误。
简单地说,敢这样用异或的人,牙根没看过硬件手册,不了解单片机IO口的结构,不知道管脚怎样定义。更不确切知道哪些语句负责IO。

下面是AVR一段操作IO的代码,比较一下与上述帖子中的反汇编有什么区别:


可以看出,操作端口的汇编语句是,读——IN,写——OUT;C语言里是读是INPx,写是PORTxn。

不仅是AVR,现在流行的51,如CY7C68013,都已经有了端口输入输出的方向控制控制,如OE寄存器,而且输入输出的都是分别控制的。目的是让程序员非常明确地表达自己的意图,而不是越来越含糊不清。

任何脱离硬件的写法都是闭门造车。C语音本身和编译器都不是万能的,最后的屏障是程序员自己。如果你在写程序的时候放任自己,势必增加了硬件行为的不确定性,结果也是未知的,模糊的。

使用特权

评论回复
40
ZRL700424| | 2011-6-24 08:34 | 只看该作者
请问:如果我要对PORTD的第7位取反,应该如何写呢?

使用特权

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

本版积分规则