×
单片机 > 单片机程序设计 > 详情

AVR编程_位定义

发布时间:2020-09-02 发布时间:
|
Question
在我的源代码中如何进行位定义?
Answer

我们总是在AVR器件数据手册中推荐使用位定义的方式来编写你的C或汇编源代码。

位定义与器件手册的该位定义一致的话可以很方便的理解代码的含义和让其他人更好的理解你的代码。同时,如果你需要移植你的代码到其他的AVR器件,用位定义可以很方便的进行移植,因为不同的AVR器件的绝对地址和位的位置或许不同,但是位定义通常都保持一致。当移植一个设计,经常需要包含正确的定义文件。

在不同的AVR器件的编译器包含文件中,所有的I/O寄存器位命名和位置都被定义了。

下面是一个Atmega16在WinAVR中的例子,iom16.h包含文件中TXEN(使能USART发送器)和RXEN位(使能USART接收器)定义如下:

#define UCSRB _SFR_IO8(0x0A)
#define TXEN 3 //Bit 3
#define RXEN 4 //Bit 4

因此,在代码中,写UCSRB = (1<

 另一个汇编和c代码的例子如下:

汇编代码

***************************************************************
...
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1< ldi r17,(1< out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB
...
***************************************************************

C代码
***************************************************************
unsigned char i;
...


PORTB = (1< DDRB = (1<
asm("nop");

i = PINB;
...
***************************************************************

为了避免各多的附加功能和寄存器功能的冲突,不要访问被标注为保留的寄存器位。保留的寄存器总是被写为0。这能确保前向兼容性,同时当前未用的功能将都保持在默认的状态。

 

____________________以下为老于添加,2009/06/07________________________

读取外部引脚电平时,应读取PINX.n的值,比如,

1)判断PD6是否高电平:

if(PIND & (1<<6))...

 

2)等待PD6变为低电平,如判断ADC转换完成

while( !(PIND & (1<<6) );

或者写成:

while( (PIND & 0x40) == 0x40 );

需要注意的是,在纯粹软件环境下,如VC,一个变量与一个常量与操作之后,往往会改变该变量的值,如

unsigned char ch = 0xc0;

unsigned char ch1 = ch & 0x40;

此时ch1 = 0x40,其值已经改变。

 

而读取管脚的输入状态,PINX,或者读取寄存器数据,如UCSR0A串口接收寄存器的内容,该数值与一个常量与操作之后,并不会改变其内容本身,即,下次再读取PINX和UCSR0A,其值不会改变,除非硬件条件发生了改变它才会发生变化。这些变量依存于硬件环境。

这也是初学者对变量,常量,位操作使用上容易混淆的问题所在。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32 USB HID 键盘