键盘中断程序+液晶显示
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MSP430F14 4*4键盘中断+液晶显示程序
#include "msp430x14x.h"
#define RS_H P5OUT |=BIT3 //Data Register is selected
#define RS_L P5OUT &=~BIT3 //Instruction Register is selected
#define READ P5OUT |= BIT2 //读LCD
#define WRITE P5OUT &= ~BIT2 //写LCD
#define EN_H P5OUT |= BIT1 //Enable Read/Write Operation
#define EN_L P5OUT &=~BIT1 //Disable Read/Write Operation
unsigned char a[]="Welcome! "; //定义全局数组
unsigned char b[]="Level control!";
unsigned char c[]="Temperature!";
unsigned char d[]="Pressure!";
unsigned char e[]="Liu Liang!";
void Init_CLK(void)
{
unsigned int i;
BCSCTL1=0x00; //将寄存器BCSCTL1的内容清零、XT2振荡器开启、LFTX1工作在低频模式
//ACLK的分频因子为1
do
{
IFG1&=~OFIFG; //清除OSCFault标志
for(i=0x20;i>0;i--);
}
while((IFG1&OFIFG)==OFIFG);
BCSCTL2=0x00; //将寄存器BCSCTL2的内容清零
BCSCTL2+=SELM1;//MCLK的时钟源为XT2CLK,分频因子为1
BCSCTL2+=SELS; //SMMLK的时钟源为XT2CLK,分频因子为1
}
void Init_Port()
{
P3SEL=0x00; //LCD所需端口设置
P3DIR=0xFF;
P3OUT&=~BIT5;
P5SEL=0x00; //P5输出
P5DIR=0xFF;
P5OUT=0x00;
P4SEL=0x00; //P4输出
P4DIR=0xFF;
P4OUT=0x00;
//将P1口所有的管脚在初始化的时候设置为输入方式
P1DIR = 0;
//将P1口所有的管脚设置为一般I/O口
P1SEL = 0;
// 将P1.4 P1.5 P1.6 P1.7设置为输出方向
P1DIR |= BIT4;
P1DIR |= BIT5;
P1DIR |= BIT6;
P1DIR |= BIT7;
//先输出低电平
P1OUT = 0x00;
// 将中断寄存器清零
P1IE = 0;
P1IES = 0;
P1IFG = 0;
//打开管脚的中断功能
//对应的管脚由高到低电平跳变使相应的标志置位
P1IE |= BIT0;
P1IES|= BIT0;
P1IE |= BIT1;
P1IES|= BIT1;
P1IE |= BIT2;
P1IES|= BIT2;
P1IE |= BIT3;
P1IES |= BIT3;
}
void Delay(unsigned int i) //延时子程序
{
while(i--);
}
void Write_Command(unsigned char command )
{
P4OUT=command;
RS_L; //选择程序寄存器
WRITE; //允许写操作
EN_H; //液晶使能
Delay(1000);//延时
EN_L; //液晶读写操作禁止
Delay(1000);
}
void Write_Data(unsigned char data )
{
P4OUT=data;
RS_H; //选择数据寄存器
WRITE; //允许写操作
EN_H; //液晶使能
Delay(1000); //延时
EN_L ; //液晶读写操作禁止
Delay(1000);
}
void Clear_Second_Line() //用于删除2*16字符液的晶第二行的函数
{
int i=16;
Write_Command(0xC0); //设置DDRAM的初始地址
while(i--)
{
P4OUT=0x20;
RS_H; //选择数据寄存器
WRITE; //允许写操作
EN_H; //液晶使能
Delay(1000); //延时
EN_L ; //液晶读
写操作禁止
Delay(1000);
}
}
void Init_LCD(void)
{
Write_Command( 0x38 );//8位总线接口,双行显示,5*7点阵型
Delay(500);
Write_Command(0x0F);//开显示,开光标,光标闪烁
Delay(500);
Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0x80);//设置DDRAM的初始地址
}
int KeyProcess(void)
{
//P5OUT&=0x00;
P5OUT=0x00;
Delay(30000);
unsigned char nP10,nP11,nP12,nP13;
nP10=0;
nP11=0;
nP12=0;
nP13=0;
int nRes = 0;
//P1.7输出低电平
P1OUT = ~(BIT7);
Delay(50);
nP10 = P1IN & BIT0;
if (nP10 == 0)
{
nRes = 13;
P5OUT|=BIT4;
}
nP11 = P1IN & BIT1;
if (nP11 == 0)
{
nRes = 14;
P5OUT|=BIT4;
}
nP12 = P1IN & BIT2;
if (nP12 == 0)
{
nRes = 15;
P5OUT|=BIT4;
}
nP13 = P1IN & BIT3;
if (nP13 == 0)
{
nRes = 16;
//P5OUT=0x00;
P5OUT|=BIT4;
}
//P1.6输出低电平
P1OUT = ~(BIT6);
Delay(50);
nP10 = P1IN & BIT0;
if (nP10 == 0)
{
nRes = 9;
P5OUT|=BIT5;
}
nP11 = P1IN & BIT1;
if (nP11 == 0)
{
nRes = 10;
P5OUT|=BIT5;
}
nP12 = P1IN & BIT2;
if (nP12 == 0)
{
nRes = 11;
P5OUT|=BIT5;
}
nP13 = P1IN & BIT3;
if (nP13 == 0)
{
nRes = 12;
//P5OUT=0x00;
P5OUT|=BIT5;
}
//P1.5输出低电平
P1OUT = ~(BIT5);
Delay(50);
nP10 = P1IN & BIT0;
if (nP10 == 0)
{
nRes = 5;
P5OUT|=BIT6;
}
nP11 = P1IN & BIT1;
if (nP11 == 0)
{
nRes = 6;
P5OUT|=BIT6;
}
nP12 = P1IN & BIT2;
if (nP12 == 0)
{
nRes = 7;
P5OUT|=BIT6;
}
nP13 = P1IN & BIT3;
if (nP13 == 0)
{
nRes = 8;
//P5OUT=0x00;
P5OUT|=BIT6;
}
//P1.4输出低电平
P1OUT = ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0)
{
nRes = 1;
P5OUT|=BIT7;
}
nP11 = P1IN & BIT1;
if (nP11 == 0)
{
nRes = 2;
P5OUT|=BIT7;
}
nP12 = P1IN & BIT2;
if (nP12 == 0)
{
nRes = 3;
P5OUT|=BIT7;
}
nP13 = P1IN & BIT3;
if (nP13 == 0)
{
nRes = 4;
P5OUT|=BIT7;
}
P1OUT = 0x00;//恢复以前值。
//读取各个管脚的状态
for(;;)
{
if((P1IN&0x0F)==0x0F )
{
break;//等待松开按键
}
}
return nRes;
}
// 处理来自端口 1 的中断
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
int key_value;
Delay(30000);
key_value=KeyProcess();
switch(key_value)
{
case 1:
// Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('8');
break;
case 2:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('4');
break;
case 3:
// Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('0');
break;
case 4:
Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0x80);//设置DDRAM的初始地址
for(unsigned int i=0;b!='\0';i++) //在液晶第二行输出
{
Write_Data(b);
}
break;
case 5:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('9');
break;
case 6:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('5');
break;
case 7:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有
的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('1');
break;
case 8:
Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0x80);//设置DDRAM的初始地址
for(unsigned int i=0;c!='\0';i++) //在液晶第二行输出
{
Write_Data(c);
}
break;
case 9:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('.');
break;
case 10:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('6');
break;
case 11:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('2');
break;
case 12:
Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0x80);//设置DDRAM的初始地址
for(unsigned int i=0;d!='\0';i++) //在液晶第二行输出
{
Write_Data(d);
}
break;
case 13:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('a');
break;
case 14:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('7');
break;
case 15:
//Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Clear_Second_Line();
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0xC0); //设置DDRAM的初始地址
Write_Data('3');
break;
case 16:
Write_Command(0x01);//清屏,将空格字符ASCII码20H写入到所有的DDRAM单元
Delay(5000);
Write_Command(0x06);//设置进入方式,DDRAM自增,整个显示右移
Delay(500);
Write_Command(0x80); //设置DDRAM的初始地址
for(unsigned int i=0;e!='\0';i++) //在液晶第二行输出
{
Write_Data(e);
}
break;
}
if(P1IFG & BIT0)
{
P1IFG &= ~(BIT0);// 清除中断标志位
}
if(P1IFG & BIT1)
{
P1IFG &= ~(BIT1);// 清除中断标志位
}
if(P1IFG & BIT2)
{
P1IFG &= ~(BIT2);// 清除中断标志位
}
if(P1IFG & BIT3)
{
P1IFG &= ~(BIT3);// 清除中断标志位
}
}
void main()
{
WDTCTL=WDTPW+WDTHOLD; //禁止看门狗
Delay(50000); //延时,等待液晶电压上升,大约需要30ms
_DINT(); //禁止中断,一般在设置硬件时都要禁止中断
Init_CLK();
Init_Port();
Init_LCD();
_EINT(); //打开中断
for(unsigned int i=0;a!='\0';i++)
{
Write_Data(a);
}
/* Write_Command(0xC0); //写入液晶第二行的手地址
for(unsigned int i=0;b!='\0';i++) //在液晶第二行输出
{
Write_Data(b);
}*/
while(1)
{};
}