关于AVR单片机的程序问题

来源:百度知道 编辑:UC知道 时间:2024/05/15 09:33:03
#define PIN_RXD 0 //PD0 RXD
#define PIN_TXD 1 //PD1 TXD
#define LED0 0 //PB0
#define LED1 1 //PB1
#define LED2 3 //PB3
#define BAUDRATE 9600 //波特率
//#define F_CPU 7372800
#define LED0_ON() PORTB|= (1<<LED0)
#define LED0_OFF() PORTB&=~(1<<LED0)
#define LED1_ON() PORTB|= (1<<LED1)
#define LED1_OFF() PORTB&=~(1<<LED1)
#define LED2_ON() PORTB|= (1<<LED2)
#define LED2_OFF() PORTB&=~(1<<LED2)
//全局变量
//如果变量会在中断服务程序中被修改,须加volatile限定
volatile unsigned char FLAG; //按键标志
volatile unsigned char PC_COMMAND;
volatile unsigned char RX_BUFFER[16];
volatile unsigned char RX_index;
void put_c(unsigned char c) //发送采用查询方式
{
while( !(UCSRA & (1<<UDRE)) );
UDR=c;
}
void put_s(unsigned char *ptr)
{
while (*ptr)
{
put_c(*ptr++);
}
put_c(0x0D);
put

你这个问题其实和AVR单片机没关系,任何一个MCU都可以采用类似的代码。
在C语言里,有值传递这个概念,这是因为编译器会优化程序,为变量做一个拷贝值。这样呢,cpu在计算这个值时,直接去取拷贝值,而不用去计算这个值的地址,然后寻址,再去取这个值,从而节省了一定的指令周期。但是,有一个隐患,这个变量的拷贝值和这个变量的真实值不一定是一样的。比如,当中断发生时,cpu会将所有变量入栈去执行中断服务子程序,然后返回到主程序。在这个过程中,如果中断服务子程序修改了某个公共变量,主程序是不知道的,因为主程序会调用入栈前的拷贝值。
volatile就是告诉编译器,不要优化,不要拷贝,而是让cpu寻址取值。
FLAG是一个全军变量,它既在主程序中使用,又在串口接收中断服务程序中使用,所以要用volatile修饰,告诉cpu取真实值