51单片机程序(c语言版),按键矩阵控制数码管显示数字。十位数显示不全

作者&投稿:龚贴 (若有异议请与网页底部的电邮联系)
51单片机C语言程序4个独立按键实现对数码管数字显示的加减清零等~

#include //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= TubeNumber)i=0;//索引递增循环,遍历整个缓冲区} //矩阵按键动作函数void KeyAction(uchar keycode){static ulint result;ulint nom = 0;//输入数字0~9 if ((keycode >= 0x30) && (keycode = 0x25) && (keycode > (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; }}}

#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e
} ;//共阳极数码管0 为亮
sbit wei=P1^0;
void delay(uchar t)//毫秒延
{
uint i,j;
for(i=0; i<t; i++)
for(j=0; j<110; j++);
}
void display(uchar d)
{
P1=0x00;
wei=1; //第一个数码管点亮
P0=table[d];

}

void main()
{
uchar v,temp;
uchar key_l,key_h;// 定义列和行
uchar key;
while(1)
{
P2=0xf0;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0) //检测到有按键按下
{
delay(10);//消抖
if(temp!=0xf0)//再次确认一下有否真的有按下
{
temp=P2;//把这次的检测值作为真值
key_l=temp&0xf0;
P2=key_l|0x0f;//让低四位置1 1110 1111
temp=P2;//赶紧读取P口值
key_h=temp&0x0f;//得到行值 0000 1110
key=key_l+key_h;//1110 0000
//+ 0000 1110
//ee 1110 1110
}

switch(key)
{
case 0xee:display(0);break;
case 0xde:display(1);break;
case 0xbe:display(2);break;
case 0x7e:display(3);break;
case 0xed:display(4);break;
case 0xdd:display(5);break;
case 0xbd:display(6);break;
case 0x7d:display(7);break;
case 0xeb:display(8);break;
case 0xdb:display(9);break;
case 0xbb:display(10);break;
case 0x7b:display(11);break;
case 0xe7:display(12);break;
case 0xd7:display(13);break;
case 0xb7:display(14);break;
case 0x77:display(15);break;
}
}

}
}
把行列扫描的值相加 key=key_l+key_h; 我也是调了很长时间 你要把原理彻底搞明白了 呵呵

没有下拉电阻,如果没有下拉电阻,没有被按键时,引脚是高组态,这个时候不能用来读取数据,必须将用来读的引脚加上下拉电阻拉到地,这样才能读数据,所以你需要4个下拉电阻在键盘上。。。。 记住引脚悬空,又没有上拉或下拉电阻的时候不要读数据,这时候读的东西是不会出现你想要的结果,可能1,可能0 ,有上拉无输入时,是1,下拉式0,你这里面希望是无输入时引脚为0,所以用下拉。。。。

#include<reg51.h> // 试试
unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void led_display(unsigned char num);
unsigned char key_scan();
unsigned char temp,key;
sbit led1=P2^0;
sbit led2=P2^1;
void main()
{
unsigned char led_key;
P1=0;
while(1)
{
led_key=key_scan();
led_display(key);
}
}
void led_display(unsigned char num)
{
unsigned char ten,single;
int delay;
ten=num/10;
single=num%10;
delay=100;
for(delay=200;delay>0;delay--)
{
P0=led[ten];
led1=0;
led1=1;
P0=led[single];
led2=0;
led2=1;
}
}
/////////////////////////////////////////
unsigned char key_scan(void)
{
P1=0xfe;
temp=P1&0xf0;
if(temp!=0xf0)
{
switch(temp)
{
case 0xe0: key=1;
break;
case 0xd0: key=2;
break;
case 0xb0: key=3;
break;
case 0x70: key=4;
}
return key;
}
P1=0xfd;
temp=P1&0xf0;
if(temp!=0xf0)
{
switch(temp)
{
case 0xe0: key=5;
break;
case 0xd0: key=6;
break;
case 0xb0: key=7;
break;
case 0x70: key=8;
}
return key;
}
P1=0xfb;
temp=P1&0xf0;
if(temp!=0xf0)
{
switch(temp)
{
case 0xe0: key=9;
break;
case 0xd0: key=10;
break;
case 0xb0: key=11;
break;
case 0x70: key=12;
}
return key;
}
P1=0xf7;
temp=P1&0xf0;
if(temp!=0xf0)
{
switch(temp)
{
case 0xe0: key=13;
break;
case 0xd0: key=14;
break;
case 0xb0: key=15;
break;
case 0x70: key=16;
}
return key;
}
}


