一、60s倒计时
具体任务:
设计一个60秒倒计时程序。要求:能够在数码管上显示倒计时,并且在倒计时为0时蜂鸣器鸣叫,按下KEY1时能够重新开始计时。
代码:
#include <reg52.h>
//位定义外部硬件
sbit SegmentG3 = P2^1;
sbit SegmentG4 = P2^0;
sbit BEEP = P1^0;
//特殊功能寄存器定义
sfr ISP_CONTR=0xE7;//STC单片机软复位功能步骤1
//宏定义蜂鸣器开关指令
#define BEEP_ON BEEP = 0;
#define BEEP_OFF BEEP = 1;
//定义显示数字0~9
static unsigned char s_arrNumber[] =
{0x03, 0x9F, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1F, 0x01, 0x09};
//延迟函数
static void DelayNms(int nms)
{
unsigned int i,j;
for(i=0;i<nms;i++)
{
for(j=0;j<123;j++)
{
}
}
}
//中断配置函数
static void InitInterrupt(void)
{
//(用于按下KEY1归零)
IT0 = 1; //外部中断0下降沿触发
EX0 = 1; //外部中断0中断允许
//用于计时器
ET0 = 1; //定时器0中断允许
//总大门
EA = 1; //总中断允许
PX0 = 1; //外部中断0优先级高于定时器0
}
//定时器0配置函数
static void InitTimer0()
{
TMOD = 0x01;//工作模式1
TH0 = 0xFC; //计数初值高8位(1ms溢出累计1000)
TL0 = 0x18; //计数初值高8位
TR0 = 1; //打开定时器0
}
//主函数
int main(void)
{
InitInterrupt();
InitTimer0();
while(1)
{
}
}
//外部中断服务函数
void External0_Handler()interrupt 0
{
ISP_CONTR |=0x20; //STC单片机软复位功能步骤2
}
//定时器0中断服务函数
void Timer0_Handler()interrupt 1
{
static unsigned int s_iCounter;//定义计数变量
static unsigned int i=0; //显示个位i
static unsigned int j=6; //显示十位j
TH0 = 0xFC; //重新设置计数初值高8位
TL0 = 0x18; //重新设置计数初值低8位,1ms后溢出
s_iCounter++; //每进行一次中断,计数变量+1
if(s_iCounter>=100)//计数变量到1000即1000ms=1s
{
s_iCounter = 0;//计数变量置零
//执行任务
i--;
if(-1==i)
{
i=9;
j--;
}
}
P0 = s_arrNumber[i];
SegmentG4 = 0;
DelayNms(5);
SegmentG4 = 1;
P0 = s_arrNumber[j];
SegmentG3 = 0;
DelayNms(5);
SegmentG3 = 1;
while((0==i)&(0==j))
{
BEEP_ON;
}
}
二、按键按下时间测量
具体任务:
能够在数码管上显示KEY1按下的 时间,单位为ms。(任务提示:利用TRO位控制定时器0的运行,当KEY,按下时定时器0开始运行,KEY;弹起时停止,计算其中的时间间隔)
代码:
#include <reg52.h>
//位定义
sbit SegmentG1 = P2^3;
sbit SegmentG2 = P2^2;
sbit SegmentG3 = P2^1;
sbit SegmentG4 = P2^0;
sbit KEY1 = P3^2;
//定义0~9
static unsigned char s_arrNumber[]={0x03, 0x9F, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1F, 0x01, 0x09};
//延时函数
static void DelayNms(int nms)
{
unsigned int i,j;
for(i=0;i<nms;i++)
{
for(j=0;j<123;j++)
{
}
}
}
//中断配置函数
static void InitInterrupt(void)
{
ET0 = 1; //定时器0中断允许
EA = 1; //总中断允许
}
//定时器0配置函数(1ms溢出)(题中要求以ms计,所以直接ms而且不用计数变量累加)
static void InitTimer0()
{
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x18;
TR0 = 1;
}
//主函数
void main()
{
if(1==KEY1)//若没有被按下
{
TR0 = 0; //不启动定时器
}
InitInterrupt();
InitTimer0();
while(1)
{
}
}
//定时器0中断服务函数
void Timer0_Handler()interrupt 1
{
static unsigned int a,b,i,j= 0; //进位符(此处必须要加static,定义静态变量!要不然不对)
TH0 = 0xFC;//重置计数初值
TL0 = 0x18;
i++;
if(10==i)
{
i=0;
j++;
}
else if(10==j)
{
j=0;
b++;
}
else if(10==b)
{
b=0;
a++;
}
while(1==KEY1)
{
P0 = s_arrNumber[i];
SegmentG4 = 0;
DelayNms(5);
SegmentG4 = 1;
P0 = s_arrNumber[j];
SegmentG3 = 0;
DelayNms(5);
SegmentG3 = 1;
P0 = s_arrNumber[b];
SegmentG2 = 0;
DelayNms(5);
SegmentG2 = 1;
P0 = s_arrNumber[a];
SegmentG1 = 0;
DelayNms(5);
SegmentG1 = 1;
}
}