新闻  |   论坛  |   博客  |   在线研讨会
AVR笔记7:外部中断INT0实验(GCC)
mayer | 2009-09-01 19:37:03    阅读:3424   发布文章

AVR笔记7:外部中断INT0实验(GCC)

 

》》点此进入    http://bbs.armavr.com/   ARM-AVR嵌入式开发论坛

一、程序结构
程序结构

二、仿真效果
点击看大图

三、程序源码
1、main.c
/*******************************************************************************
Platform : AVR mega16学习板(www.iccavr.com)
Project : 实验七:外部中断INT0实验(GCC)
Clock F : 3.6864M
Software: WinAVR-20071221+Proteus7.4
Author  : 林夕依然
Version : 08.12.06
Updata  : 09.02.26  模块化
          09.05.03  增加proteus仿真模型,仿真通过
    09.07.21  WinAVR-20071221环境下编译通过
comments:
1、以学习板流水灯和INT0键为硬件电路,练习INT0中断函数的编写
2、电路板上电后LED0进入无限闪烁状态,当按下INT0键后,程序进入四种模式流水灯,
   流水灯后程序返回LED0无限闪烁状态
3、使用GCC自带延时函数
4、同ICC比较,中断函数写法不同,中断向量名称也不相同,均需更改。
*******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "functions.h"

int main(void)
{
port_init();
GICR |= (1 << INT0);   //使能外部中断请求0
sei();                 //全局中断使能
while (1)
{
  PORTB = 0XFE;     //PB0置低,点亮LED0
  _delay_ms(500);
  PORTB = 0XFF;         //PB0置高,熄灭LED0
  _delay_ms(500);
}
}

2、functions.c
/*******************************
Platform : AVR mega16学习板(www.iccavr.com)
function :功能函数集
Clock F  : 3.6864M
Software : WinAVR-20071221+Proteus7.4
Author   : 林夕依然
Version  : 09.07.21
comments :
1、使用GCC自带延时函数,需包含"util/delay.h"
2、GCC中无参数的函数需要写为void,否则编译时会有警告产生。如:void LED_off(void)
********************************/
#include <avr/io.h>
#include <util/delay.h>
void LED_off(void)                       //关闭所有LED
    {
PORTB = 0xFF;
_delay_ms(1);
}

void LED_01(char i)                  //LED亮灭控制
    {
    PORTB = ~_BV(i);                //输出低电平
    _delay_ms(100);                   //调用延时程序
    }
void LED_02(char i)                  //间隔点亮
    {
PORTB=~(_BV(i)|_BV(i-2));
_delay_ms(100);
}

void LED_03(char i)                 //相临点亮
    {
PORTB=~(_BV(i)|_BV(i-1));      //~后内容需用括号括起来
_delay_ms(100);
}
//端口初始化程序
void port_init(void)
{
    DDRA = 0x00;    /*方向输入*/
PORTA = 0xFF;    /*打开上拉*/
DDRB = 0xFF;    /*方向输出*/
PORTB = 0xFF;    /*电平设置*/
DDRC = 0x00;
PORTC = 0xFF;
DDRD = 0x00;
PORTD = 0xFF;
}

3、int0_interrupt.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include "functions.h"
#define uint unsigned int
//INT0中断函数,与ICCAVR写法不同,中断向量名称也不相同
ISR(INT0_vect)
  {
      uint i,l,m,n,o;
      DDRB =0xFF;                         //端口输出
      PORTB=0xFF;                         //输出高电平,LED熄灭   
      
   for(l=0;l<2;l++)               //模式1:顺序点亮
          {
       for (i = 0; i < 8; i++)     //顺序单个点亮LED
                LED_01(i);
             for (i = 6; i > 0; i--)     //逆序单个点亮LED
                LED_01(i);
    }   
    LED_off();
   
      for(m=0;m<2;m++)               //模式2:顺序单个间隔点亮
    {
             for (i = 0; i < 8; i += 2)  //顺序间隔点亮LED
              LED_01(i);
             for (i = 7; i > 1; i -= 2)  //逆序间隔点亮LED(note1:当改为i>0时,程序异常,原因为循环被破坏)
              LED_01(i);
    }
    LED_off();
   
      for(n=0;n<2;n++)               //模式3:间隔点亮
    {
       for (i = 2; i < 8; i++)     //间隔顺序同时点亮
       LED_02(i);
    for (i = 6; i > 2; i--)  //间隔逆序同时点亮
       LED_02(i);
    }
    LED_off();
   
      for(o=0;o<2;o++)               //模式4:相临点亮
    {
       for (i = 1; i < 8; i++)     //相临顺序同时点亮
       LED_03(i);
    for (i = 6; i > 1; i--)  //相临逆序同时点亮
       LED_03(i);
    }
    LED_off();
     
  }

4、functions.h
void LED_off(void);
void LED_01(char i);
void LED_02(char i);
void LED_03(char i);
void port_init(void);

四、完整项目文件下载

http://bbs.armavr.com/thread-800-1-2.html

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客