单片机c语言程序
while(!TF0); \/\/等到定时器溢出 这句话的意思是等待TF==1的发生。我们看条件,当TF为0的时候!TF0==1,那么while的条件为真,要一直执行循环,但是while后面没有跟循环,只有一个分号,所以程序死在这里,就是一直等待,等到什么时候呢?直到TF==1,也就是!TF0==0,跳出循环。接下来我们首...

一段单片机C语言,求大神逐句翻译一下。
P1=0xff; \/\/port1全部置位 P0=0xff; \/\/port0全部置位 y=0; \/\/y赋0 while(1)

C语言与单片机C语言的区别 急求
2、C是一门语言,由对应平台的编译器编译成对应平台汇编的程序,各平台的汇编不一样,当然编译器也不一样DOS上的TC2TC3 WINDOWS上的VC8051的C51都有自已的编译器。具体区别是由编译器决的,只能参考对应的编译手册,即使同种平台不同的编译器对C的扩展也有不同。3、单片机c语言编程是基于C语言的单片机...

单片机C语言编程
使用两个定时器或一个定时器中使用两个计数都能满足你的要求。建议使用一个定时器和一个计数器即可,如计数器为i,则 if(i%测温定时==0)温度测量();if(i%步进电机定时==0)步进电机控制();注:此时要求两个控制模块的定时步长是一致,比如都是1ms ...

一个关于单片机控制步进电机的C语言程序 想请高人帮我把每一步都注释...
C语言程序源代码 include <REGX51.H> \/\/ 51寄存器定义 include "intrins.h"define control P1 \/\/P1_0:A相,P1_1:B相,P1_2:C相,P1_3:D相 define discode P0 \/\/显示代码控制端口 define uchar unsigned char \/\/定义无符号型变量 define uint unsigned int sbit en_dm=P3^0; \/\/...

