[AVR单片机] 如何在一个IO寄存器中同时清空和置位2个不同的位

[复制链接]
 楼主| 高建明 发表于 2007-5-21 15:05 | 显示全部楼层 |阅读模式
我想在一个IO寄存器中同时清空和置位2个不同的位,该怎么做?
以前是这样搞的
        PORTA|=(1<<PA0);
        PORTA&=~(1<<PA1);
如何才能合并成一句?
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”,多位类推。我也是才学哈,不对请高人指点。
John_Lee 发表于 2007-5-29 11:24 | 显示全部楼层

这样可以

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

这样能做到同时改变 PA0 和 PA1 的电平,但整体效率比楼主的方法要慢些。
 楼主| 高建明 发表于 2007-5-29 12:17 | 显示全部楼层

re

PORTA=(PORTA&~(1<<PA1))|(1<<PA0));
beiji1984 发表于 2007-5-29 21:01 | 显示全部楼层

我喜欢这样

PORTA=_BV(PA0)|_BV(PA1);
DDRA=_BV(PA0)|_BV(PA1);
阿发 发表于 2007-5-29 22:19 | 显示全部楼层

比较喜欢5楼的方法

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

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

5楼的方法非常科学,应该是位高手。(欢迎来AVR论坛)
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型中断中执行以上代码,则无需考虑这个问题!
cqtrw 发表于 2007-6-3 02:26 | 显示全部楼层

ATMEL这样作

ATMEL的一段程序中是这样处理既置一些位又清零一些位的:
TCCR1B = (0<<WGM13)|(0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);
都是位操作,I/O寄存器也应一样。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

203

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部