那个贴个例子,虽是M88的,用法都一样
平台:STK500 + IAR AVR + ATmega88
//********已调试********// /* PC0-PC5控制5个LED发光,正常时间隔1秒钟闪烁。PORTC送出0时LED亮(见原理图)。 PB0-PB5采用引脚电平中断方式响应按键事件。5个按键均为乒乓开关,控制相应的LED参与闪烁/不亮. 延时采用软件延时。 author: www.315avr.com */
#include <iom88.h> // 必须使用 #include <intrinsics.h> // 调用 __delay_cycles()的库声明
#define GET_BIT(x,y) (x&(1<<y)) // 定义读寄存器位的宏
char led,led_mask=0x00;
// 引脚电平变化中断 0-7 的中断服务程序 #pragma vector = PCINT0_vect // 注意在IAR中中断服务程序的定义方式 __interrupt void pcint0_isr(void) { if (!GET_BIT(PINB,0)) led_mask = led_mask ^ 0X01; if (!GET_BIT(PINB,1)) led_mask = led_mask ^ 0X02; if (!GET_BIT(PINB,2)) led_mask = led_mask ^ 0X04; if (!GET_BIT(PINB,3)) led_mask = led_mask ^ 0X08; if (!GET_BIT(PINB,4)) led_mask = led_mask ^ 0X10; if (!GET_BIT(PINB,5)) led_mask = led_mask ^ 0X20; }
void main(void) { CLKPR=0x80; CLKPR=0x01; //CLKPR=0x00 时钟分频1 //CLKPR=0x01 时钟分频2 //CLKPR=0x02 时钟分频4 //CLKPR=0x03 时钟分频8 //... ... // I/O端口设置 PORTB=0x3F; // PORTB输入,上拉有效 DDRB=0x00;
PORTC=0x00; // PORTC输出,初始输出全另 DDRC=0x3F;
// 引脚电平中断初始化 PCICR=0x01; // 允许引脚PCINT0-7电平变化中断 PCMSK0=0x3F; // 屏蔽引脚PCINT6-7的电平变化中断 PCIFR=0x01; // 清除PCINT0的中断标志
ACSR=0x80; // 禁止模拟比较器,省电
asm("SEI"); // 开放全局中断,注意在IAR-C中汇编语言的嵌入方式 // 也可使用在 <intrinsics.h>中定义的专用函数 void __enable_interrupt(void) __enable_interrupt();
while (1) { PORTC = led | led_mask; // 输出控制LED led = ~led; __delay_cycles(100000); // 延时1000000个时钟周期 }; }
|
|