首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++中的宏控制AVR芯片中某一端口上的一位

用C++中的宏控制AVR芯片中某一端口上的一位
EN

Stack Overflow用户
提问于 2020-10-25 15:24:35
回答 1查看 484关注 0票数 0

我有使用CodeVisionAVR进行AVR编程的经验。最近我转而使用Atmel Studio,发现了一个很小但很烦人的问题:我不能像在CodeVisionAVR中那样轻松地控制每个PIN/端口。

首先,让我们初始化一个特定的端口:

代码语言:javascript
复制
// Initialzing one port, for example PORT D:
// Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out 
DDRD=0x01;
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=1 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (1<<PORTD0);
// After initializing, Port D bit 0 should be the only pin set to out.

在CodeVisionAVR中,我可以这样做:

代码语言:javascript
复制
PORTD.0 = 0; // Set Port D bit 0 to low
PORTD.0 = 1; // Or to high

但在Atmel Studio中,将端口D位0寻址为PORTD.0会给我一个错误。我不得不这样做:

代码语言:javascript
复制
PORTD = (1<<PORTD0); // Set Port D bit 0 to high
PORTD = (0<<PORTD0); // and low

正如您所看到的,通过位移位进行寻址不那么整洁,也更难读写。我以为CVAVR使用了类似于结构的东西来模仿圆点(.)addressing方法(在C中我们没有类),或者一些重载操作符,或者一些宏,但在CVAVR中挖掘了包含的头文件后,我只能找到以下内容:

代码语言:javascript
复制
sfrb PORTD=0x12;
// ... other ports ...
sfrb PIND=0x10;

我的问题是,我可以在Atmel Studio中模仿CVAVR的位寻址方法吗?如果是,是如何实现的?或者这是IDE独有的特性?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-25 16:15:45

您对CodeVisionAVR的看法

代码语言:javascript
复制
PORTD.0 = 0; // Set Port D bit 0 to low
PORTD.0 = 1; // Or to high

不是有效的C语义,所以如果您没有在谓词上犯错误,那么它一定是一个codevision编译器扩展。

C中的这种赋值表示结构访问,但您不能声明以数字开头的结构成员(或任何其他标识符),因此PORTD.0将产生错误。

同样,当你这样做的时候:

代码语言:javascript
复制
PORTD = (1<<PORTD0); // Set Port D bit 0 to low
PORTD = (0<<PORTD0); // and high

您不是在做注释,而是在第一个表达式中将0x1赋值给PORTD,在第二个表达式中赋值为0x0 (假设为PORTD0==1)。如果你打算只操纵一个比特,这就是你应该做的:

代码语言:javascript
复制
PORTD |= (1<<PORTD0); //sets bit PORTD0 high in PORTD 
PORTD &= ~(1<<PORTD0); //sets bit PORTD0 low in PORTD 
PORTD ^= (1<<PORTD0); //toggles PORTD0 in PORTD 

您应该阅读有关C、here is a post with more examples中位操作的内容

有时这些操作被封装在一个宏中,这是一个如何做到这一点的示例:

代码语言:javascript
复制
#define BitSet(Port,Bit) (Port|=(1<<Bit))
#define BitClear(Port,Bit) (Port&=~(1<<Bit))
#define BitToggle(Port,Bit) (Port^=(1<<Bit))

#define SetBits(Port,BitMask) (Port|=BitMask)
#define ClearBits(Port,BitMask) (Port&=~BitMask)
#define ToggleBits(Port,BitMask) (Port^=BitMask)



//then you can use it
BitSet(PORTD,0) ; //Sets the bit0
BitSet(PORTD,1) ; //Sets the bit1
BitSet(PORTD,2) ; //Sets the bit2
// or
BitSet(PORTD,PORTD0) ; //Sets the bit0
BitSet(PORTD,PORTD1) ; //Sets the bit1
BitSet(PORTD,PORTD2) ; //Sets the bit2
...

SetBits(PORTD,0x55) ; //Sets the bits 0,2,4, and 6. Leaves the other unchanged
ClearBits(PORTD,0x55) ; //Clear the bits 0,2,4, and 6. Leaves the other unchanged
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64521334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档