AT89c51单片机实现4*4拨号输入,并用6位数码管显示,从右往左依次显示,求大神c语言指教,如

AT89c51单片机实现4*4拨号输入,并用6位数码管显示,从右往左依次显示,求大神c语言指教,如果附带proteus模拟图更好

/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/************* 12864LCD引脚定义 *************/
#define LCD_data P0 //数据口
sbit LCD_RS = P2^6; //寄存器选择输入
sbit LCD_RW = P2^5; //液晶读/写控制
sbit LCD_EN = P2^7; //液晶使能控制
sbit LCD_PSB = P3^2; //串/并方式控制
sbit LCD_RST = P3^7; //液晶复位端口
#define NOP(); {_nop_();_nop_();_nop_();_nop_();};
/*********************************************************/
uchar xdata DIS1[] ={"机组及装架号 "};
uchar xdata DIS2[] ={"输入及存储成功 "};
uchar a;
uchar asc2[]={"123A456B789C*0#D"};//asc2码4*4键盘显示专用
uchar keydat[6]=0;
uchar keycache;
uchar keycache1;
/* 延时函数 */
void delay(int ms)
{unsigned int i;
while( ms-- != 0)
{
for(i = 0; i < 600; i++);
}
}
/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy()
{ bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
NOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
NOP();
LCD_EN = 1;
NOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
NOP();
LCD_EN = 1;
NOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
LCD_PSB = 1; //并口方式

LCD_RST = 0; //液晶复位
delay(3);
LCD_RST = 1;
delay(3);
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if (X==1)
{X=0x80;}
else if (X==2)
{X=0x90;}
else if (X==3)
{X=0x88;}
else if (X==4)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //显示地址
}
/*********************************************************
* *
* 清屏函数 *
* *
*********************************************************/
void clr_screen()
{
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x01); //清屏
delay(5);
}
/**************************************************************
* 名称:KeyRvs()
* 功能:P2外接4×4按键, 按照反转法读出键值
* 输出:按键值0~15/如无键按下, 返回16
***************************************************************/
uchar KeyRvs(void)
{
uchar temH, temL, key;
P1 = 0xf0; //低四位先输出0
temH = P1;//读入,高四位含有按键信息
P1 = 0x0f; //然后反转输出0
temL = P1;//读入,低四位含有按键信息
switch(temH)
{
case 0xe0: key = 0; break;
case 0xd0: key = 1; break;
case 0xb0: key = 2; break;
case 0x70: key = 3; break;
default: return 16;//按下的不是上述按键,就当是没有按键
}
switch(temL) {
case 0x0e: return key;
case 0x0d: return key + 4;
case 0x0b: return key + 8;
case 0x07: return key + 12;
default: return 16;//按下的不是上述按键,就当是没有按键
}
}
/***************************************************************************************
函数名:UART串口初始化函数
调 用:UART_init();
结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备 注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
/**********************************************************************************************/
void UART_init (void){
//EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
//ES = 1; //允许UART串口的中断
TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x40; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xF3; //定时器初值高8位设置
TL1 = 0xF3; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
TR1 = 1; //定时器启动
}
/***************************************************************************************
函数名:UART串口发送函数
调 用:UART_T (?);
参 数:需要UART串口发送的数据(8位/1字节)
结 果:将参数中的数据发送给UART串口,确认发送完成后退出
/**********************************************************************************************/
void UART_T (unsigned char UART_data){ //定义串口发送数据变量
SBUF = UART_data; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0; //令发送中断标志位为0(软件清零)
}
uchar i;
/*********************************************************
*
* 主函数 好难!!!!!!!!基本功能实现
功能1键盘输入6个值,显示在12864上
功能2 *键修改
* 功能3 #键串口输出对应6个asc2码 并退出
*********************************************************/
void main()
{
delay(100); //上电,等待稳定
lcd_init(); //初始化LCD
UART_init ();
a=0;
lcd_pos(1,1); //设置显示位置为第一行
for(i=0;i<16;i++)
{
lcd_wdat(DIS1[i]);
while(lcd_busy());
}
while(1)
{
uchar kkey;
do{keycache=KeyRvs(); }
while(keycache==16);
delay(20);
do{keycache1=KeyRvs(); }
while(keycache1==16);
if(keycache1==keycache){kkey=keycache1;}
do{keycache=KeyRvs();}
while(keycache!=16);
if(a<=5&&(kkey!=14&&kkey!=12))
{ keydat[a]=keycache1;
lcd_pos(2,(a+1));
while(lcd_busy());
lcd_wdat(asc2[keydat[a]]);
a++;
}
if(a>=1&&kkey==12)
{ lcd_pos(2,a);
while(lcd_busy());
lcd_wdat(asc2[0x20]);
keydat[a]=0;
a--;
continue;
}
if(a>5&&kkey==14)
{
UART_T (asc2[keydat[0]]);
UART_T (asc2[keydat[1]]);
UART_T (asc2[keydat[2]]);
UART_T (asc2[keydat[3]]);
UART_T (asc2[keydat[4]]);
UART_T (asc2[keydat[5]]);
lcd_pos(2,0);
for(i=0;i<16;i++)
{
lcd_wdat(DIS2[i]);
while(lcd_busy());
}
delay(1000);
break;
}
}

}
温馨提示:内容为网友见解,仅供参考
无其他回答

