📄 jianpan.c
字号:
//加减计数器
//载入头文件---------------------------------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
//-------------------------------------------------------------------------------------------------
//公共数据定义------------------------------------------------------------------------------------
unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
unsigned char dis_buf[4]; // 显示数据缓冲区
unsigned char dis_index; //扫描输出数码管偏移指针
unsigned char dis_digit=0xfe; //位选通信号,dis_digit=0xfe时从P2.0开始扫描
unsigned char RAN_n=0; //列计数变量
unsigned char count=0; //计数
//-------------------------------------------------------------------------------------------------
//函数声明-----------------------------------------------------------------------------------------
void delayms(unsigned char ms); //延时子程序
void update_disbuf(unsigned char count); //更新数据区子程序
unsigned char scan_key(); //输入编码子程序
unsigned char keboard(); //键盘输入健值编码子程序
unsigned char proc_key(unsigned char key_s); //输入计数子程序
//------------------------------------------------------------------------------------------------
//键盘扫描管脚定义--------------------------------------------------------------------------------
sbit LIN4 = P1^7; //1脚扫描键盘第四行
sbit LIN3 = P1^6; //2脚扫描键盘第三行
sbit LIN2 = P1^5; //3脚扫描键盘第二行
sbit LIN1 = P1^4; //4脚扫描键盘第一行
sbit RAN4 = P1^3; //5脚扫描键盘第四列
sbit RAN3 = P1^2; //6脚扫描键盘第三列
sbit RAN2 = P1^1; //7脚扫描键盘第二列
sbit RAN1 = P1^0; //8脚扫描键盘第一列
//------------------------------------------------------------------------------------------------
//主程序-----------------------------------------------------------------------------------------
main()
{
unsigned char key_s; //当前健值变量
unsigned char no_key=0x00; //没有键按下常量标记
P0 = 0xff; //初始化P0口,输出高电平使数码管关闭(即熄灭)
P2 = 0xff; //初始化P2口,输出高电平使输出扫描停止
RAN1=0x1; //初始化P1^0,输出高电平使第一列扫描停止
RAN2=0x1; //初始化P1^1,输出高电平使第二列扫描停止
RAN3=0x1; //初始化P1^2,输出高电平使第三列扫描停止
RAN4=0x1; //初始化P1^3,输出高电平使第四列扫描停止
TMOD = 0x51; // 定时器0工作模式1, 16位定时方式
dis_digit = 0xfe; //初始显示P20口数码管
dis_index = 0; //初始显示0
IE = 0x82; // 使能timer0中断
TR0 = 1;
//初始化显示缓冲区------------------------------------
dis_buf[0] = 0xc0&0x7f; //0xc0是'0'的显示代码
dis_buf[1] = 0xc0; //0xc0是'0'的显示代码
dis_buf[2] = 0xff; //关闭数码管3
dis_buf[3] = 0xff; //关闭数码管4
//----------------------------------------------------
while(1)
{
RAN_n=RAN_n&0x03; //4列扫描完后,再重新从第一列开始扫描
switch(RAN_n) //列扫描
{
case 0x0:RAN1=0; break; //第一列
case 0x1:RAN2=0; break; //第二列
case 0x2:RAN3=0; break; //第三列
case 0x3:RAN4=0; break; //第四列
}
key_s = scan_key();
if(key_s != key_v)
{
delayms(100);
key_s = scan_key();
if(key_s != key_v)
{
proc_key(key_s);
}
}
RAN1=RAN2=RAN3=RAN4=0x1;
RAN_n++; //列计数加一
}
}
//------------------------------------------------------------------------------------------------
//函数定义----------------------------------------------------------------------------------------
void delayms(unsigned char ms) // 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
void update_disbuf(unsigned char count) //更新数据区子程序
{
unsigned char quotient; //商数
unsigned char residue; //余数
quotient = count / 10;
residue = count % 10;
dis_buf[0] = dis_code[quotient]&0x7f;
dis_buf[1] = dis_code[residue];
}
unsigned char scan_key() //输入编码子程序
{
unsigned char key,key_s;
key=keboard();
if(key==0x0d)
{
key_s=0x02;
}
else if(key==0x0f)
{
key_s=0x01;
}
else
{
key_s=0x00;
}
return key_s;
}
unsigned char proc_key(unsigned char key_v) //输入计数子程序
{
if(count<99&&count>0)
{
if((key_v & 0x01) == 0)
{
count=count-1;
}
else if((key_v & 0x02) == 0)
{
count=count+1;
}
}
else if(count==0)
{
if((key_v & 0x01) == 0)
{
count=count;
}
else if((key_v & 0x02) == 0)
{
count=count+1;
}
}
else if(count==99)
{
if((key_v & 0x01) == 0)
{
count=count-1;
}
else if((key_v & 0x02) == 0)
{
count=count;
}
}
else count=0;
return count;
}
unsigned char keboard() //键盘输入健值编码子程序
{
unsigned char key; //变量声明
if(LIN1==0||LIN2==0||LIN3==0||LIN4==0) //是否有按键按下
{
if(LIN1==0)
key=RAN_n+1; //计算返回码
else if(LIN2==0)
key=RAN_n+5;
else if(LIN3==0)
key=RAN_n+9;
else
key=RAN_n+13;
}
else key=0; //没有按键按下
return key; //返回按键码
}
//-------------------------------------------------------------------------------------------------
//定时器0中断服务程序, 用于数码管的动态扫描
void timer0() interrupt 1
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
// 选通P2.0口数码管
// dis_buf --- 显于缓冲区基地址
{
TH0 = 0xFC;
TL0 = 0x17;
P2 = 0xff; // 先关闭所有数码管
P0 = dis_buf[dis_index]; // 显示代码传送到P0口
P2 = dis_digit; //
dis_digit = _crol_(dis_digit,1); // 位选通值右移(P20<-P27), 下次中断时选通下一位数码管
dis_index++; //
dis_index &= 0x01; // 2个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
if(dis_index == 0)
{
update_disbuf(count);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -