Ⅰ 单片机秒表课程设计,急求!!!!
原理图如下,
程序如下:
;=================================================
;寄存器分配定义
;=================================================
LED_BUF EQU 50H ;显示数据首址
COUNTER_INT EQU 3BH ;中断计数器
SECOND EQU 3DH ;秒单元
;=================================================
;常数定义
;=================================================
CN_COUNT_INT EQU 100 ;10ms * 100 = 1S
SET_MODEL EQU 0FFH ;完全译码模式
SET_BRIGHT EQU 04H ;占空比为15/32;显示亮度;
SET_LIMIT EQU 01H ;2位显示方式;
SET_NORMAL EQU 01H ;测试模式
SET_START EQU 01H ;进入启动工作方式?
;=================================================
;管脚分配定义
;=================================================
m7219_DIN BIT P3.0
m7219_LOAD BIT P3.1
m7219_CLK BIT P3.2
KEYSTART BIT P1.0
KEYRESET BIT P1.1
;============================================
;模拟主程序
;===========================================
org 0000h
ajmp main
ORG 000BH
LJMP Timer0Interrupt
org 0030h
main:
mov sp,#70h
lcall Init_M7219
lcall InitTimer0
; MOV SECOND,#95H ;TEST
Loop:
CALL disp
key_reset:
SETB KEYRESET
JB KEYRESET,key_start
; DELAY
NOP
NOP
NOP
JB KEYRESET,key_start
JNB KEYRESET,$
CLR TR0
MOV A,#0
MOV SECOND,A
MOV led_buf,A
MOV LED_BUF+1,A
JMP key_SCAN_END
key_start:
SETB KEYSTART
JB KEYSTART,key_SCAN_END
; DELAY
NOP
NOP
NOP
JB KEYSTART,key_SCAN_END
JNB KEYSTART,$
SETB TR0
key_SCAN_END:
JMP loop
;===========================================
InitTimer0:;10ms一次中断
MOV TMOD,#01H
MOV TH0,#0D8H
MOV TL0,#0F0H
SETB EA
SETB ET0
RET
;===========================================
Timer0Interrupt:
PUSH DPH
PUSH DPL
PUSH ACC
MOV TH0,#0D8H
MOV TL0,#0F0H
;========================
INC COUNTER_INT
MOV A,COUNTER_INT ;10ms 计数值加1
CJNE A,#CN_COUNT_INT,Timer0Interrupt_EXIT
MOV COUNTER_INT,#0
MOV A,SECOND
CJNE A,#99H,Timer0Int_sec
CLR TR0;关闭计时
JMP Timer0Interrupt_EXIT
Timer0Int_sec:
ADD A,#01 ;秒加1
DA A
MOV SECOND,A
SWAP A
ANL A,#0fH
MOV led_buf,A
MOV A,SECOND
ANL A,#0FH
MOV LED_BUF+1,A
;========================
Timer0Interrupt_EXIT:
POP ACC
POP DPL
POP DPH
RETI
;====================================================
; function:Init_M7219 ;初始化max719
; input: ------------
; output: ----------
; usage: a,b
;====================================================
Init_M7219: ;初始化Max7219
MOV a,#0bh ;设置扫描界限
MOV b,#set_limit ;设置位数
lcall w_7219
MOV a,#09h ;设置译码模式
MOV b,#set_model ;00h非译码模式;ffh为BCD译码模式
lcall w_7219
MOV a,#0ah ;设置亮度
MOV b,#set_bright ;15/32亮度
lcall w_7219
MOV a,#0fh ;设置工作方式
MOV b,#set_normal ;正常工作方式
lcall w_7219
MOV a,#0ch ;进入启动工作方式
MOV b,#set_start
lcall w_7219
RET
;===================================================
; function:disp ;显示子程序
; input: r0
; output: -----------
; usage: r0,r3,r4,a,b
;===================================================
disp:
MOV r0,#led_buf
MOV r4,#01h
MOV r3,#set_limit
INC r3
disp1:
MOV a,@r0
MOV b,a
MOV a,r4
lcall w_7219
INC r0
INC r4
djnz r3,disp1
RET
;===================================================
; function:w_7219 ;显示驱动程序;
; input: a ;传送7219的地址
; b ;传送7219的数据
; output:-------------
; usage: a,r2
;====================================================
w_7219:
CLR M7219_clk
CLR M7219_din
CLR M7219_load ;置load=0
lcall sd_7219 ;传送7219的地址
MOV a,b
lcall sd_7219 ;传送数据
setb M7219_load ;数据装载
CLR M7219_din
RET
;=================================================
; function:sd_7219 ;向7219传送数据或地址子程序
; input: a
; output: max7219
; usage: a, r2
;==================================================
sd_7219: ;向7219送地址或数据
MOV r2,#08h
c_sd:
CLR C
CLR M7219_clk
RLC a
MOV M7219_din,c ;准备数据
NOP
setb M7219_clk ;上升沿将数据传入
NOP
NOP
CLR M7219_clk
djnz r2,c_sd
RET
Ⅱ 利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开始每1秒钟加1。
共阳数码管中断程序:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
uint num,a;
uchar ,shi,ge;
void init();
void delay(uint);
void display(uchar,ucharshi,ucharge);
uint fb();
uint fs();
uint fg();
void main()
{
init();
while(1)
{
display(fb(),fs(),fg());
}
}
void init()
{
num=0;
a=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void display(uchar,ucharshi,ucharge)
{
P1=0xfd;
P0=table[];
delay(1);
P1=0xfb;
P0=table[shi];
delay(1);
P1=0xf7;
P0=table[ge];
delay(1);
}
void timeoff() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65526-50000)%256;
a++;
if(a%20==0)
{
num++;
if(num==999)
{
num=0;
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uint fb()
{
=num/100;
return ;
}
uint fs()
{
shi=num%100/10;
return shi;
}
uint fg()
{
ge =num%100%10;
return ge;
}
(2)单片机课程设计计时器扩展阅读
2个可编程定时/计数器·5个中断源,2个优先级(52有6个)
一个全双工串行通信口
外部数据存储器寻址空间为64kB
外部程序存储器寻址空间为64kB
逻辑操作位寻址功能·双列直插40PinDIP封装
单一+5V电源供电
CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器;
RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据;
ROM:用以存放程序、一些原始数据和表格;
I/O口:四个8位并行I/O口,既可用作输入,也可用作输出
T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式;
五个中断源的中断控制系统;
一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;
片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最佳振荡频率为6M—12M。
参考资料来源:网络-51单片机
Ⅲ 30秒倒计时器课程设计
【摘 要】篮球比赛30秒钟规则规定:进攻球队在场上控球时必须在30秒钟内投篮出手(NBA比赛为24秒,全美大学体育联合会比赛中为35秒),因此在比赛时裁判既要看比赛又要看秒表计时,而本文介绍的30秒倒计时器可以解决此问题。
【关键词】AT89C51单片机、30秒倒计时器、LED
30秒倒计时器的设计和制作有很多方法,本文介绍的30秒倒计时器以AT89C51单片机作为控制单元,采用两个数码管显示时间,用三个按键分别控制计时器的计时开始、复位和暂停。倒计时器初始状态显示“30”,当裁判员按下计时键,30秒倒计时开始,当计时器时间减到0时,计时器发出声光报警,提示裁判计时时间已到。
一、电路设计
30秒倒计时器的电路主要由电源电路、单片机最小系统、按键输入、显示驱动电路、报警电路组成,30秒倒计时器控制电路如图1所示。
图1 30秒倒计时器电路原理图
1、按键输入
“30秒倒计时器”采用了三个按键来完成计数器的启动计数、复位、暂停/继续计数等功能。
(1)K1键:启动按钮(P3.2)。
按下K1键,计数器倒计时开始,数码管显示数字从30开始每秒递减计数,当递减到到零时,报警电路发出声、光报警信号。当计数器处于暂停状态时按下K1键将回到计时状态。
(2)K2键:复位按钮(P3.3)。
按下K2键,不管计数器工作于什么状态,计数器立即复位到预置值 “30” ,在报警状态时按下K2键还可取消报警。
(3)K3键:暂停/计时切换按钮(P3.4)。
当计数器处于计时状态时按下该键计数器暂停计时,数码管显示数字保持不变;当计数器处于暂停状态按下该键计数器将回到计时状态;初始状态时该键无效。
2、显示驱动电路
“30秒倒计时器”用两个共阳数码管来显示时间,数码管显示方式为动态显示。显示驱动电路中,数码管的段码引脚通过470欧的电阻接到单片机的P1口,两个片选引脚各通过一个9012连接到正5V电源,由P3.0和P3.1控制。
4、报警电路
计时时间减到0,显示数码管显示“00”时,发光二极管D1由P3.5控制发出光报警,同时蜂鸣器由P3.7控制发出声报警。
二、软件编程思路
1、全局变量
“30秒倒计时器”动作流程主要受三个全局变量控制。首先是bit变量“act”,当“act”为“1”时倒计时开始,为“0”时倒计时停止,“act”初值为“0”,可以由按钮操作将其置“1”或清“0”。第二个全局变量是char变量“time”,存放倒计时的时间,当倒计时时间为0时,发出声光报警。变量“time”的初值为30,定时中断服务程序在“act”为1时,每1s对其进行减1操作,减到0时保持为0,按下“复位键”可将“time”复位为30。第三个全局变量是int变量“t”,记录响应定时中断0的次数。根据初始化定义,定时器0以方式1工作,每1ms发出一次中断请求。控制程序只开放了定时器0中断,因此不会有比定时器0中断更高级的中断被允许,所以每次请求都会立刻被响应。响应后在中断服务程序中将全局变量“t”加1记录响应中断次数,每响应1000次即为1秒钟。变量“t”初值为0,在中断服务程序中加1,当“t”为2000时由中断服务程序清0。在按键驱动程序中,按下启动键、复位键、暂停/启动键时将“t”清0,目的是从0ms开始计时。
2、控制流程
主程序主要用来检测全局变量“time”当“time”为0时发出“声光报警”。按键驱动、显示驱动和“time”操作都在定时器0中断服务程序中进行。其控制流程如图2所示。
图2 控制流程图
三、软件程序设计
1、数码管驱动程序
到计时器的两个数码管以动态显示的方式显示计时时间“time”(全局变量),LED1显示“time”的十位,LED2显示“time”的个位。
(1)定义段码数据口和片选信号
根据实际电路,在C51中定义段码的数据口为P1,两个片选信号为P3.0和P3.1。定义如下:
#define an P1
sbit wei1=P3^0;
sbit wei2=P3^1;
(2)定义字形码
LED显示数字0~9以及全灭的字形码表格放在数组zixing[]中。字形码是固定的表格,定义时加上关键字“code” 表示该表格存放在程序存储器中。
unsigned char code zixing[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff
};
(3)定义数码管LED1和LED2的显示变量
为了增加驱动程序的可移植性,笔者为数码管LED1和LED2定义了显示变量。显示变量就是本驱动程序的对外接口,外部程序只要改变显示变量的值就可改变数码管显示的数值。定义方式如下:
unsigned char led_str[2]={10,10};
led_str[0]直接对应数码管LED1, led_str[1]直接对应数码管LED2。本项目中由专门的子程序将全局变量time计算拆分成led_str[0]和led_str[1]。
void js()
{
led_str[1]=time/10%10;
led_str[0]=time%10;
}
(4)数码管驱动程序
数码管驱动程序“void chushi(char i)”在定时中断服务程序中被调用执行。根据初始化程序的定义,定时中断服务程序每1ms被执行一次。定时中断服务程序中运用全局变量“t”记录进入该服务程序的次数,“t”计满2000由定时中断服务程序清零。
数码管驱动程序的参数“char i”是用来确定当前点亮的是LED1还是LED2,当参数为“0”时点亮LED1,参数为“1”时点亮LED2。如果我们希望偶数次进入定时中断服务程序时点亮LED1,奇数次进入定时中断服务程序时点亮LED2,我们可以用程序调用语句“chushi(t%2);”轻松实现。
进入数码管驱动程序后首先调用子函数js(),计算当前的led_str[0]和led_str[1]。接下来将两个数码管全部熄灭以防止余晖的出现。最后点亮需要点亮的数码管并送出字型码。驱动程序代码如下:
void chushi(char i)
{
js(); //计算显示变量
an=0xff; //去余晖
wei1=i; wei2=!i; //确定片选
an=zixing[led_str[i]]; //送字型码
}
2、按键驱动程序
按键驱动程序分为按键识别和按键功能执行两部分。按键功能执行可在按键按下时或按键抬起后执行,文中将其设计在按键抬起后执行。
(1)定义按键I/O地址
根据实际电路,三个按键(启动键、复位键、暂停/启动键)分别接在P3口的P3.2,P3.3和P3.4三个引脚上。为了取键值方便还将P3口定义为“iokey”,程序中可作定义如下:
#define iokey P3
sbit key1=P3^2;
sbit key2=P3^3;
sbit key3=P3^4;
(2)按键驱动流程
按键识别的通用流程为:I/O口写“1”→判断有无键按下→延时去抖→确定键值→等待按键抬起→执行按键功能。按键驱动程序中定义了两个静态变量“ts” 和“kv”,分别用来延时去抖和存放键值。
(3)延时去抖
静态变量“ts”用来延时去抖。按键驱动程序在定时中断服务程序中每1ms被执行一遍,每检测到有键按下“ts”加1,检测到无键按下“ts”清0。按键连续按下20ms,则连续20次执行按键驱动程序时都检测到有键按下,此时静态变量“ts”累加到20,可确认按键按下有效。
为防止按键一直按着不放而使“ts”累加到溢出,确认有键按下后可使“ts”的值保持为20,或大于20的某一个值如21。
(4)取键值
确认有键按下后即可通过读取按键的I/O口状态来得到键值。为读取P3.2、P3.3和P3.4引脚状态,屏蔽P3口其他引脚的影响,可将读取后的数值按位或上11100011B(0xE3)再送给静态变量“kv”。
静态变量“kv”存放按键的键值,无键按下或按键抬起后kv的值为0。按下启动键key1时kv=11111011B(0xFB),按下复位键key2时kv=11110111B(0xF7),按下暂停/启动键key3时kv=11101111B(0xEF)。
(5)执行按键功能
按键抬起后第一次执行按键驱动程序时,静态变量“kv”任保持着按键按下时最后得到的键值,以该键值作为参数调用按键执行程序“actkey(kv);”即可执行按键功能。调用后kv值立刻清0,确保按一次键执行一次按键功能。驱动程序代码如下:
void key()
{
static unsigned char kv=0;
static unsigned char ts=0;
key1=1;key2=1;key3=1;
if(!(key1&key2&key3))
{
ts++;
if(ts>=20)ts=20; //有键按下
if(ts==20)
kv=iokey|0xe3; //取键值
}
else
{ //无键按下或按键已抬起
actkey(kv);
ts=0;
kv=0;
}
}
函数actkey(kv)用来根据键值“kv”执行相应操作。当“kv”等于0xFB时代表启动键key1按下,函数actkey(kv)将全局变量act赋值为“1”。当“kv”等于0xF7时代表复位键key2按下,函数actkey(kv)将全局变量“time”复位为“30”。当“kv”等于0xEF时代表暂停/启动键按下,函数actkey(kv)将全局变量act取反。每按一个按钮都有将全局变量“t”清0的操作,目的是每当复位、或启动计时时,进入定时中断的次数都从0开始计算,否则会出现第1秒计时不准确的现象。程序代码如下:
void actkey(unsigned char k)
{
switch(k)
{
case 0xfb:act=1;t=0;break;
case 0xf7:time=30;t=0; break;
case 0xef:act=~act;t=0; break;
}
}
四、结束语
本文在编程过程中以面向对象的编程思路封装了两个LED数码管和三个独立按键。当其驱动程序在定时中断服务程序中被调用,编程者只要操作其接口:数组“led_str[2]”和函数“actkey(unsigned char k)”,无需直接对硬件进行编程即可改变功能,增强了软件的通用性和可移植性。
Ⅳ 我在做单片机设计,需要一个特殊的计时器,请高手指点!
常用的是DS1302时钟芯片,电脑和手机用的就是它,但是没有“当达到设定的时间时向单片机发送信号”这个功能,估计市场上还没有。
Ⅳ 利用单片机设计59秒计时器
共阳共阴只是你在选COM端时给其高低电平的问题无关大雅
我给一段PIC单片机的程序让你参考一下,如果你看懂的话应该能做出来了
#include <pic.h>
#include <math.h>
//此程序实现计时秒表功能,时钟显示范围00.00~99.99秒,分辨度:0.01秒
unsigned char s0,s1,s2,s3;
//定义0.01 秒、0.1 秒、1秒、10秒计时器
unsigned char s[4];
unsigned char k ,data ,sreg;
unsigned int i;
const table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
//不带小数点的显示段码表
const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的显示段码表
//TMR0初始化子程序
void tmint()
{
T0CS=0; //TMR0工作于定时器方式
PSA=1; //TMR0不用分频
T0IF=0; //清除TMR0的中断标志
T0IE=1; //TMR0中断允许
}
//spi显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送。与"74HC595,当其
//SCLK从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7; //SDO引脚为输出,SCK引脚为输出
TRISA5=0; //RA5引脚置为输出,输出显示锁存信号
}
//系统其它部分初始化子程序
void initial()
{
TRISB1=0;
TRISB2=0;
TRISB4=1;
TRISB5=1; //设置与键盘有关的各口的输入输出方式
RB1=0;
RB2=0; //建立键盘扫描的初始条件
}
//SPI传输数据子程序
void SPILED(data)
{
SSPBUF=data; //启动发送
do {
;
}while(SSPIF==0);
SSPIF=0;
}
//显示子程序,显示4位数
void dispaly()
{
RA5=0; //准备锁存
for(k=4;k>0;k--)
{
data=s[k-1];
if(k==3) data=table0[data];//第二位需要显示小数点
else data=table[data];
SPILED(data); //发送显示段码
}
for(k=0;k<4;k++)
{
data=0xFF;
SPILED(data); //连续发送4个DARK,使显示好看一些
}
RA5=1; //最后给锁存信号,代表显示任务完成
}
//软件延时子程序
void DELAY()
{
for(i = 3553; --i ;) continue;
}
//键扫描子程序
void KEYSCAN()
{
while(1){
while(1)
{
dispaly(); //调用一次显示子程序
if ((RB5==0)||(RB4==0)) break;
}
DELAY(); //若有键按下,则软件延时
if ((RB5==0)||(RB4==0)) break;//若还有键按下,则终止循环扫描,返回
}
}
//等键松开子程序
void keyrelax()
{
while(1){
dispaly(); //调用一次显示子程序
if ((RB5==1)&&(RB4==1)) break;
} //为防止按键过于灵敏,每次等键松开才返回
}
//系统赋值初始化子程序
void ini()
{
s0=0x00;
s[0]=s0;
s1=0x00;
s[1]=s1;
s2=0x00;
s[2]=s2;
s3=0x00;
s[3]=s3; //s0=s1=s2=s3=0,并放入显示缓冲数组中
sreg=0x00; //tmr0中断次数寄存器清0
}
//中断服务程序
void interrupt clkint(void)
{
TMR0=0X13; //对TMR0写入一个调整值。因为写入TMR0后接着的
//两个周期不能增量,中断需要3个周期的响应时间,
//以及C语言自动进行现场保护要消耗周期
T0IF=0; //清除中断标志
CLRWDT();
sreg=sreg+1; //中断计数器加1
if(sreg==40) //中断次数为40后,才对S0,S1,S2,S3 操作
{
sreg=0;
s0=s0+1;
if(s0==10){
s0=0 ;
s1=s1+1;
if(s1==10){
s1=0 ;
s2=s2+1;
if(s2==10){
s2=0;
s3=s3+1;
if(s3==10) s3=0 ;
}
}
}
}
s[0]=s0;
s[1]=s1;
s[2]=s2;
s[3]=s3;
}
//主程序
main()
{
OPTION=0XFF;
tmint(); //TMR0初始化
SPIINIT(); //spi显示初始化
initial(); //系统其它部分初始化
di(); //总中断禁止
while(1) {
ini(); //系统赋值初始化
KEYSCAN(); //键扫描,直到开始键按下
keyrelax(); //等键松开
ei(); //总中断允许
TMR0=0X08;
KEYSCAN(); //键扫描直到停止键按下,在键扫描时有显示
keyrelax() ; //等键松开
di(); //总中断禁止
KEYSCAN(); //键扫描到清0键按下,在键扫描时有显示
keyrelax() ; //等键松开
}
}
Ⅵ 单片机计时器
//1:用AT89C51单片机的定时/计数器T0产生一秒的
//定时时间,作为秒计数时间,当一秒产生时,秒
//计数加1,秒计数到60时,自动从0开始。单片机
//晶振频率为12MHZ
//由于是刚刚注册,积分没有多少,请大家帮个忙,谢谢!
#include<reg52.h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
uchar
code
table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f};
void
display(uchar
fen,uchar
miao);
uchar
a,fen,miao,shu;
void
delay(uint
z);
void
init();
void
main()
{
init();
while(1)
{
display(fen,miao);
}
}
void
timer0()
interrupt
1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
a++;
if(a==20)
{
a=0;
shu++;
fen=shu/10;
miao=shu%10;
if(shu==60)
shu=0;
}
}
void
init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void
display(uchar
fen,uchar
miao)
{
P1=0xFe;
P2=table[fen];
delay(5);//延时5毫秒
P1=0xFf;
P2=table[miao];
delay(5);//延时5毫秒
}
void
delay(uint
z)
{
uint
x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//P2口接数码管,然后数码管位选通过74HC138来控制
//我可是刚学,弄了好久才弄出来的哦
//要图的话加980100952
//这个软件是调通过了的,也加载到我的实验扳上试过的
Ⅶ 如何用单片机做一个简单的倒计时器
51单片机实现数码管99秒倒计时,其实很简单,就是使用定时器中断来实现。目的就是学习怎样用单片机实现倒计时,从而实现一些延时控制类的东西,99秒只是一个例子,你完全可以做出任意倒计时如10秒倒计时程序。定时器定时时间计算公式:初值X=M(最大计时)-计数值。
初值,换算成十六进制,高位给TH0,低位给TL0,如果用定时器0的话。
M(最大计时)如果是16位的,就是2的16次方,最大定时,65535 微秒,实现1秒定时,可以通过定时10毫秒,然后100次改变一次秒值即可。10*100毫秒=1S
计数值:你要定时多长时间,如果定时1毫秒,就是1000微秒,(单位为微秒),如果定时10毫秒,就是10000(微秒),当然,最大定时被定时器本身位数限制了,最大2的16次方(16位定时计数器),只能定时65.535毫秒。定时1S当然不可能1S定时器中断。
下面为实现99秒倒计时C语言源程序
/*了解定时器,这样的话,就可以做一些基本的实验了,如定时炸弹~~,10秒后打开关闭继电器*/
/*数码管,12M晶振*/
#include <reg52.h>
#define uchar unsigned char
sbit p11=P1^1; //连的是继电器。。
code unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar shiwei;
uchar gewei;
void delay(unsigned int cnt)
{
while(--cnt);
}
void main()
{
TMOD|=0x01; /*定时器0 16位定时器 X=65535-10000(10毫秒)=55535=D8F0(十六进制)定时10ms
*/
TH0=0xd8;
TL0=0xf0;
IE=0x82; //这里是中断优先级控制EA=1(开总中断),ET0=1(定时器0允许中断),这里用定时器0来定时
TR0=1; //开定时器0
while(1)
{
P0=shiwei; //99的十位
P2=0; //99的个位,
delay(300); //动态扫描数码管延时
P0=gewei;
P2=1;
delay(300);
}
}
void tim(void) interrupt 1 using 1 //定时器0中断
{
static uchar second=99,count; //99只是一个数,可以任意改,因为这里只学习怎样实现倒计时
TH0=0xd8; //定时10毫秒
TL0=0xf0;
count++;
if(count==100) //10毫秒定时,10*100=1000(毫秒)=1秒
{
count=0;
second--;
if(second==0)
{
p11=0; //这里让继电器动作,当然动作之后,要复位才能等下次倒定时再动作。
second=99; //回到99再循环来,当然,可以做其他的控制,
}
shiwei=tab[second/10]; //数码管10位
gewei=tab[second%10]; //数码管个位
}
Ⅷ 单片机计时器
#include<reg51.h>
#defineucharunsignedchar
ucharledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
uchartime=0,led0=0,led1=0;
voidt0isr()interrupt1
{
TH0=(65536-50000)/256;//重赋初值
TL0=(65536-50000)%256;
time++;//中断次数加1
if(time>=20)//如果20次中断到
{
time=0;
led1++;//秒个位加1
if(led1>=10)//如果秒个位大于等于10
{
led1=0;
led0++;//秒十位加1
if(led0>5)led0=0;
}
P0=ledtab[led0];//显示十位
P1=ledtab[led1];//显示个位
}
}
voidext0()interrupt0
{
led0=0;外部中断0,清零
led1=0;
}
main()
{
TMOD=0x01;//定时器0方式1
TH0=(65536-50000)/256;//50毫秒中断一次
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EX0=1;
IT0=1;
EA=1;
P0=ledtab[led0];
P1=ledtab[led1];
while(1);
}