PIC单片机-定时器的应用

2019-04-15 12:12发布

一、利用定时器Timer0的定时功能,设计一个倒计时,显示在数码管上。

#include #define uint8 unsigned char #define uint16 unsigned int #define SCK_595 RA5 #define RCK_595 RE0 #define SER_595 RC0 __CONFIG(WDTDIS & LVPDIS & HS & PWRTDIS & BORDIS);//设置配置位 //WDTDIS:disable watchdog timer 看门狗禁止 //LVPDIS:low voltage programming disabled 低电压编程禁止 //HS:high speed crystal/resonator 4M以上晶振选择HS高速 //PWRTDIS:disable power up timer //BORDIS:disable brown out reset /*************************定义全局变量******************************************/ uint8 Time_Value; uint16 count; const uint8 disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//0~9共阳数码管段码表 /************************声明函数***********************************************/ void DelayUS(uint8 delay); void LED_Display(uint8 chosebit,uint8 wdata); void HC595_Init(void); void HC595_Write_Byte(uint8 data); /******************************************************************************* * 函 数 名: DelayUS(uint8 delay) * 函数功能: 微秒延时 for 20MHZ * 入口参数: delay * 返 回: 无 *******************************************************************************/ void DelayUS(uint8 delay) { while(--delay); } /****************************************************************************** * 函 数 名: HC595_Init(void) * 函数功能: 74HC595初始化 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void HC595_Init(void) { ADCON1 = 0x8E; TRISA5 = 0; TRISE0 = 0; TRISC0 = 0; } /****************************************************************************** * 函 数 名: HC595_Write_Byte(uint8 data) * 函数功能: 74HC595写8位数据 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void HC595_Write_Byte(uint8 data) { uint8 i; for(i=0;i<8;i++) { if(data&0x80) { SER_595 = 1; } else { SER_595 = 0; } SCK_595 = 0; data <<= 1;;; SCK_595 = 1; } RCK_595 = 0; ;; RCK_595 = 1; } /******************************************************************************* * 函 数 名: LED_Display(uint8 chosebit,uint8 wdata) * 函数功能: 单个数码管显示 * 入口参数: chosebit选择字位,wdata字型 * 返 回: 无 *******************************************************************************/ void LED_Display(uint8 chosebit,uint8 wdata) { if((chosebit<0) || (chosebit>4)) return; ADCON1 = 0x86; //10000110 PORTA口设置为数字IO口 TRISA &= 0x00; TRISE &= 0xEF; //配置PORTD为普通IO口,对PORTD的操作务必加上这句 TRISD = 0x00; //数据线配置为输出 PORTA = (PORTA & 0xE3) | ((chosebit+3) << 2); //RA2:RA3:RA4:011 选通第一位 100选通第二位 101选通第三位 110选通第四位 PORTD = disp[wdata]; //送显示数字的断码 DelayUS(100); //延时 PORTD = 0xFF; //关闭显示 } /****************************************************************************** * 函 数 名: main(void) * 函数功能: 利用定时器0进行倒计时 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void main(void) { HC595_Init(); //74HC595初始化 HC595_Write_Byte(0x00); //写0x00数据,关掉LED点阵显示 OPTION = 0x00; //设置定时器0为定时器,2分频 TMR0 = 0x05; //定时器0 (255-5)*2*200ns = 100us T0IF = 0; //清中断标志 T0IE = 1; //开定时器0中断 PEIE = 1; //开外设中断 GIE = 1; //开总中断 Time_Value = 99; while(1) { LED_Display(3,Time_Value%10); //显示个位数 LED_Display(2,Time_Value/10); //显示十位数 } } /****************************************************************************** * 函 数 名: interrupt Time0(void) * 函数功能: 中断处理程序 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void interrupt Time0(void) { GIE = 0; //关总中断 if(T0IF) //定时器0计数溢出 { T0IF = 0; //清中断标志 count++; //计数器加1 if(count >= 10000) //计数器到10000,即1s { count = 0; if(Time_Value == 0) { Time_Value = 100; } Time_Value--; //时间减1 } TMR0 = 0x05; } GIE = 1; //开总中断 }

二、利用定时器Timer1的定时功能,设计一个倒计时,显示在数码管上。

