一起学mini2440裸机开发(十一)--mini2440定时器0中断实验

时间:2022-04-20 23:30:31

   在前边讲解系统时钟和定时器时,曾给出一个实验,实现的功能是:使用定时器0的功能,使LED每秒钟闪烁一次,当时是使用查询方式实现的,现在使用中断方式实现上述功能。

   下图为我的工程文件布局:

   一起学mini2440裸机开发(十一)--mini2440定时器0中断实验

   下面贴出我的代码,你也可以去这里下载,

   http://download.csdn.net/detail/mybelief321/5457371  下载下来之后,直接编译,点击Flash/Download ,下载到nor flash中运行。

   main.c文件

#include"led.h"
#include"timer.h"
#include"isrservice.h"
#include"interrupt.h"

unsigned int flag=0;
int main()
{   
 Led_Init();             //初始化LED
 Timer0_Init();       //定时器0初始化
 Timer0_Interrupt_Init();    
//定时器0中断初始化

 while(1)            //循环,等待中断发生
 {  
  if(flag)
  {
   Led2_On();
  }
  else
  {       
   Led2_Off();
  }
 }
}

 

     led.c文件

 

/****************************************************
* 我的mini2440开发板上4个LED灯对应的GPIO口
* LED1---GPB5    LED2---GPB6
* LED3---GPB7    LED4---GPB8
*****************************************************/

#include<s3c2440.h>

/****************************************************
* 函数名称:void Led_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:设置GPB5-8为输出功能,初始化4个LED灯灭
*****************************************************/

void Led_Init(void)
{
  GPBCON&=~((3<<10)|(3<<12)|(3<<14)|(3<<16));
  GPBCON|=((1<<10)|(1<<12)|(1<<14)|(1<<16));  //设置GPB5-8口为输出功能
  GPBUP&=~((1<<5)|(1<<6)|(1<<7)|(1<<8)); //上拉电阻使能
  GPBDAT|=(1<<5)|(1<<6)|(1<<7)|(1<<8); //令GPBDAT5-8均为高电平,即令4个led灯全灭
}

 

    led.h文件

#ifndef __LED_H__
#define __LED_H__

#include<s3c2440.h>
#define Led1_On()  {GPBDAT&=(~(1<<5));}
#define Led1_Off()  {GPBDAT|=(1<<5);}
#define Led2_On()  {GPBDAT&=(~(1<<6));}
#define Led2_Off()  {GPBDAT|=(1<<6);}
#define Led3_On()  {GPBDAT&=(~(1<<7));}
#define Led3_Off()  {GPBDAT|=(1<<7);}
#define Led4_On()  {GPBDAT&=(~(1<<8));}
#define Led4_Off()  {GPBDAT|=(1<<8);}
/****************************************************
* 函数名称:void Led_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:设置GPN5-8为输出功能,初始化4个LED灯灭
*****************************************************/

void Led_Init(void);

#endif

    timer.c文件


#include<s3c2440.h>   //s3c2440.h对S3C2440芯片的一些地址的宏定义
#include"timer.h"

/***************************************************************
* 函数名称:void Timer0_Init(void)
* 参数说明:无
* 全局变量:无
* 返 回 值:无
* 功    能:对于50MHz的PCLK,经过分频获得62.5KHz的定时器0
*     的输入时钟。
***************************************************************/
void Timer0_Init(void)
{
 TCFG0&=~(0xff);  
  //设置第1级分频系数,分频系数为99
 TCFG0|=99;

 TCFG1&=~(0xf);      //设置第2级分频系数,分频系数为8
 TCFG1|=0x02;  //62.5KHz=50MHz/(99+1)/8

 TCNTB0=62500;       //1s中断一次。经过上述分频器得到定时器0的输入时钟频率为62.5kHz,即定时器
                     //每秒钟计数62500次。因此,初始化时,定时器0计数值初始值为62500
      //在这里我们可以看出TCMPBn没有设置,因为咱们用它的默认值0,所以就不需要设置

 TCON|=(1<<1); //开启手动更新位,即当定时器开启后,TCMPB0和TCNTB0中的值会加载到寄存器TCMP0和TCNT0中
 TCON=0x09;     //关闭手动更新位,设置自动加载位,同时开启定时器,这样,TCNT0进行减1计数,当TCNT0中的计
                 //数值减到0时,TCNTB0、TCMPB0中的数据分别会自动加载到TCNT0、TCMP0中并进行新一轮的减1计数
}

     timer.h文件

#ifndef __TIMER_H__
#define __TIMER_H__

/***************************************************************
* 函数名称:void Timer0_Init(void)
* 参数说明:无
* 全局变量:无
* 返 回 值:无
* 功    能:对于50MHz的PCLK,经过分频获得62.5KHz的定时器0
*     的输入时钟。
***************************************************************/

void Timer0_Init(void);

#endif

 

    interrupt.c文件

#include<s3c2440.h>
#include"interrupt.h"


/****************************************************
* 函数名称:void Timer0_Interrupt_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:将定时器0中断屏蔽位设为无效
*****************************************************/

void Timer0_Interrupt_Init(void)

 INTMSK&=~(1<<10);   //将定时器0中断屏蔽位设为无效,这样当
                                     //定时器0发生中断时,中断请求信号可以

}                                    //顺利到达CPU

    interrupt.h文件

#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__


/****************************************************
* 函数名称:void Timer0_Interrupt_Init(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:将定时器0中断屏蔽位设为无效
*****************************************************/

void Timer0_Interrupt_Init(void);

#endif

 

     isrservice.c文件

#include<s3c2440.h>
#include"isrservice.h"

extern unsigned int flag; //声明外部变量flag,该变量是在main.c文件中定义的
                                      //当1s到来时,中断响应函数将该变量值取反,在主
                                     //程序中通过检测该变量的值来实现不同的操作

/****************************************************
* 函数名称:void __irq IRQ_Handler(void) 
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:定时器0中断服务函数,必须加__irq
*****************************************************/

void __irq IRQ_Handler(void) //注意这个函数名字要和S3C2440.s处的跳转标号相同   
{
 flag=!flag;   //1s时间到,flag值取反
 SRCPND|=1<<10; //清除中断标志位
 INTPND|=1<<10;

}

       isrservice.h文件

#ifndef __ISRSERVICE_H__
#define __ISRSERVICE_H__

/****************************************************
* 函数名称:void __irq IRQ_Handler(void)
* 全局变量:无
* 参数说明:无
* 返 回 值;无
* 功    能:定时器0中断服务函数,必须加__irq
*****************************************************/

void __irq IRQ_Handler(void);

#endif

   千万要记得下载到nor flash中啊,如果不会,请看博客:

    http://blog.csdn.net/mybelief321/article/details/8954788