AT89c51单片机实现4*4拨号输入,并用6位数码管显示,从右往左依次显示,求...
\/* *\/ \/*写显示数据到LCD *\/ \/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 *\/ \/* *\/

AT89C51单片机怎么用汇编语言让4个数码管同时显示1234?
1、首先我们先打开keil。2、接着,我们要定义好库函数,void main(){while(1)\/\/不断循环显示{dispaly();}}void dispaly(){P0=smg[1];\/\/选择显示数字几,P1=0x7f;\/\/控制是否点亮数码管。3、接着,我们加上一条循环语句。delay(5);\/\/显示5毫秒P0=0XFF;\/\/消影P0=smg[2];P1=0xbf;delay...

用AT89C51单片机,4位共阴极数码管,显示出1234 程序怎么写??? 请各位...
TAB: DB 3FH,06H,5BH,4FH DB 66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH DB 39H,5EH,79H,71H DB 40H END

如何用单片机AT89C51控制六位数码管,可以显示出不同的六个数字(123456...
uchar number=0;void t0isr() interrupt 1 { TH0=0xf4;TL0=0x48;switch(number){ case 0:P2=0x01;P0=distab[1];break;case 1:P2=0x02;P0=distab[2];break;case 2:P2=0x04;P0=distab[3];break;case 3:P2=0x08;P0=distab[4];break;case 4:P2=0x10;P0=distab[5];break;cas...

用C语言编写AT89C51单片机程序,设计一个智能数字钟。
这是我的课程设计,6个数码管,显示时分秒,三个按钮P0.0、P0.1、P0.2可以调时,有8个彩灯(可以不要),没闹钟、倒计时之类的。呵呵。include<AT89X52.H> define uchar unsigned char int i;\/\/***时钟的 uchar one[10]={0xbf,0xb0,0xdb,0xcf,0xe6,0xed,0xfd,0x07,0xff,0xef}...

如何使用单片机at89c51驱动4位8段数码管,如果用到芯片来驱动的,电路...
看你将四位数码管接在单片机的哪一组输出口 例如51单片机一般都是四组八位输i\/o口P0,P1,P2,P3口 一般P0口是三态i\/o是要接上拉电阻的。其他接口是不用接上拉电阻的。上拉电阻一般选用1k~4k7都可以保证各管脚输出的电流小于500mA就可以了。图我传的这个图 六位数码管虽然是共阴极的 (...

求程序用AT89C51单片机...用六位数码管实现数字时钟,显示时分秒,用两个...
TL0=(65536-45872)%256; \/\/定时器初值,定时50ms(12M晶振),由于考虑MCU指令处理时间,此处赋初值位45872 EA=1;ET0=1;TR0=1;}void timer0() interrupt 1 \/\/定时计数器中断 { TH0=(65536-45872)\/256;TL0=(65536-45872)%256; 、aa++;if(aa==20) \/\/中断2次位1S,秒加1 { miao++;...

AT89C51单片机实现4位数码管显示学号后四位,谢谢
\/\/共阴数码管七段码 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77};uchar code table2[]={5,4,3,2};\/\/这就是学号的后4位,自行修改 void display()\/\/4位显示子程序 { P0=~(table[ table2[0]]);wei1=0;Delay1ms(2);wei1=1;P0=~(...

单片机 at89c51 6位数码管24小时倒计时程序
uchar hour,min,sec;uint count;uchar code tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar code add[6]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb};\/***延时一毫秒***\/ void delay1ms(void){ unsigned char a,b,c;for(c=1;c>0;c--)for(b=142;b>0...

编写一个AT89C52单片机控制四相单四拍步进电机汇编程序,急用...
1实验任务基于MCS-51系列单片机AT89C51,设计一个控制步进电动机的控制装置。2设计要求:1)采用单片机控制一个小功率四相四拍的步进电机工作,步进电机步距为1.5度,最大相电流100mA... 1 实验任务基于MCS-51系列单片机AT89C51,设计一个控制步进电动机的控制装置。2 设计要求:1) 采用单片机控制一个小功率四相四拍的...

相似回答