飞思卡尔智能车招新
内容:定时器数码管矩阵键盘
定时器
什么是定时器
- 定时器或计数器实质是加一计数器(16位)(其输入脉冲有两个来源,一是由系统时钟振荡器输出脉冲经过十二分频后送来;另外是T0或T1引脚输入的外部脉冲源,每来一个脉冲计数器加1,当加到计数器全为1时,在输入一个脉冲就可使计数器回零,计数器的溢出是的TCON寄存器中TF0或TF1置1,向CPU发出中断请求,如果定时或计数器工作于定时模式,则表示定时时间到了,如果是计数则表示计数值已满)由高八位和低八位两个寄存器组成。
- 看着感觉听不懂吧,那就看下图,手把手教你定时器的原理:
1.定时器工作原理: 2.定时器和计数频率的关系
定时器中断配置+1s点亮1次LED灯
寄存器配置
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|
TMOD | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 | | T1 | T1 | T1 | T1 | T0 | T0 | T0 | T0 |
GATE:门控位 GATE=0,定时器/计数器是否计数,仅由控制位TR1或TR0控制。 GATE=1,定时器/计数器是否计数,由外中断引脚(P3.2或者P3.3)上的电平与TRx共同控制。 C/T:计数模式(Count)和定时器(Timer)模式选择位 C/T = 0,为定时器工作模式,对系统时钟12分频后的内部脉冲进行计数 C/T = 1,为计数器工作模式,计数器对外部输入引脚T0(p3.4)或者T1(p3.5)的外部脉冲(负跳变)计数 M1,M0:工作方式选择位 M1,M0的4中编码,对应于4中工作方式的选择
M1 M0 | 工作方式 |
---|
0 0 | 方式0,为13位定时器/计数器 | 0 1 | 方式1,为16位定时器/计数器 | 1 0 | 方式2,为8位的常数自动重新装载的定时器/计数器 | 1 1 | 方式3,仅适用于T0,此时T0分成2个8位计数器,T1停止计数 |
TMOD代码配置:GATE=0 - 由TR0控制是否计数。C/T=0 - 定时模式。M0,M1=0,1 - 方式1 16位 定时器
TMOD=0X01;
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|
TCON | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF1:定时器/计数器T1的溢出中断请求标志位。 当启动T1后,T1从初值开始加1计数,当计数溢出时,由硬件自动置TF1为“1”,向CPU申请中断。CPU响应TF1中断时,TF1标志1由硬件自动清零,TF1也可由软件清零。 TF0:定时器/计数器T0的溢出中断请求标志位。功能与TF1相同 TR1、TR0:计数运行控制位 TR1、TR0=1时,启动定时器/计数器的必要条件 TR1、TR0=0时,停止定时器/计数器 低四位不用管,那四个是外部中断的
代码配置:配置TR0或者TR1=0或者1即可,这里我们用定时器0,TR0=1使能定时器,让定时器启动计数.
TR0=1;
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|
IE | EA | – | – | ES | ET1 | EX1 | ET0 | EX0 |
EA:中断允许总开关控制位。置1所有中断请求被允许,置零所有中断请求被屏蔽。 ES:串行口中断允许控制位。置1允许串行口中断,置0禁止 ETI:定时器/计数器T1的溢出中断允许控制位。置1允许,置0禁止 ET0:定时器/计数器T0的溢出中断允许控制位。置1允许,置0禁止 EX1:外部中断1中断允许位。置1允许,置0禁止 EX0:外部中断0中断允许位。置1允许,置0禁止 我们只关注EA位和ET0/ET1位
定时器中断代码配置:配置EA=1或者ET1=1或者ET0=1,这里我们用定时器0,EA=1,ET0=1使能总中断,使能定时器中断.
EA=1;
ET0=1;
TF0=0;
初值代码配置:因为我们想要中断1ms响应一次,由于计一个数为1us,则计1000个数就是1ms,所以配置初值为65536-1000=64536(十六进制为FC18) 这里我们配置定时器1初值为F81C
TH0=0XFC;
TL0=0X18;
至此:定时器中断配置完毕,接下来开始总体配置代码 定时器和定时器中断初始化 -中断1ms发生一次
void Timer0Init(void)
{
TMOD=0X01;
TH0=0XFC;
TL0=0X18;
TF0 = 0;
TR0=1;
ET0=1;
EA=1;
}
定时器代码
main.c
#include <REGX52.H>
#include <Timer0.h>
#include <Delay.h>
extern int a;
void Dispaly(int num)
{
int i;
int s=num;
for(i=0;i<2;i++)
{
P2_0=1;
P2_1=1;
P1=0X00;
switch (i)
{
case 0:P2_0=0,P2_1=1;break;
case 1:P2_1=0,P2_0=1;break;
}
switch(s%10)
{
case 0:P1=0X3F;break;
case 1:P1=0X06;break;
case 2:P1=0X5b;break;
case 3:P1=0X4f;break;
case 4:P1=0X66;break;
case 5:P1=0X6d;break;
case 6:P1=0X7d;break;
case 7:P1=0X07;break;
case 8:P1=0X7f;break;
case 9:P1=0X6f;break;
}
Delay(10);
s=s/10;
}
}
void main()
{
P3_0=1;
Timer0Init();
while(1)
{
}
}
Timer0.c
#include <REGX52.H>
#include <Timer0.h>
void Timer0Init(void)
{
TMOD=0X01;
TH0=0XFC;
TL0=0X18;
TF0 = 0;
TR0=1;
ET0=1;
EA=1;
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18;
TH0 = 0xFC;
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
P3_0=!P3_0;
}
}
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init(void);
#endif
Delay.c
#include <Delay.h>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
数码管代码
void Dispaly(int num)
{
int i;
int s=num;
for(i=0;i<2;i++)
{
P2_0=1;
P2_1=1;
P1=0X00;
switch (i)
{
case 0:P2_0=0,P2_1=1;break;
case 1:P2_1=0,P2_0=1;break;
}
switch(s%10)
{
case 0:P1=0X3F;break;
case 1:P1=0X06;break;
case 2:P1=0X5b;break;
case 3:P1=0X4f;break;
case 4:P1=0X66;break;
case 5:P1=0X6d;break;
case 6:P1=0X7d;break;
case 7:P1=0X07;break;
case 8:P1=0X7f;break;
case 9:P1=0X6f;break;
}
Delay(5);
s=s/10;
}
}
- 假如显示159
- 显示第一个数个位:s%10=9;
- 显示第二个数十位:s/10%10=9;
- 显示第三个数十位:s/10/10%10=1;
矩阵键盘代码
#include <REGX52.H>
#include <Delay.h>
int MatrixKey()
{
int KeyNumber=0;
P1=0xFF;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=2;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=3;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=4;}
P1=0xFF;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=5;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=7;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=8;}
P1=0xFF;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=9;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=10;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=12;}
P1=0xFF;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=13;}
if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=14;}
if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=15;}
if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
void main()
{
while(1)
{
switch( MatrixKey())
{
case 1:P2=0X06;break;
case 2:P2=0X5b;break;
case 3:P2=0X4f;break;
case 4:P2=0X66;break;
case 5:P2=0X6d;break;
case 6:P2=0X7d;break;
case 7:P2=0X07;break;
case 8:P2=0X7f;break;
case 9:P2=0X6f;break;
}
}
}
|