程序功能:
上电后,数码管显示"00"
第一次按下KEY1后,数码管以1秒加1的速度开始计时
第二次按下KEY1后,计时停止
第三次按下KEY1后,数码管上显示的时间归零
管脚与数码管的连接方式:
PA0~PA7 == "HGFEDCBA"
PA8 == SHIWEI
PA9 == GEWEI
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "DrvTimer.h"
#define GEWEI_ON GPIOA->DOUT&=~(1<<9)
#define GEWEI_OFF GPIOA->DOUT|=(1<<9)
#define SHIWEI_ON GPIOA->DOUT&=~(1<<8)
#define SHIWEI_OFF GPIOA->DOUT|=(1<<8)
uint8_t Table[11]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff};
uint8_t u8DispCount = 0;
uint8_t u8Cnt5ms;
uint8_t u8SecTime = 0;
uint8_t u8DispData1;
uint8_t u8DispData2;
uint8_t u8StartStop = 0;
//**************************************************************************
// 延时子函数(12MHZ,1MS)
//**************************************************************************
void delay_ms(uint32_t count)
{
uint32_t i,j;
for(i=count;i>0;i--)
for(j=2395;j>0;j--);
}
//**************************************************************************
// 回调函数
//**************************************************************************
void Timer0_Callback (void)
{
GPIOA->DOUT |= 0xff; //熄灭码
u8DispCount++;
if(u8DispCount > 1)u8DispCount = 0;
switch(u8DispCount)
{
case 0x0: //个位码扫描
GPIOA->DOUT &= Table[u8DispData2];
GEWEI_ON;
SHIWEI_OFF;
break;
case 0x1: //十位码扫描
GPIOA->DOUT &= Table[u8DispData1];
SHIWEI_ON;
GEWEI_OFF;
break;
default:break;
}
u8Cnt5ms++;
if((u8Cnt5ms >= 200)&&(u8StartStop == 1))
{
u8SecTime++;u8Cnt5ms = 0;
}
if(u8SecTime > 60)u8SecTime = 0;
}
//**************************************************************************
// 系统初始化函数
//**************************************************************************
void Init_System(void)
{
UNLOCKREG(x);
DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1); //设定时钟为外部12M
DrvSYS_Delay(5000);
LOCKREG(x);
}
//**************************************************************************
// Timer0初始化函数
//**************************************************************************
void Init_Timer0(void)
{
DrvTIMER_Init();
DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0);
DrvTIMER_Open(E_TMR0,200,E_PERIODIC_MODE);
DrvTIMER_SetTimerEvent(E_TMR0,1,(TIMER_CALLBACK) Timer0_Callback,0);
DrvTIMER_EnableInt(E_TMR0); //允许定时器T0中断
DrvTIMER_Start(E_TMR0); //开始启动定时器T0
}
//**************************************************************************
// 显示设置函数
//**************************************************************************
void DispSet(void)
{
u8DispData1 = u8SecTime/10;
u8DispData2 = u8SecTime%10;
}
//**************************************************************************
// 按键函数
//**************************************************************************
void KeyProgram(void)
{
static uint8_t u8KeyCount;
if(DrvGPIO_GetBit(E_GPB, 15) == 1)return;
delay_ms(10);
if(DrvGPIO_GetBit(E_GPB, 15) == 1)return;
while(DrvGPIO_GetBit(E_GPB, 15) == 0)
{
delay_ms(10);
DispSet();
}
switch(u8KeyCount)
{
case 0:
u8Cnt5ms = 0;
u8StartStop = 1; //起动计时
u8KeyCount = 1; //转换按键状态
break;
case 1:
u8StartStop = 0; //停止计时
u8KeyCount = 2;
break;
case 2:
u8SecTime = 0; //计时值清零
u8KeyCount = 0;
break;
default:break;
}
}
//**************************************************************************
// 主函数
//**************************************************************************
int main(void)
{
Init_System();
Init_Timer0();
DrvGPIO_Open( E_GPB, 15, E_IO_INPUT ); //按键端口设置为输入
while(1)
{
KeyProgram(); //按键函数
DispSet(); //显示设置函数
}
}
LED2KEY.rar
(804.53 KB)
|