编写简单的单片机c语言程序 1、指定数组找最大值 2、排序
就是一般的排序算法,与查找算法一样,这个的都不会吗 float a[3],max=0;for(i=0;i<=2;i++){ printf("Please enter the mark:");scanf("%f",&a[i]);if(max<a[i]){ max=a[i];maxnum=i+1;} } printf("the number of the highest is d\\n",maxnum);for(i=0;i<=2;i...

用c语言编写程序,用于c51单片机四位共阴数码管显示,显示分秒的计时器...
\/ 用proteus做的时钟 可以显示年月日时分秒 可调整时间 有图 \/ include<reg52.h> defineuchar unsigned char define uint unsigned int define timh 0xee define timl 0x00 sbit K1=P1^0;sbit K2=P1^1;sbit K3=P1^2;sbit K4=P1^3;sbit K5=P1^4;sbit K6=P1^5;sbit poit=P0^7;uint...

单片机C51编程(C语言):1到100的求和显示,在数码管里显示出来.
void convert();void display();void delay();\/\/共阴:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F code unsigned char Led[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};uchar num,sw,gw;void main(){ num=0;while(1){ co...

用单片机输入控制输出 C语言程序
程序实现很简单,建议你参考一下独立键盘原理:void keyboard(){ if(key1==1){ delay(8);if(key1==0){ keyP21=~keyP21;while(!key1);} } if(key2==1){ delay(8);if(key2==0){ keyP22=~keyP22;while(!key2);} } if(key3==1){ delay(8);if(key3==0){ keyP23=~keyP...

高分求一个单片机电子琴c语言程序
(3. 把“单片机系统”区域中的P1.7\/RD端口用导线连接到“四路拨动开关”区域中的K1端口上; 4. 程序设计内容 (1. 信号产生的方法 500Hz信号周期为2ms,信号电平为每1ms变反1次,1KHz的信号周期为1ms,信号电平每500us变反1次; 5. 程序框图 图4.6.2 6. 汇编源程序...

湖滨区13084617272: 51单片机程序(c语言版),按键矩阵控制数码管显示数字.十位数显示不全 -
顾戚天仲: /*----------------------------------------------- 名称:单个共阳数码管动态显示变化数字 内容:通过循环检测p1口按键输入值,然后用数码管输出, 没有按键按下时原值不变 ------------------------------------------------*/#include //包含头文件,一般情况不需要改动...

湖滨区13084617272: 51单片机4*3矩阵键盘6位密码锁c语言程序 -
顾戚天仲: #include<stdio.h> #include<reg51.h> #define uchar unsigned charuchar key; int i=0; char b[4]={'0','0','0','0'};//输入的密码放这里和初始的比较来判断是否密码正确 void keyscan() //扫描按键是否按下 { uchar temp; P3=0xfe; //扫描第一行 temp=...

湖滨区13084617272: 51单片机c语音独立按键程序 -
顾戚天仲: 一个独立按键程序,没有必要写成子程序,更没有必要写得这么复杂.其实很简单的.如下程序:#include typedef unsigned int u16; sbit k1=P1^0; sbit led=P1^1; void delay(u16 i) { while(i--); } void main() { led=0; while(1) { if(k1==0) { delay(700); if(k1==0) { led=~led; } while(k1==0); //等待按键释放 } } }

湖滨区13084617272: 怎么用C语言实现51单片机矩阵键盘按一个键后其他键才有用? -
顾戚天仲: 按键消抖动程序估计有问题,给你看个消抖动的例子程序 while(key1==0) { delayms(10); if(key1==0) { num=1; }}

湖滨区13084617272: 51单片机C语言编程两个按键加减显示0 - 99的加减,求程序,自己编的有警告,不知道哪里错了 -
顾戚天仲: # include <reg52.h> # define uint unsigned int # define uchar unsigned char sbit K2 = P3^7; //按键 sbit K3 = P3^6; sbit W1 = P3^2; //位选 sbit W2 = P3^1; uint num, shi, ge; uchar code table[]={0xc0,0xf9,0xa4,0xb0, // 数码管 共阳0x99,0x92,0x...

湖滨区13084617272: 51单片机,用c语言,如何用矩阵键盘为一个变量char a赋值?已设计出一个函数,使得每按一个矩阵 -
顾戚天仲: /***4*4矩阵按键构架——火柴天堂作品-20110921***//***源程序默认硬件环境:52单片机,12MHz晶振,P1口 4*4矩阵键盘,详细布局如下***//* 默认矩阵布局,按键扫描方式1使用 P0 P1 P2 P3 │ │ │ │ P4─┼──┼──┼──┤ S1 S2 S3 ...

湖滨区13084617272: 51单片机c语言设计,按键控制数码管,依次按下显示0到9循环 -
顾戚天仲: #include<reg51.h> sbit k1=P1^0; #define uint16 unsigned int #define uchar unsigned char uchar code shuzu[ ]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void delay() { uint16 i=1000;while(i--); } void main() { uchar n ; P2=0xfe; P1=0xff; ...

湖滨区13084617272: (80C51单片机)设计4*4键盘及8位数码管显示构成的电子密码锁.的C语言程序. -
顾戚天仲: 4*4矩阵键盘检测程序(新手用),本程序用于检测4*4矩阵按键,先检测是否有按 键按下,如果有按键按下,由P1口读出相应的编码值,由P0经两片74HC573输出给8位数码管,P2^0位选,P2^1段选,P1接4*4矩阵按键#include #include //头文...

湖滨区13084617272: 谁能帮我用C语言编一个80C51的按键程序 -
顾戚天仲: 你先凑合着看看,有时间我再来完善.你应该可以自己改改吧?unsigned char key,key_h,kpush;unsigned int key_l;//按键连接到p1.0、p1.1、p1.2void int_t0(void) inter...

湖滨区13084617272: 51单片机C语言控制按键蜂鸣器 -
顾戚天仲: unsigned char flag=1; //定义上升沿ready标志 while(1) {if(key1&&flag) // 默认key1下拉至GND,若产生上升沿,则响一次,同时清零标志 {SPK=1;delay();SPK=0;flag=0;}if(!key1) { flag=1;} //检测key1是否归零 准备第二次上升沿,是,则标志位置1...... } 仅供参考

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网