📄 keypad.c
字号:
/*
* keypad.c
*
* Created on: 2013-3-19
* Author: think
*/
#include "msp430x54xA.h"
#include "cry12864.h"
/* 4X4矩阵按键
* P7,P2都是高4位操作,P7输出,P2输入
* */
#define KEY_ROW P7DIR |=0xf0
#define KEY_COL P2DIR |=0x00
#define KEY_DIN P2IN
#define KEY_DOUT P7OUT
#define start 5 //按键6,启动
#define stop 6 //按键7,停止
#define mode 1 //按键1,模式
#define add 3 //按键2,加
#define dec 4 //按键3,减
#define set 2 //按键4,选择对象
void RTC_clock(void);
typedef unsigned char uchar;
typedef unsigned int uint;
uchar key_Pressed;
uchar key_val;
uchar key_flag;
uchar t_hour,h1,h2;
uchar t_min,m1,m2;
uchar t_sec,s1,s2;
uchar Num=1;
volatile uchar cursor=0,m_AN=0; //光标位置变量,mode按键次数
uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; //16个按键的键值数组
void Init_Keypad(void)
{
KEY_ROW;
KEY_COL;
KEY_DOUT |= 0XF0;
key_flag = 0;
key_Pressed = 0;
key_val = 0;
}
void Check_Key(void)
{
uchar row, col, tmp1, tmp2;
tmp1 = 0x80;
for(row=0; row<4; row++) //行扫描
{
KEY_DOUT = 0XF0; //输出全为1
KEY_DOUT-= tmp1; //依次输出一个为0
tmp1 >>=1;
if((KEY_DIN & 0xF0) < 0xF0) //P2输入是否有一位为0
{
tmp2 = 0x10; //用于检测出哪一位为0
for(col=0; col<4; col++) //列扫描
{
if(0x00 == (KEY_DIN & tmp2)) //找到等于0的列
{
key_val = key_Map[row*4 + col];//获取键值
return; //退出循环
}
tmp2 <<= 1; //右移1位
}
}
}
}
void delay()
{
uint tmp;
for(tmp = 200000; tmp>0; tmp--);
}
void Key_Event(void)
{
uchar tmp;
KEY_DOUT =0x00; //设置P7OUT为0
tmp = KEY_DIN; //获取P2IN
if ((0x00 == key_Pressed) && ((tmp & 0xF0) < 0xF0)) //如果有键按下
{
key_Pressed = 1; //按键按下标识位置位
delay(); //延时去抖
Check_Key(); //获取键
// key_flag = 1; //按键标识置位
}
else if ((key_Pressed == 1)&&((tmp & 0xf0) == 0xF0)) //如果按键释放
{
key_Pressed = 0; //清除标识位
key_flag = 1; //按键标识位置位
}
else
{
_NOP();
}
}
/*******
* 模式功能选择按键,key_val按1下进入时间动态显示,等同于电子表。在按第2下进入静态模式。
* 有其他按键按下会断开功能按键,需要重新按下按键。
********/
void Key_Mode(void)
{
if(key_val==mode)
{
if(key_flag)
{
++m_AN;
key_flag=0;
}
if(m_AN>2)m_AN=1;
if(m_AN==1)
{
/*****进入动态模式,电机启动,停止有效,电子表保持运行,*****/
}
if(m_AN==2)
{
/*****进入静态模式,时钟启动,停止有效,*****/
}
}
}
void Key_start(void)
{
if(m_AN==1)
{/*****在动态模式下,启动信号是启动电机,电子表保持运行*****/
if(key_val==start)
{
RTCCTL01 &= ~(RTCHOLD); //RTC电子表启动信号
// ADC12CTL0 |= ADC12SC; // Start sampling/conversion
RTC_clock();
}
}
if(m_AN==2)
{/*****在静态模式下,启动信号是启动电子表,*****/
if(key_val==start)
{
RTCCTL01 &= ~(RTCHOLD); //RTC电子表启动信号
// ADC12CTL0 |= ADC12SC; // Start sampling/conversion
RTC_clock();
}
}
}
void Key_stop(void)
{
if(m_AN==1)
{/*****在动态模式下,停止信号是关闭电机,电子表保持运行*****/
if(key_val==stop)
{
RTCCTL01 &= ~(RTCHOLD); //RTC电子表启动信号
RTC_clock();
}
}
if(m_AN==2)
{/*****在静态模式下,停止信号是关闭电子表,*****/
if(key_val==stop)
{
RTCCTL01 |= (RTCHOLD); //RTC电子表停止信号
}
}
}
/*****光标移动位置,选择操作数*****/
void Key_Cursor(void)
{
if(key_val==set)
{
ADC12CTL0 &=~ ADC12SC; // Start sampling/conversion
m_AN=2;
if(key_flag)
{
cursor++; // 光标移动位置加1
key_flag=0;
}
if(cursor>4)cursor=1;
if(cursor==1) //小时位置显示光标及其位置
{
Write_Cmd(0x83);
Write_Cmd(0x0f);
}
if(cursor==2) //分钟位置显示光标及其位置
{
Write_Cmd(0x85);
Write_Cmd(0x0f);
}
if(cursor==3) //秒钟位置显示光标及其位置
{
Write_Cmd(0x87);
Write_Cmd(0x0f);
}
if(cursor==4) //Num位置显示光标及其位置
{
Write_Cmd(0x9a);
Write_Cmd(0x0f);
}
}
}
/*****光标对应的数字加运算*****/
void Key_add(void)
{/*****光标运行的情况下对数字加运算*****/
if(cursor!=0)
{
if(key_val==add)
{
m_AN=2;
if(cursor==1) //小时数字加运算
{
if(key_flag)
{
t_hour++;
key_flag=0;
}
if(t_hour>23) t_hour=0;
h1=t_hour/10;
h2=t_hour%10;
Write_Cmd(0x83); //写入DDRAM地址,游标开,游标位置关
Write_Cmd(0x0e);
Write_Data(0x30+h1); //写十位时钟数据
Write_Data(0x30+h2); //写个位时钟数据
}
if(cursor==2) //分钟数字加运算
{
if(key_flag)
{
t_min++;
key_flag=0;
}
if(t_min>59) t_min=0;
m1=t_min/10;
m2=t_min%10;
Write_Cmd(0x85); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+m1); //写十位分数据
Write_Data(0x30+m2); //写个位分数据
}
if(cursor==3) //秒钟数字加运算
{
if(key_flag)
{
t_sec++;
key_flag=0;
}
if(t_sec>59) t_sec=0;
s1=t_sec/10;
s2=t_sec%10;
Write_Cmd(0x87); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+s1); //写十位秒数据
Write_Data(0x30+s2); //写个位秒数据
}
if(cursor==4) //Num数量加运算
{
if(key_flag){
Num++;
key_flag=0;
}
if(Num>4) Num=1;
Write_Cmd(0x9a); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+Num); //写Num数据
Write_Data(0x20);
}
}
}
}
/*****光标对应的数字加运算*****/
void Key_dec(void)
{/*****光标运行的情况下对数字减运算*****/
if(cursor!=0)
{
if(key_val == dec)
{
m_AN=2;
if(cursor==1) //时钟数字减运算
{
if(key_flag){
t_hour--;
key_flag=0;
}
h1=t_hour/10;
h2=t_hour%10;
Write_Cmd(0x83); //写入DDRAM地址,游标开,游标位置关
Write_Cmd(0x0e);
Write_Data(0x30+h1); //写十位时钟数据
Write_Data(0x30+h2); //写个位时钟数据
if(t_hour>24) t_hour=23;
}
if(cursor==2) //分钟数字减运算
{
if(key_flag){
t_min--;
key_flag=0;
}
m1=t_min/10;
m2=t_min%10;
Write_Cmd(0x85); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+m1); //写十位分数据
Write_Data(0x30+m2); //写个位分数据
if(t_min>59) t_min=59;
}
if(cursor==3) //秒钟数字减运算
{
if(key_flag){
t_sec--;
key_flag=0;
}
s1=t_sec/10;
s2=t_sec%10;
Write_Cmd(0x87); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+s1); //写十位秒数据
Write_Data(0x30+s2); //写个位秒数据
if(t_sec>59) t_sec=59;
}
if(cursor==4) //Num数字减运算
{
if(key_flag){
Num--;
key_flag=0;
}
Write_Cmd(0x9a); //操作DDRAM地址
Write_Cmd(0x0e); //游标打开、位置关闭
Write_Data(0x30+Num); //写Num数据
Write_Data(0x20);
if(Num==0) Num=4;
}
}
}
}
/*****电子时钟显示函数,*****/
void RTC_clock(void)
{
s1=t_sec/10;
s2=t_sec%10;
Write_Cmd(0x87); //操作DDRAM地址
Write_Cmd(0x0c); //游标打开、位置关闭
Write_Data(0x30+s1); //写十位秒数据
Write_Data(0x30+s2); //写个位秒数据
if(t_sec>59)
{
t_sec=0;
Write_Cmd(0x85);
t_min++;
m1=t_min/10;
m2=t_min%10;
Write_Cmd(0x85); //操作DDRAM地址
Write_Data(0x30+m1); //写十位分数据
Write_Data(0x30+m2);
if(t_min>59)
{
t_min=0;
t_hour++;
h1=t_hour/10;
h2=t_hour%10;
Write_Cmd(0x83); //写入DDRAM地址,游标开,游标位置关
Write_Data(0x30+h1); //写十位时钟数据
Write_Data(0x30+h2); //写个位时钟数据
if(t_hour>23)t_hour=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -