问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

51单片机C语言程序4个独立按键实现对数码管数字显示的加减清零等

发布网友 发布时间:2022-04-28 21:11

我来回答

3个回答

热心网友 时间:2023-09-15 23:53

#include <reg52.h>
//P0是数码管。P1是LED.P2是按键
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2; 
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;

#define uchar unsigned char
#define ulint unsigned long
#define Frequency 10//定时器中断时间 = f*T
#define Time 1//一个周期1ms
#define TubeNumber 6//数码管个数
#define KeyLine 4//矩阵按键行数 
#define KeyColumn 4//矩阵按键列数 
//数码管真值表
uchar code LED_Number[]={0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//uchar code LED_Alphabet[]={0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0x8C,0xC1,0x91,0x9C};
/*0~9
                              A~F   (b      、d为小写)        H    L    P    U   y    o  */
uchar  LED_Buff[TubeNumber]={0xff,0xff,0xff,0xff,0xff,0xff};
/*数码管显示缓冲区,0xff确保初始时都不亮.
不可写成uchar code LED_Buff[]。code定义变量写入room,不可修改*/
// 矩阵按键编号到标准盘码的映射表 
uchar code KeyCodeMap[4][4] = { 
( 0x31, 0x32, 0x33, 0x26 ), // 数字键 1、数字键 2、数字键 3、向上键
( 0x34, 0x35, 0x36, 0x25 ), // 数字键 4、数字键 5、数字键 6、向左键 
( 0x37, 0x38, 0x39, 0x28 ), // 数字键 7、数字键 8、数字键 9、向下键 
( 0x30, 0x1B, 0x0D, 0x27 )};  // 数字键 0、ESC 键  、回车键  、向右键
uchar StaFlag[KeyLine][KeyColumn] ={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按键是否稳定标志 
void StartTime0();
void TubeDisplay(ulint sec);
ulint pow(x,y);
void TubeScan();
void KeyAction(uchar keycode);
void KeyDriver();
void KeyScan();
void main ()
{
P1 = 0x08;//使能U3,选择数码管。
StartTime0();
while(1)KeyDriver();
}
//定时器0启动函数
void StartTime0()
{
EA = 1;
ET0 = 1;
TMOD = 0x01;
TH0 = (65536 - Time * 100) / 256;
TL0 = (65536 - Time * 100) % 256;
PT0 = 1;
/*定时器0优先中断控制位。
IP 这个寄存器的每一位,表示对应中断的抢占优先级,每一位的复值都是0,当我们把某一位设置为1的时候,这一位优先级就比其它位的优先级高了。
比如我们设置了 PT0位为1后, 当单片机在主循环或其他中断程序执行时,一旦TO发生中断,作为更高优先级,程序马上执行T0.若在T0程序执行时,
其他中断程序发生中断,仍执行TO直到T0中断结束后再执行其他程序。 
*/  
}
//中断服务函数 
void To_time0()interrupt 1 using 0
{
static uchar cnt;//记录TO中断次数
//static ulint sec;//记录经过秒速
//判断是否溢出 
if (TF0 == 1)
{
TF0 = 0;
TH0 = (65536 - Time * 100) / 256;
TL0 = (65536 - Time * 100) % 256;
}

if (cnt >= Frequency)
{
cnt = 0;
//sec++;
//Tube_Display(sec);
TubeScan();
KeyScan();
}
}
//数码管显示函数
void TubeDisplay(ulint nom)
{
uchar m = 2;//小数部分位数
uchar i;//传输索引
//秒速达到上限清零
if (nom > pow(10,TubeNumber - m))nom = 0;
//分别传输小数部分和整数部分 
for(i=0; i<m; i++)
LED_Buff[i] = LED_Number[nom/pow(10,i)%10];
for(i=0; i<(TubeNumber - m); i++)
LED_Buff[i+m] = LED_Number[nom/pow(10,i)%10];
//点亮小数点
LED_Buff[m] &= 0x7f;
}
//平方运算函数 
ulint pow(x,y)//x为底,为幂
{
ulint p,i = 1;
//平方运算 
for(i=1; i<=y; i++)
p*=x;
//输出结果 
return p;
}
//数码管动态函数
void TubeScan()
{
static uchar i = 0;//动态扫描索引
//关闭所有段选位,数码管消隐
P0 = 0xff;
//for (i=0; i < Tube_number; i++)
P1 = (P1 & 0xf8) | i;//位选索引赋值到P1口低3位
P0 = LED_Buff[i];//缓冲区中的索引位置数据传输到P0口
if (++i >= TubeNumber)i=0;//索引递增循环,遍历整个缓冲区

//矩阵按键动作函数
void KeyAction(uchar keycode)
{
static ulint result;
ulint nom = 0;
//输入数字0~9 
if ((keycode >= 0x30) && (keycode <= 39))
{
nom = (nom*10) + (keycode - 0x30);//十进制整体左移,新数进入各位
TubeDisplay(nom); 
}
//输入方向键 
if ((keycode >= 0x25) && (keycode <= 28))
switch (keycode)
{
case 0x26:result += nom; nom = 0; TubeDisplay(result);
case 0x28:result -= nom; nom = 0; TubeDisplay(result);
case 0x25:result = 1; result *= nom; nom = 0; TubeDisplay(result);
case 0x27:result = 1; result /= nom; nom = 0; TubeDisplay(result);
}
else if (keycode == 0x0d)TubeDisplay(result);//输入回车键,输出最终结果 
else if (keycode == 0x1b)//输入ESC键,清零 
{
nom = result = 0;
TubeDisplay(nom);
}
}
//矩阵按键驱动函数 
void KeyDriver()
{
uchar l,c; 
static uchar backup[KeyLine][KeyColumn] = {(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按键值备份,保存前一次值 
for(l=0; l<KeyLine; l++)
{
for(c=0; c<KeyColumn; c++)
{
if (backup[l][c] != StaFlag[l][c])
{//检测按键动作 
if (backup[l][c] == 1)//按键按下时执行
KeyAction(KeyCodeMap[l][c]);//调用动作函数 
backup[l][c] = StaFlag[l][c];//刷新前一次备份值
}
}
}

//矩阵按键扫描函数
void KeyScan()
{
uchar l = 0;//矩阵按键扫描输出索引
uchar c = 0;//矩阵按键扫描列索引
uchar keybuff [KeyLine][KeyColumn] = {(0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff),
      (0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff)};//矩阵按键扫描缓冲区
 //将一行的四个按键移入缓冲区 
 for(l=0; l<KeyColumn; l++)
 keybuff [l][c] = ((0xfe | (P2 >> (4 + l)) & 0x01));
//按键消抖 
for(l=0; l <KeyLine; l++)
{
if((keybuff [l][c] & 0x0f) == 0x00)//连续4次扫描都为0,判断4*4ms内都是按下状态,可认为按键已稳定按下
StaFlag[l][c] = 0;
else if ((keybuff [l][c] & 0x0f) == 0x0f)//连续4次扫描都为1,判断4*4ms内都是弹起状态,可认为按键已稳定弹起
 StaFlag[l][c] = 1;
}
for(c=0; c <KeyColumn; c++)
{
switch (c) // 根据索引,释放当前输出脚 拉低下次的根据索引

case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; 
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; 
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; 
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; 
default: break;
 }
}
}

热心网友 时间:2023-09-15 23:54

图片失真,看不清楚

热心网友 时间:2023-09-15 23:54

需要带做吗追问嗯嗯

追答需要私信聊

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
抖音弹幕怎么关掉?怎么关闭抖音弹幕? 惠普LaserJet P3005D是否支持B5纸的双面打印? word打印出图片总是缺一部分怎么办-word打印图片不完整怎么解决_百度... 理想one哪里产的车辆? 抚州抚州ONE在哪里? one地址在哪里? 如何在图片上写字(如何在图片上添加文字) 网商贷为什么钱没到账 高级经济师职称怎么评 高级经济师需要评审吗 华为畅享10plus OTG怎么打开? OPPOr9s应用加密怎么取消? 用51单片机C语言编写程序实现6位共阴极数码管循环显示0123456789ABCDEF,六个数码管是连续不同的六个数? oppor9s手机应用加密怎么取消 C语言 单片机数码管动态显示 为什么会显示成这样,请高手帮忙,谢谢 华为畅享10怎么OTg怎么打开? oppor9s取消了应用加密,为什么进微信QQ还是要密码呢?怎么取消密码 如何用C语言实现数码管显示数字12345和HELLO 华为畅享10s的OTG功能在哪里打? 单片机实现4位一体数码管显示0000—FFFF的16进制(C语言编程)怎么编程? 怎样打开华为畅亨10s的OTG功能? 单片机C语言编程关于数码管动态显示的问题 华为畅享10怎么用OTG? 请问单片机中要怎么用按键控制数码管显示的模式。。用C语言编程。。 用C语言编程,使51单片机数码管从0显示到60 华为畅享10怎么设置otg? 51单片机C语言数码管动态显示 单片机如何用c语言使数码管显示3 c语言如何编程点亮一个数码管显示数字 51单片机C语言程序中如何确定数码管显示内容 激光打印机可加粉和不可加粉的区别 打印机硒鼓灌了粉,对打印机有什么损害么? hp打印机—12A易加粉硒鼓怎么加粉 连供硒鼓和易加粉硒鼓比有什么具体的不同? ps代做一张海报多少钱? ps中用一张图“替代”(包括这张图的样式)图层中一张图怎么做 求一高手代做PS图片,qq744954528 PS logo 代做 求助达人 求ps高手代做海报一张。有加分&gt; &lt;很急! 求ps大神代做两页杂志,有报酬 求人代做PS,,,QQ1479850875 本人会简单的cad,ps,su,想兼职代画图~ 如何用ps把图片中的字去掉?求大神代做,857442376,在线等! 建行往招行用网银跨行转账要几天到账? 建设银行转到招商银行最快几小时到? 帮忙代做一份酒店大堂的3Dmax文件,带ps完成图。没有水印哦~~~ 建行转招行跨行转账要几天?如果没有到账能不能查询到这笔待入账的钱 建行网银跨行转账到招行要多久到账 建设银行转账到招商银行跨行转的。下午三点转的显示二十四小时到账。具体时间是什么时候到 建行异地转款到招行一般需要多久