我自己焊了了一个4*4矩阵键盘接在了 p1口,现在单个按键可以显示内容 我想做的是两个按键实行上下翻页显示
有人能指导交流一下吗
下面是我的main.c程序 欢迎指正
#include <msp430x14x.h>
#include "12864.h"
#include "UART.h"
#define KEY_DIR P1DIR
#define KEY_OUT P1OUT
#define KEY_IN P1IN
#define KEY_IE P1IE
#define KEY_IES P1IES
#define KEY_IFG P1IFG
void init_sys(unsigned int a);
void init_p20(void);
unsigned int counter_p20;
//中断初始化 p2.0
void init_p20(void)
{
P2DIR &= 0xfe; //p2.0为输入方向
P2SEL &= 0xfe; //选择p2.0产生中断
P2IES |= 0x01; //下降沿产生中断
P2IE |= 0x01; //使能p2.0中断
_EINT();
counter_p20 = 0;
}
//中断响应
#pragma vector=PORT2_VECTOR
__interrupt void p2int()
{
counter_p20++;
P2IFG &= 0xfe; //清除中断标志
if(counter_p20 > 3)
{
P2SEL |= 0x01; //选择p2.0为普通I/O口
P2IE &= 0xfe; //禁止p2.0中断
}
}
//系统初始化,等待GPS产生可用数据
void init_sys(unsigned int a)
{
while(counter_p20 <= 3)
{
display_char(2,11,' ');
display_char(2,12,' ');
display_char(2,13,' ');
display_char(2,14,' ');
display(2,3,(unsigned char *)"初始化");
display_char(2,11,'.');
delay_Nms(a);
display_char(2,12,'.');
delay_Nms(a);
display_char(2,13,'.');
delay_Nms(a);
display_char(2,14,'.');
delay_Nms(a);
}
}
/***************全局变量***************/
unsigned char Key_Val; //存放键值
void CtrlKey(unsigned char sw); //控制键盘开关//sw=0关 sw=1开
/*******************************************
函数名称:Init_Keypad
功 能:初始化扫描键盘的IO端口
参 数:无
返回值 :无
********************************************/
void Init_Keypad(void)
{
KEY_DIR = 0x0f; //P1.0~P1.3设置为输出状态,P1.4~P1.7输入 状态(上拉H)
KEY_OUT &=0xf0; //P1.0~P1.3输出为低电平
KEY_IES =0xf0; //P1.4~P1.7下降沿触发中断
KEY_IE =0xf0; //P1.4~P1.7允许中断
KEY_IFG= 0; //中断标志清0
Key_Val = 16; //按键值初始设为非0~15的值均可
}
/*******************************************
函数名称:Check_Key
功 能:扫描键盘的IO端口,获得键值
参 数:无
返回值 :无
********************************************/
//p14567 接上拉电阻
/***************************************
key_Val 对应键值
列:[p14] [p15] [p16] [p17]
↓ ↓ ↓ ↓
行:
[p13]→ 0 1 2 3
[p12]→ 4 5 6 7
[p11]→ 8 9 10 11
[p10]→ 12 13 14 15
***************************************/
void Check_Key(void)
{
unsigned char hang ,lie,tmp1,tmp2;
unsigned char keymap[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//设置键盘逻辑键值与程序计算键值的映射
tmp1 = 0x08;
for(hang = 0;hang < 4;hang++) //行扫描
{
KEY_OUT = 0x0f; //P1.0~P1.3输出全1
KEY_OUT -= tmp1; //P1.0~p1.3输出四位中有一个为0
tmp1 >>=1;
if((KEY_IN & 0xf0)<0xf0) //是否P1IN的P1.4~P1.7中有一位为0
{
tmp2 = 0x10; // tmp2用于检测出哪一位为0
for(lie = 0;lie < 4;lie++) // 列检测
{
if((KEY_IN & tmp2) == 0x00) // 是否是该列,等于0为是
{
Key_Val = keymap[hang*4 + lie]; // 获取键值
return; // 退出循环
}
tmp2 <<= 1; // tmp2右移1位
}
}
}
}
/*******************************************
函数名称:delay
功 能:延时约15ms,完成消抖功能
参 数:无
返回值 :t= tmp*5*clk 根据使用时钟调整tmp值
********************************************/
void delay(void)
{
unsigned int tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功 能:检测按键,并获取键值
参 数:无
返回值 :无
********************************************/
void Key_Event(void)
{
unsigned char tmp;
KEY_OUT =0; // 设置P1OUT全为0,等待按键输入
tmp = KEY_IN; // 获取 p1IN
if((tmp & 0xf0) < 0xf0) //如果有键按下
{
delay(); //消除抖动
Check_Key(); // 调用check_Key(),获取键值
P2DIR =0xff;
P2OUT =0xfb;
switch(Key_Val) //P2.0~P2.3接发光二极管,测试程序用
{
case 0:P2OUT=0xef;cls();display(1,1,(unsigned char *)"火车站");break;
case 1:P2OUT=0xdf;cls();display(1,1,(unsigned char *)"火车站到了");break;
case 2:P2OUT=0xbf;cls();display(1,1,(unsigned char *)"西安科技大学");break;
case 3:P2OUT=0x7f;cls();display(1,1,(unsigned char *)"西安科技大学到了");break;
case 4:P2OUT=0x7f;cls();display(1,1,(unsigned char *)"西安工程大学");break;
case 5:P2OUT=0xbf;cls();display(1,1,(unsigned char *)"西安科技大学到了");break;
case 6:P2OUT=0xdf;cls();display(1,1,(unsigned char *)"兵马俑");break;
case 7:P2OUT=0xef;cls();display(1,1,(unsigned char *)"兵马俑到了");break;
case 8:P2OUT=0xfb;break;
case 9:P2OUT=0xfd;delay_Nms(50);cls();init_UART0();break;
case 10:P2OUT=0xf7;break;
case 11:P2OUT=0xf7;break;
case 12:P2OUT=0xef;break;
case 13:P2OUT=0xdf;break;
case 14:P2OUT=0xbf;break;
case 15:P2OUT=0x7f;break;
default :break;
}
}
}
/*********************************************************************
控制打开或者关闭键盘中断
SW= 0:关闭; ELSE:打开
*********************************************************************/
void CtrlKey(unsigned char sw)
{
if(sw==0)
KEY_IE =0; //关闭端口中断
else
KEY_IE =0xf0; //打开端口中断
}
/*********************************************************************
主函数
*********************************************************************/
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
init_LCD();
init_p20();
init_sys(500);
init_UART0();
Init_Keypad(); //键盘初始化
delay_1ms();
CtrlKey(1); //键盘打开
while(1)
Key_Event(); //不断扫描,获取键值
}
/*端口1按键中断*/
#pragma vector=PORT1_VECTOR
__interrupt void Port(void)
{
if((KEY_IFG&0xf0)!=0)
{
Key_Event();
if(Key_Val!=16) //键值!=16有键按下
{
CtrlKey(0); //关键盘中断
}
}
KEY_IFG=0;KEY_OUT=0; //清中断标志
}
一周热门 更多>