仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<at89x52.h>
- #include <intrins.h>
- #include "key_8574.h"
- #include"1602.h"
- uchar key; //定于全局变量key,用于按键扫描后的码值存放
- //#define LED P2 //用于事例
- uchar i;
- int temp=0; //1602的列
- int temp1=0; //1602的行
- /*4*4键盘对应的值*/
- uchar zi[]={' ',
- '1','2','3','A',
- '4','5','6','B',
- '7','8','9','C',
- '*','0','#','D', };
- /*********************************************
- 函数名称:delay_ms
- 函数功能:延时函数 单位为1ms
- 入口参数:uint a
- 出口参数:无
- 备 注:
- *********************************************/
- void delay_ms(uint a)
- {
- uchar b;
- for(;a>0;a--)
- for(b=110;b>0;b--);
- }
- /*********************************************
- 函数名称:shuru
- 函数功能:实现4*4矩阵按键在1602上的输出
- 入口参数:无
- 出口参数:无
- 备 注:实现输出0~9,光标的移位
- *********************************************/
- void shuru()
- {
- if(key!=0)
- {
- delay_ms(10); //按键消抖
- if(key!=0)
- {
- i=key;
- switch(i)
- {
- case 4:
- write_com_1602(0x14); //光标右移一位 (0x14)~(0x17)光标右移一位
- temp++; //列加1 //(0x18)~(0x1b)屏幕左移
- break; //(0x1c)~(0x1f)屏幕右移
- case 8:
- write_com_1602(0x10); //光标左移一位 (0x10)~(0x13)光标左移一位
- temp--; //列减1
- break;
- case 16:
- switch(temp1) //查询当前光标在哪一行
- {
- case 1:
- temp1=0; //改变光标的行
- write_com_1602(0x80+temp);//改变光标的行,列不变
- break;
- case 0:
- temp1=1; //改变光标的行
- write_com_1602(0xc0+temp);//改变光标的行,列不变
- break;
- }
- break;
- case 12:
- write_com_1602(0x01); //显示清屏
- temp=0; //回到第一列
- temp1=0; //回到第一行
- break;
- case 15:
- temp++; //向后移动一位
- if(temp1==0) //如果在第一行
- {
- write_com_1602(0x80+temp);//光标显示在第一行
- }
- else //否则
- {
- write_com_1602(0xc0+temp);//光标显示在第二行
- }
- break;
- default:
- write_char_1602(temp1,temp,zi[ i]); //在当前位置输出数字[ i]
- if(temp1==0) //如果在第一行
- {
- write_com_1602(0x80+temp); //光标显示在第一行
- }
- else //否则
- {
- write_com_1602(0xc0+temp); //光标显示在第二行
- }
- break;
-
- }
- if(temp==16)//如果到了最后一列
- {
- temp=0; //回到第一列
- temp1++;//到下一行
- }
- if(temp1==2)//如果到了最后一行
- {
- temp1=0;//回到第一行
- }
- if(temp<0) //如果向左移,移过了第一列
- {
- temp=16;//到最后一列
- temp1--;//回到上一行
- }
- if(temp1<0) //如果向上移,移过了第一行
- {
- temp1=1;//到第二行
- temp=15;//到最后一列
- }
- }
- while(key!=0); //等待按键释放
- }
- }
- /*-----------主函数------------*/
- void main()
- {
- init_8574();//初始化函数
- init_1602();
- /*外部中断0被pcf8574占用*/
- IT0 = 1; //令INT0下降沿触发
- EX0 = 1; //开INT0中断
- EA = 1; //开启总中断
- write_com_1602(0x01);//显示清屏
- while(1)
- {
- shuru();
- }
- }
- /*---------------------------------------------
- **函数名称:int0()
- **函数功能:中断系统
- **入口参数:无
- **输出参数:无
- **说明:当pcf8574P口变化时会产生中断变化,单片机
- 根据中断进行按键扫描
- ---------------------------------------------*/
- void int0() interrupt 0
- {
- EX0 = 0;//为了防止多次进入中断造成干扰,先关闭中断
- key = key_scan();//读取按键值
- EX0 = 1;//开启中断
- }
复制代码
全部资料51hei下载地址:
3-3光标控制.zip
(128.43 KB, 下载次数: 54)
|