找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2457|回复: 0
收起左侧

51单片机6x6矩阵键盘驱动程序

[复制链接]
ID:718659 发表于 2020-3-31 14:07 | 显示全部楼层 |阅读模式
自学了一点单片机知识,写了一个6x6矩阵键盘,用的行列扫描法,P1P3口是键盘口,P0是液晶屏口,按下按键液晶屏输出字符,液晶相关代码是百度的,大佬们见笑了

电路原理图如下:

仿真

仿真


单片机源程序如下:

#include "reg51.h"        
#include <math.h>
#include <stdio.h>

sbit rs=P2^6;            //指令or数据  RD
sbit wela=P2^5;          //读or写      WR
sbit lcden=P2^7;         //使能信号LCD

unsigned int KeyValue,KeyState;
//************************************************************************/
// 描述: 延时t us函数
//************************************************************************/
void LCD_Delay_us(unsigned int t)
{
        while(t--);           //t=0,退出
}
//************************************************************************/
// 描述: 延时t ms函数
//************************************************************************/
void LCD_Delay_ms(unsigned int t)
{
        unsigned int i,j;
        for(i=0;i<t;i++)                       //执行t次循环
        for(j=0;j<113;j++)                     //执行113次循环
        ;
}
//************************************************************************/
// 描述: 1602液晶写指令
//************************************************************************/
void write_com(unsigned char com)            //1602液晶写指令
{
        rs=0;                       //写指令
        lcden=0;                    //使能1602
        P0=com;                     //写入指令com
        LCD_Delay_ms(1);            //延时1ms
        lcden=1;                    //使能1602
        LCD_Delay_ms(2);            //延时2ms  
        lcden=0;                        //使能1602
}
//************************************************************************/
// 描述:1602液晶写数据
//************************************************************************/
void write_date(unsigned char date)             //1602液晶写数据
{
        rs=1;                        //写数据
        lcden=0;                     //使能1602
        P0=date;                     //写入数据date
        LCD_Delay_ms(1);             //延时1ms
        lcden=1;                     //使能1602
        LCD_Delay_ms(2);             //延时2ms
        lcden=0;                         //使能1602
}
//************************************************************************/
// 描述:指定x,y写入字符函数
//************************************************************************/
void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
{     
         if (y == 0){write_com(0x80 + x);}   //第一行  
         else{write_com(0xc0 + x);}          //第二行
         write_date( Data);                  //写入数据
}
//指定x,y写入字符串函数
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{     
if (y == 0){write_com(0x80 + x);}                 //第一行
else{write_com(0xC0 + x);}                        //第二行
while (*s)                                        //
         {write_date( *s); s++;}                      //写入数据
}
//************************************************************************/
// 描述:初始化液晶,及画面初始化
//************************************************************************/
void init_lcd(void)            //初始化液晶,及画面初始化
{
        wela=0;                      //写液晶
        lcden=0;                     //使能1602
        write_com(0x38);             //8 位总线,双行显示,5X7 的点阵字符
        LCD_Delay_us(100);           //延时100us
        write_com(0x0F);             //开显示,有光标,闪烁
        write_com(0x06);             //光标右移动
        write_com(0x01);             //清屏
        write_com(0x80);             //DDRAM 地址归0
}
//键盘输入函数**********************************************************************
void KeyDown(void)
{
         char a=0;
         P3=0x3f;
         P1=0x00;
         KeyState=0;
          if(P3!=0x3f)//读取按键是否按下
         {
                LCD_Delay_ms(10);//延时10ms进行消抖
                if(P3!=0x3f)//再次检测键盘是否按下
                {        
               
                        P3=0x3f;
                        P1=0x00;
                         KeyState=1;
                        switch(P3)            //P3口选择
                        {
                                case(0x3e):        KeyValue=0;break;
                                case(0x3d):        KeyValue=1;break;
                                case(0x3b): KeyValue=2;break;
                                case(0x37):        KeyValue=3;break;
                                case(0x2f):        KeyValue=4;break;
                                case(0x1f):        KeyValue=5;break;
                        }
               
                        P1=0x3f;               //高低电平对调
                        P3=0x00;
                        switch(P1)          //检测P1口
                        {
                                case(0x3e):        KeyValue=KeyValue;break;
                                case(0x3d):        KeyValue=KeyValue+6;break;
                                case(0x3b): KeyValue=KeyValue+12;break;
                                case(0x37):        KeyValue=KeyValue+18;break;
                                case(0x2f):        KeyValue=KeyValue+24;break;
                                case(0x1f):        KeyValue=KeyValue+30;break;
                        //default: KeyValue=0;
                        }
               
                        while(P1!=0x3f)  //检测按键松手检测
                        {
                                LCD_Delay_ms(10);
                                a++;
                        }
                }
        }
        
}

//***********************************************************************
void main()
{
        unsigned char a[]="0123456789abcdefghigklmnopqrstuvwxyz";
        init_lcd() ;
        while(1)
        {
               
                KeyDown();
                if(KeyState)
                {
    write_date(a[KeyValue]);
          KeyState=0;
          }
   }
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表