打印
[AVR单片机]

如何在一个IO寄存器中同时清空和置位2个不同的位

[复制链接]
2709|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
高建明|  楼主 | 2007-5-21 15:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
goothin| | 2007-5-21 18:52 | 只看该作者

不能吧

使用特权

评论回复
板凳
高建明|  楼主 | 2007-5-21 21:26 | 只看该作者

直到了

使用特权

评论回复
地板
cqtrw| | 2007-5-29 11:19 | 只看该作者

应该可以吧

    按PORTA|=(1<<PA0);的意识是将0B00000001左移“PA0”位(应该是0),得到“0B00000001”,再和A口寄存器“或”,结果是将A口的0位置1了。若写为PORTA|=(1<<PA0)|(1<<PA1);结果应该是将A口的“0”位和“1”位同时置“1”,多位类推。我也是才学哈,不对请高人指点。

使用特权

评论回复
5
John_Lee| | 2007-5-29 11:24 | 只看该作者

这样可以

只有一个办法:
uint8_t temp = PORTA;
temp |= 1 << PA0;
temp &= ~(1 << PA1);
PORTA = temp;

这样能做到同时改变 PA0 和 PA1 的电平,但整体效率比楼主的方法要慢些。

使用特权

评论回复
6
高建明|  楼主 | 2007-5-29 12:17 | 只看该作者

re

PORTA=(PORTA&~(1<<PA1))|(1<<PA0));

使用特权

评论回复
7
beiji1984| | 2007-5-29 21:01 | 只看该作者

我喜欢这样

PORTA=_BV(PA0)|_BV(PA1);
DDRA=_BV(PA0)|_BV(PA1);

使用特权

评论回复
8
阿发| | 2007-5-29 22:19 | 只看该作者

比较喜欢5楼的方法

如果在实现同时置高或同时置低的话,那么用4楼的方法就挺好了。

如果又置高又置低,那还是用1楼的方法简单直观。

5楼的方法非常科学,应该是位高手。(欢迎来AVR论坛)

使用特权

评论回复
9
gooder1| | 2007-5-30 13:42 | 只看该作者

5楼的方法有点问题需要注意

5楼的方法非常科学,应该是位高手。(欢迎来AVR论坛)
-------------------------------
5楼的方法,当使能中断,且中断中有修改PA口的操作,则存在一定的隐患:

uint8_t temp = PORTA;  //0
temp |= 1 << PA0;      //1
temp &= ~(1 << PA1);   //2
PORTA = temp;          //3

可以想象,如果在执行完//0后,如果恰巧有中断执行了,修改PA2-PA7的电平,中断返回后,此改变后的电平将得不到保存!

如果在SIGNAL型中断中执行以上代码,则无需考虑这个问题!

使用特权

评论回复
10
cqtrw| | 2007-6-3 02:26 | 只看该作者

ATMEL这样作

ATMEL的一段程序中是这样处理既置一些位又清零一些位的:
TCCR1B = (0<<WGM13)|(0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);
都是位操作,I/O寄存器也应一样。

使用特权

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

本版积分规则

46

主题

203

帖子

0

粉丝