/******************************************************************************* * 跳线接法:断开P14短接帽 * 功能描述: 使用中断函数利用定时器1的定时功能,设计一个倒计时,显示在数码管上 *******************************************************************************/ #include #define uint8 unsigned char #define uint16 unsigned int #define SCK_595 RA5 #define RCK_595 RE0 #define SER_595 RC0 __CONFIG(FOSC_HS &WDTE_OFF &BOREN_OFF &PWRTE_OFF &LVP_OFF); //设置配置位 //WDTE_OFF:disable watchdog timer 看门狗禁止 //LVP_OFF:low voltage programming disabled 低电压编程禁止 //FOSC_HS:high speed crystal/resonator 4M以上晶振选择HS高速 //PWRTDIS:disable power up timer //BOREN_OFF:disable brown out reset /*************************定义全局变量******************************************/ uint8 Time_Value; uint16 count; const uint8 disp[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //0~9共阳数码管段码表 /************************声明函数***********************************************/ void DelayUS(uint8 delay); void LED_Display(uint8 chosebit, uint8 wdata); void HC595_Init(void); void HC595_Write_Byte(uint8 data); void TIMER1_Init(void); /******************************************************************************* * 函 数 名: DelayUS(uint8 delay) * 函数功能: 微秒延时 for 20MHZ * 入口参数: delay * 返 回: 无 *******************************************************************************/ void DelayUS(uint8 delay) { while(--delay); } /****************************************************************************** * 函 数 名: HC595_Init(void) * 函数功能: 74HC595初始化 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void HC595_Init(void) { ADCON1 = 0x8E; TRISA5 = 0; TRISE0 = 0; TRISC0 = 0; } /****************************************************************************** * 函 数 名: HC595_Write_Byte(uint8 data) * 函数功能: 74HC595写8位数据 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void HC595_Write_Byte(uint8 data) { uint8 i; for(i = 0; i < 8; i++) { if(data & 0x80) { SER_595 = 1; } else { SER_595 = 0; } SCK_595 = 0; data <<= 1;;; SCK_595 = 1; } RCK_595 = 0; ;; RCK_595 = 1; } /******************************************************************************* * 函 数 名: LED_Display(uint8 chosebit,uint8 wdata) * 函数功能: 单个数码管显示 * 入口参数: chosebit选择字位,wdata字型 * 返 回: 无 *******************************************************************************/ void LED_Display(uint8 chosebit, uint8 wdata) { if((chosebit < 0) || (chosebit > 4)) return; ADCON1 = 0x86; //10000110 PORTA口设置为数字IO口 TRISA &= 0x00; TRISE &= 0xEF; //配置PORTD为普通IO口,对PORTD的操作务必加上这句 TRISD = 0x00; //数据线配置为输出 PORTA = (PORTA & 0xE3) | ((chosebit + 3) << 2); //RA2:RA3:RA4:011 选通第一位 100选通第二位 101选通第三位 110选通第四位 PORTD = disp[wdata]; //送显示数字的断码 DelayUS(100); //延时 PORTD = 0xFF; //关闭显示 } /******************************************************************************* * 函 数 名: void TIMER1_Init(void) * 函数功能: TIMER1溢出中断初始化 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void TIMER1_Init(void) { T1CON = 0x01; //开TIMER1 TMR1H = 0xFC; /*置初值,TMR1每1ms中断一次。因为写入TMR1后接着的两个周期不能增量, 中断需要3个周期的响应时间,以及C语言自动进行现场保护要消耗周期,取修正值15,所以只需 要定时1000-15=985us,初值=65535-985=0xFC27*/ TMR1L = 0x27; TMR1IF = 0; //清定时器1中断标志 TMR1IE = 1; //开定时器1中断 PEIE = 1; //开外设中断 GIE = 1; //开总中断 Time_Value = 99; } /****************************************************************************** * 函 数 名: main(void) * 函数功能: 利用定时器0进行倒计时 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void main(void) { HC595_Init(); //74HC595初始化 HC595_Write_Byte(0x00); //写0x00数据,关掉LED点阵显示 TIMER1_Init(); //定时器1初始化 while(1) { LED_Display(3, Time_Value % 10); //显示个位数 LED_Display(2, Time_Value / 10); //显示十位数 } } /****************************************************************************** * 函 数 名: interrupt Time0(void) * 函数功能: 中断处理程序 * 入口参数: 无 * 返 回: 无 *******************************************************************************/ void interrupt Time1(void) { GIE = 0; //关总中断 if(TMR1IF) //定时器1计数溢出 { TMR1IF = 0; //清中断标志 count++; //计数器加1 if(count >= 1000) //计数器到1000,即1s { count = 0; if(Time_Value == 0) { Time_Value = 100; } Time_Value--; //时间减1 } TMR1H = 0xFC; TMR1L = 0x27; } GIE = 1; //开总中断 }