需求:使用4位共阴极段码表及共阳极数码管,通过外部中断方式,实现两个按钮分配加1、减1功能。
今天我就来讲解一下这道题:
目录
1.代码
1.1定义头文件
1.2定义延时函数(毫秒)
1.3定义主函数
1.4定义0~15共阴极数码管字符码
1.5定义中断
1.5.1IE寄存器(中断允许控制)(interrupt enable)
1.5.2IP寄存器
1.5.3定时控制寄存器TCON ( Timer control register )
1.5.4真-定义中断
1.5.5定义中断子程序
1.6计算与显示
1.6.1定义全局变量
1.6.2计算
1.6.3显示
1.7完整代码
2.仿真
3.效果
1.代码
1.1定义头文件
首先我们定义单片机头文件<reg51.h>
#include<reg51.h>//单片机头文件
1.2定义延时函数(毫秒)
我们在定义一下延时函数DelayMs(后面会用到),这里我们用两个for循环与一个传参来实现。
第二个for循环循环120次得出1毫秒。
第一个for循环与传参ms完成我们需要延时的毫秒。
void DelayMs (const int ms)//延时函数(毫秒)
{
int i;
for(i = 0;i < ms;i++)//循环几亳秒
{
int j;
for(j = 0;j < 120;j++);
}
}
1.3定义主函数
因为是单片机,所以不需要返回值,所以用void main来定义主函数。
void main()//主函数
{
}
1.4定义0~15共阴极数码管字符码
因为这个共极数码管字符码不需要做改变,所以我们用const把他锁上。
int mian()
{
//定义0~15共阴极数码管字符码
const unsigned char 1ed[] = {0X3F, 0X06, 0X5B, 0X4E, 0X66, 0X6D, 0X7D,0X7,0X7E,0X6E, 0X77, 0X7C, 0X39, 0X5E, 0X79, 0X71};
}
1.5定义中断
首先我们先了解亿点点中断知识。
1.5.1IE寄存器(中断允许控制)(interrupt enable)
EXO(IE.0) | 外部中断0允许位;(interrupt controller of external interrupt) |
ETO(IE.1) | 定时/计数器TO中断允许位 (interrupt controller of Timer0 interrupt) |
EX1(IE.2) | 外部中断0允许位 |
ET1(IE.3) | 定时/计数器T1中断允许位 |
ES (IE.4) | 串行口中断允许位; (interrupt controller of serial port) |
EA(IE.7) | CPU 中断允许(总允许)位(global all interrupt ) |
1.5.2IP寄存器
PXO (IP.0) | 外部中断0优先级设定位 |
PTO (IP.1) | 定时/计数器TO优先级设定位 |
PX1 (IP.2) | 外部中断0优先级设定位 |
PT1 (IP.3) | 定时/计数器T1优先级设定位 |
PS (IP.4) | 串行口优先级设定位 |
PT2 (IP.5) | 定时/计数器T2优先级设定位(80C52 的T2) |
1.5.3定时控制寄存器TCON ( Timer control register )
ITO (TCON.0) | 外部中断0触发方式控制(interruput-0 type control bit ) |
ITO=0 | 为电平触发方式 |
IT0=1 | 为边沿触发方式(下降沿有效) |
IEO (TCON.1) | 外部中断0中断请求标志位(external interrupt-0 flag) |
IT1 (TCON.2) | 外部中断1触发方式控制位 |
IE1 (TCON.3) | 外部中断1中断请求标志位 |
TRO (TCON.4) | 定时/计数器TO运行控制位( timer0 run control bit) |
TR1 (TCON.6) | 定时/计数器T1运行控制位 |
TFO(TCON.5) | 定时/计数器TO溢出中断请求标志位 |
TF1 (TCON.7) | 定时/计数器T1溢出中断请求标志位( timer1 overflow flag ) |
OK,我们这中断知识了解这亿点点就可够了。
1.5.4真-定义中断
int mian()
{
//定义中断
IE=0xFF;
ITO=1;//T1为边沿触发方式(下降沿有效)
IT1=1;//T2为边沿触发方式(下降沿有效)
}
1.5.5定义中断子程序
当然我们给配合两个子程序来用。
interrupt 0 |
指明是外部中断0 |
interrupt 1 | 指明是定时器中断0 |
interrupt 2 | 指明是外部中断1 |
interrupt 3 | 指明是定时器中断1 |
interrupt 4 | 指明是串行口中断 |
void Add() interrupt 0//T2加
{
if (shu<9999)//防止数值溢出————出现野指针
{
shu++;//加
}
}
void Sub() interrupt 2//T1减
{
if (shu>0)//防止数值过小————出现野指针
{
shu--;//减
}
}
1.6计算与显示
1.6.1定义全局变量
先定义一个全局变量shu。
int shu = 1;//数(全局变量)
1.6.2计算
因为要重复计算,所以我们计算把放到循环里。
int main()
{
while (1)//死循环
{
//定义每一位
int qian = shu/1000,//千
bai = shu%1000/100,//百
shi = shu%100/10,//十
ge= shu%10;//个
}
}
1.6.3显示
因为要重复显示,所以我们再把显示放进去,并延时1毫秒(利用人的视觉误差)。
int main()
{
while (1)//死循环
{
//亮个位
P3=~ (0x10<<0);
P2 = 1ed[ge];
DelayMs (1) ;//延时1亳秒
//亮十位
P3=~ (0x10<<1);
P2 = led[shi];
DelayMs(1);//延时1亳秒
//亮百位
P3=~ (0x10<<2);
P2 = 1ed[bai];
DelayMs(1);//延时1亳秒
//亮千位
P3=~(0x10<<3) ;
P2 = led[qian];
DelayMs (1) ;//延时1亳秒
}
}
1.7完整代码
#include<reg51.h>//单片机头文件(全局变量)
int shu = 1;//数
void DelayMs (const int ms)//延时函数-毫秒
{
int i;
for(i = 0;i < ms;i++)//循环几亳秒
{
int j;
for(j = 0;j < 120;j++);
}
}
void main()//主函数
{
//定义0~15共阴极数码管字符码
const unsigned char 1ed[] = {0X3F, 0X06, 0X5B, 0X4E, 0X66, 0X6D, 0X7D,0X7,0X7E,0X6E, 0X77, 0X7C, 0X39, 0X5E, 0X79, 0X71};
//定义中断
IE=0xFF;
ITO=1;//T1为零终止一次
IT1=1;//T2为零终止一次
while (1)//死循环
{
//定义每一位
int qian = shu/1000,//千
bai = shu%1000/100,//百
shi = shu%100/10,//十
ge= shu%10;//个
//亮个位
P3=~ (0x10<<0);
P2 = 1ed[ge];
DelayMs (1) ;//延时1亳秒
//亮十位
P3=~ (0x10<<1);
P2 = led[shi];
DelayMs(1);//延时1亳秒
//亮百位
P3=~ (0x10<<2);
P2 = 1ed[bai];
DelayMs(1);//延时1亳秒
//亮千位
P3=~(0x10<<3) ;
P2 = led[qian];
DelayMs (1) ;//延时1亳秒
}
}
void Add() interrupt 0//T2加
{
if (shu<9999)//防止数值溢出————出现野指针
{
shu++;//加
}
}
void Sub() interrupt 2//T1减
{
if (shu>0)//防止数值过小————出现野指针
{
shu--;//减
}
}
2.仿真
因为这次程序非常简单,所以只需要4个元件:
Component Mode中的7SEG-MPX4-CC(共阳极数码管)与AT89C51(单片机)与BUTTON(按钮)。
Terminals Mode中的GROUND(负极)。
布局如下:
3.效果
制作不易,你懂得。
文章来源:https://www.toymoban.com/news/detail-433291.html
按钮加减计数器文章来源地址https://www.toymoban.com/news/detail-433291.html
到了这里,关于题解:按钮加减计数器设计(单片机C51)(外部中断)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!