找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2939|回复: 2
收起左侧

用单片机pcf8574+4x4矩阵按键实现1602光标控制程序

[复制链接]
ID:584513 发表于 2020-5-14 09:41 | 显示全部楼层 |阅读模式
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

仿真

仿真


单片机源程序如下:
  1. #include<at89x52.h>
  2. #include <intrins.h>
  3. #include "key_8574.h"
  4. #include"1602.h"
  5. uchar key; //定于全局变量key,用于按键扫描后的码值存放
  6. //#define LED P2        //用于事例
  7. uchar i;
  8. int temp=0;         //1602的列
  9. int temp1=0; //1602的行
  10. /*4*4键盘对应的值*/
  11. uchar zi[]={' ',
  12.                         '1','2','3','A',                 
  13.                         '4','5','6','B',
  14.                         '7','8','9','C',
  15.                         '*','0','#','D', };
  16. /*********************************************
  17.     函数名称:delay_ms
  18.         函数功能:延时函数 单位为1ms
  19.         入口参数:uint a
  20.         出口参数:无
  21.         备 注:
  22. *********************************************/
  23. void delay_ms(uint a)
  24. {
  25.         uchar b;
  26.         for(;a>0;a--)
  27.                 for(b=110;b>0;b--);
  28. }
  29. /*********************************************
  30.     函数名称:shuru
  31.         函数功能:实现4*4矩阵按键在1602上的输出
  32.         入口参数:无
  33.         出口参数:无
  34.         备 注:实现输出0~9,光标的移位
  35. *********************************************/
  36. void shuru()
  37. {
  38.         if(key!=0)                                          
  39.         {
  40.                 delay_ms(10); //按键消抖
  41.                 if(key!=0)
  42.                 {
  43.                         i=key;
  44.                         switch(i)
  45.                         {
  46.                                 case 4:
  47.                                         write_com_1602(0x14);        //光标右移一位         (0x14)~(0x17)光标右移一位
  48.                                         temp++;        //列加1                                    //(0x18)~(0x1b)屏幕左移
  49.                                 break;                                                                //(0x1c)~(0x1f)屏幕右移
  50.                                 case 8:
  51.                                         write_com_1602(0x10);        //光标左移一位         (0x10)~(0x13)光标左移一位
  52.                                         temp--; //列减1
  53.                                 break;
  54.                                 case 16:
  55.                                         switch(temp1)                        //查询当前光标在哪一行
  56.                                         {        
  57.                                                 case 1:
  58.                                                         temp1=0;                //改变光标的行
  59.                                                         write_com_1602(0x80+temp);//改变光标的行,列不变
  60.                                                 break;
  61.                                                 case 0:
  62.                                                         temp1=1;                //改变光标的行
  63.                                                         write_com_1602(0xc0+temp);//改变光标的行,列不变
  64.                                                 break;
  65.                                         }                                         
  66.                                 break;                                                         
  67.                                 case 12:
  68.                                         write_com_1602(0x01);        //显示清屏
  69.                                         temp=0;                                        //回到第一列
  70.                                         temp1=0;                                //回到第一行
  71.                                 break;
  72.                                 case 15:
  73.                                         temp++;                                        //向后移动一位
  74.                                         if(temp1==0)                                //如果在第一行
  75.                                         {
  76.                                                 write_com_1602(0x80+temp);//光标显示在第一行        
  77.                                         }
  78.                                         else                                                  //否则
  79.                                         {
  80.                                                 write_com_1602(0xc0+temp);//光标显示在第二行
  81.                                         }
  82.                                         break;
  83.                                 default:
  84.                                         write_char_1602(temp1,temp,zi[ i]); //在当前位置输出数字[ i]
  85.                                         if(temp1==0)                                                 //如果在第一行
  86.                                         {
  87.                                                 write_com_1602(0x80+temp);         //光标显示在第一行
  88.                                         }
  89.                                         else                                                         //否则
  90.                                         {
  91.                                                 write_com_1602(0xc0+temp);         //光标显示在第二行
  92.                                         }                                                           
  93.                                 break;
  94.                                 
  95.                         }
  96.                         if(temp==16)//如果到了最后一列                                                           
  97.                         {
  98.                                 temp=0;        //回到第一列
  99.                                 temp1++;//到下一行
  100.                         }
  101.                         if(temp1==2)//如果到了最后一行
  102.                         {
  103.                                 temp1=0;//回到第一行
  104.                         }
  105.                         if(temp<0)        //如果向左移,移过了第一列
  106.                         {
  107.                                 temp=16;//到最后一列
  108.                                 temp1--;//回到上一行
  109.                         }
  110.                         if(temp1<0)        //如果向上移,移过了第一行
  111.                         {
  112.                                 temp1=1;//到第二行
  113.                                 temp=15;//到最后一列
  114.                         }
  115.                 }
  116.                         while(key!=0);          //等待按键释放        
  117.         }        
  118. }
  119. /*-----------主函数------------*/
  120. void main()
  121. {
  122.         init_8574();//初始化函数
  123.         init_1602();
  124.         /*外部中断0被pcf8574占用*/
  125.         IT0 = 1;        //令INT0下降沿触发
  126.         EX0 = 1;        //开INT0中断
  127.         EA = 1;                //开启总中断
  128.         write_com_1602(0x01);//显示清屏
  129.         while(1)
  130.         {
  131.                 shuru();
  132.         }
  133. }


  134. /*---------------------------------------------
  135. **函数名称:int0()
  136. **函数功能:中断系统
  137. **入口参数:无
  138. **输出参数:无
  139. **说明:当pcf8574P口变化时会产生中断变化,单片机
  140.                 根据中断进行按键扫描
  141. ---------------------------------------------*/
  142. void int0() interrupt 0
  143. {
  144.         EX0 = 0;//为了防止多次进入中断造成干扰,先关闭中断
  145.         key = key_scan();//读取按键值
  146.         EX0 = 1;//开启中断
  147. }

复制代码

51hei.png

全部资料51hei下载地址:
3-3光标控制.zip (128.43 KB, 下载次数: 48)

评分

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

查看全部评分

回复

使用道具 举报

ID:589833 发表于 2020-5-16 10:22 | 显示全部楼层
赞一个
回复

使用道具 举报

ID:1080302 发表于 2023-5-28 00:45 来自手机 | 显示全部楼层
原来如此,豁然开朗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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