实验五 定时器实验
一、实验目的
1. 理解单片机定时器的工作原理。
2. 掌握定时器溢出中断实现定时的编程方法。
二、实验内容
1. 验证例题
编译下载运行T0秒表例题,查看运行结果。理解程序的编程思想和程序执行过程。
2. 设计程序
参考上述例题的电路和编程思路,自行设计电路,包括数码管、2个按键,完成数码管显示和按键控制数码管数字累加速度。
具体要求如下:
(1)定时器溢出时间为20ms;
(2)上电复位后,数码管显示全0并保持,直到有按键按下;
(3)数码管后一位循环显示0-9;
(4)按下K1键后,数字以每0.8s加1的速度递增,同时在数码管最左侧一位显示“1”;按下K2键后,数字以每1.6s加1的速度递增,同时在数码管最左侧一位显示“2”。
在设计报告中,需进行总体设计思路描述,给出所涉及到的主程序、中断程序、关键功能子函数的流程图和设计代码。描述程序调试结果及出现的问题。
仿真连线
实现代码:
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
uchar shumaguan[10]={0x03,0x9f,0x25,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08};///定义数码管显示数组,分别对应0~9
数码管显示函数
void shownumber(uint a,uint b,uint c,uint d,uint e,uint f)///a~f分别控制数码管的6位
{
uint z;
uint w,h;
DDRB=0xff;///数码管位选
for(w=0;w<59;w++)//延时
{
for(z=0;z<30;z++)/第一位显示
{
PORTC=0x02;
PORTB=shumaguan[a];
}
for(z=0;z<55;z++)///
{
PORTC=0x04;
PORTB=shumaguan[b];
}
for(z=0;z<55;z++)///
{
PORTC=0x08;
PORTB=shumaguan[c];
}
for(z=0;z<55;z++)///
{
PORTC=0x10;
PORTB=shumaguan[d];
}
for(z=0;z<55;z++)///
{
PORTC=0x20;
PORTB=shumaguan[e];
}
for(z=0;z<29;z++)///最后一位显示的数字
{
PORTC=0x40;
PORTB=shumaguan[f];
}
}
}
///--------定时器初始化函数------------
void Timer0_init(void)
{
TCCR0=0x05;
TCNT0=52;
TIFR=0x01;
TIMSK=0x01;
}
uchar sec=0;
uchar x=19;///定时器溢出循环次数变量
uint q,p,n,smg;///数码管显示的变量
void main(void)
{
DDRC=0xff;///C口数码管位选
DDRD &=0x00;///PD输入
PORTD |=0xff;//PD上拉输入
DDRA=0x01;
PORTA=0x00;
Timer0_init();
SREG |=0x80;//打开全局中断
shownumber(0,0,0,0,0,0);//数码管全显示0
smg=0;
while(1)
{
if(PIND==0xfe)///K1按下
{
q=1;///最左侧一位显示1
x=25;//每0.8s加一
}
else if(PIND==0xfd)///K2按下
{
q=2;///最左侧一位显示2
x=50;///每1.6秒加一
}
shownumber(q,0,0,0,0,smg);
}
}
#pragma interrupt_handler Timer0_TOV_ISR:iv_TIM0_OVF
void Timer0_TOV_ISR(void)
{
TCNT0=52;
if(sec<x)
{
sec++;
}
else
{
sec=0;
if(x==19)///判断没有按键按下时,不改变数码管全零显示
{}
else///有按键按下,数码管最右侧显示0~9
{
if(smg<9)
{
smg++;
}
else
{
smg=0;
}
}
}
}
课堂实验作业原题目要求数码管最右侧显示0~99,这里稍作改动;原题目要求数字递增时间为0.5s和1s,这里稍作改动。
运行截图:
有任何问题私信