📄 msp4302274_1602.c
字号:
//MSP430F14 4*4键盘中断+液晶显示程序
#include <msp430x22x4.h>
#define uchar unsigned char
#define rs_1 (P2OUT|=BIT4)
#define rs_0 (P2OUT&=~BIT4)
#define ep_1 (P2OUT|=BIT3)
#define ep_0 (P2OUT&=~BIT3)
#define rw_1 (P3OUT|=BIT6)
#define rw_0 (P3OUT&=~BIT6)
/**************************************************************************/
int k=0; //定义全局变量
int r=3;
float T_up;
float T_down;
int T_c=375;
int T_h=985;
//...............................................................................
void lcd_wcmd(uchar);
void lcd_pos(uchar);
void lcd_wdat(uchar);
void display(uchar,uchar *);
//.............................................................................
void delay(long i);
int delay2(void);
void Spiwrite(unsigned char i);
void delay1(uchar);
unsigned char Spiread(unsigned char i);
void Recepacket1();
void Recepacket2();
int key_pass();
int inot(void);
/**************************************************************************/
int delay2(void) //延时
{
int i;
for(i=0;i<5000;i++);
return 0;
}
/**************************************************************************/
int inot(void) //初始化
{
WDTCTL = WDTPW + WDTHOLD; //关看门狗
BCSCTL1 = CALBC1_1MHZ; //设定DCO为1MHZ
DCOCTL = CALBC1_1MHZ;
P1DIR=0x00; //将P1口所有的管脚在初始化的时候设置为输入方式
P1DIR&=~0x0f;
P1DIR|=0xf0; // 将P1.4 P1.5 P1.6 P1.7设置为输出方向
P1OUT&=~0xf0; //先输出低电平
P2DIR |= BIT3+BIT4;
P2OUT|= BIT3+BIT4;
P3DIR|=BIT6;
P3OUT= BIT6;
P4SEL=0x00;
P4DIR |=0xff; //P4输出
P4OUT =0x00;
// 将中断寄存器清零
P1IE = 0;
P1IES = 0;
P1IFG = 0;
//打开管脚的中断功能
//对应的管脚由高到低电平跳变使相应的标志置位
P1IE |= BIT0;
P1IES|= BIT0;
P1IE |= BIT1;
P1IES|= BIT1;
P1IE |= BIT2;
P1IES|= BIT2;
P1IE |= BIT3;
P1IES |= BIT3;
return 0;
}
/**************************************************************************/
void delay(long i)
{
while (i--);
}
/**************************************************************************/
// 多发射机时用二维数组
unsigned char Rxbuf0[16]={"1 "};
unsigned char Rxbuf1[16]={"2 "};
unsigned char Rxbuf2[16]={"3 "};
unsigned char Rxbuf3[16]={"up set "};
unsigned char Rxbuf4[16]={"4 "};
unsigned char Rxbuf5[16]={"5 "};
unsigned char Rxbuf6[16]={"6 "};
unsigned char Rxbuf7[16]={"down set "};
unsigned char Rxbuf8[16]={"7 "};
unsigned char Rxbuf9[16] ={"8 "};
unsigned char Rxbuf10[16]={"9 "};
unsigned char Rxbuf11[16]={" "};
unsigned char Rxbuf12[16]={"* "};
unsigned char Rxbuf13[16]={"0 "};
unsigned char Rxbuf14[16]={". "};
unsigned char Rxbuf15[16]={" "};
unsigned char Rxbuf16[16];
unsigned char Rxbuf17[16]={" OUT "};
//...............................................................................
void longdelay(long s) //长延时
{
while(s--)
{
delay(600);
}
}
void delay1(uchar ms)
{ // 延时子程序
uchar i;
while(ms--)
{
for(i = 0; i< 250; i++);
}
}
//.............................. 测试LCD忙碌状态.........................................................................................................
lcd_bz()
{
P4DIR&=~BIT7;
int result=0;
rs_0 ;
rw_1;
ep_1;
result =(result||(P4IN & 0x80));
ep_0;
P4DIR|=0xff;
return result;
}
//................................. 写入指令数据到LCD..............................................................................................................................
void lcd_wcmd(uchar cmd)
{
while(lcd_bz());
rs_0;
rw_0;
ep_0;
P4OUT = cmd;
ep_1;
ep_0;
}
//..........................设定显示位置........................................................................
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80);
}
//...........................写入字符显示数据到LCD.........................................................
void lcd_wdat(uchar dat)
{
while(lcd_bz());
rs_1;
rw_0;
ep_0;
P4OUT = dat;
ep_1;
ep_0;
}
//........................LCD初始化设定.............................................
void lcd_init()
{
lcd_wcmd(0x38); //function set
delay1(20);
lcd_wcmd(0x38); //function set
delay1(20);
lcd_wcmd(0x0f); //display on/off
delay1(20);
lcd_wcmd(0x0f); //display on/off
delay1(1);
lcd_wcmd(0x01); //清除LCD的显示内容
delay1(20);
lcd_wcmd(0x04); //entry mode set
delay1(20);
lcd_wcmd(0x04); //entry mode set
delay1(20);
}
/*---------------
函数名称:display()
功能 :在LCD上显示数组的数据
说明 :先写显示地址,后写显示数据
调用 :lcd_wcmd(), lcd_pos()
入口参数:pos 写入的位置,q指向要写入的数据所在的数组
返回值 :无
----------------*/
void display(uchar pos, uchar *q)
{
uchar i;
//lcd_wcmd(0x01); //clear
delay1(10);
lcd_pos(pos);
delay1(1);
for(i=0;i<16;i++)
{
lcd_wdat(*q);
delay1(1);
q++;
longdelay(2);
}
}
/**************************************************************************/
void Recepacket1()
{
int s,t,m,n,p,q;
s=T_c;
t=s%10;
m=(s/10)%10;
n=(s/100)%10;
p=(s/1000)%10;
q=(s/10000)%10;
Rxbuf11[14]=67;
Rxbuf11[10]=t+48;
Rxbuf11[9]=46;
Rxbuf11[8]=m+48;
Rxbuf11[7]=n+48;
Rxbuf11[6]=p+48;
Rxbuf11[5]=q+48;
Rxbuf11[1]=84;
display(0x00,Rxbuf11);
delay(20);
}
/**************************************************************************/
void Recepacket2()
{
int s,t,m,n,p,q;
s=T_h;
t=s%10;
m=(s/10)%10;
n=(s/100)%10;
p=(s/1000)%10;
q=(s/10000)%10;
Rxbuf15[14]=70;
Rxbuf15[10]=t+48;
Rxbuf15[9]=46;
Rxbuf15[8]=m+48;
Rxbuf15[7]=n+48;
Rxbuf15[6]=p+48;
Rxbuf15[5]=q+48;
Rxbuf15[1]=84;
display(0x00,Rxbuf15);
delay(20);
}
/**************************************************************************/
void up_set()
{
T_up=Rxbuf16[3]*10+Rxbuf16[2]*1+Rxbuf16[0]*0.1;
}
/**************************************************************************/
void down_set()
{
T_down=Rxbuf16[3]*10+Rxbuf16[2]*1+Rxbuf16[0]*0.1;
}
/**************************************************************************/
int key_pass() //键盘分析
{
int keyz;
int key;
key=(P1IN&0x0f);
switch(key)
{
case 0x0e:
delay2();
P1OUT |=BIT4;
if((P1IN&BIT0)==0x01)
{
delay2();keyz=0;break;
}
P1OUT |=BIT5;
if((P1IN&BIT0)==0x01)
{
delay2(); keyz=1;break;
}
P1OUT |=BIT6;
if((P1IN&BIT0)==0x01)
{
delay2(); keyz=2;break;
}
P1OUT |=BIT7;
if((P1IN&BIT0)==0x01)
{
delay2(); keyz=3;break;
}
break;
case 0x0d:
P1OUT |=BIT4;
if((P1IN&BIT1)==0x02)
{
delay2();keyz=4;break;
}
P1OUT |=BIT5;
if((P1IN&BIT1)==0x02)
{
delay2();keyz=5;break;
}
P1OUT |=BIT6;
if((P1IN&BIT1)==0x02)
{
delay2(); keyz=6;break;
}
P1OUT |=BIT7;
if((P1IN&BIT1)==0x02)
{
delay2(); keyz=7;break;
}
break;
case 0x0b:
P1OUT |=BIT4;
if((P1IN&BIT2)==0x04)
{
delay2(); keyz=8;break;
}
P1OUT |=BIT5;
if((P1IN&BIT2)==0x04)
{
delay2(); keyz=9;break;
}
P1OUT |=BIT6;
if((P1IN&BIT2)==0x04)
{
delay2(); keyz=10;break;
}
P1OUT |=BIT7;
if((P1IN&BIT2)==0x04)
{
delay2(); keyz=11;break;
}
case 0x07:
P1OUT |=BIT4;
if((P1IN&BIT3)==0x08)
{
delay2(); keyz=12;break;
}
P1OUT |=BIT5;
if((P1IN&BIT3)==0x08)
{
delay2(); keyz=13;break;
}
P1OUT |=BIT6;
if((P1IN&BIT3)==0x08)
{
delay2(); keyz=14;break;
}
P1OUT |=BIT7;
if((P1IN&BIT3)==0x08)
{
delay2(); keyz=15;break;
}
default: keyz=16;break;
}
P1OUT&=~0xf0;
delay2();
delay2();
return keyz;
}
/**************************************************************************/
// 处理来自端口 1 的中断
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
int key_pass();
int delay2(void);
delay2();
while(1)
{
int key,i;
int a[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
delay2();
i=a[k];
key=key_pass();
switch(key)
{
case 0:display(i,Rxbuf0);k++;if(k>15)k=15;Rxbuf16[r]=1;r--;if(r<0)r=0;break;
case 1:display(i,Rxbuf1); k++;if(k>15)k=15;Rxbuf16[r]=2;r--;if(r<0)r=0;break;
case 2:display(i,Rxbuf2); k++;if(k>15)k=15;Rxbuf16[r]=3;r--;if(r<0)r=0;break;
case 3:display(i,Rxbuf3);up_set();lcd_wcmd(0x01);k=0;break; //报警上限设置
case 4:display(i,Rxbuf4); k++;if(k>15)k=15;Rxbuf16[r]=4;r--;if(r<0)r=0;break;
case 5:display(i,Rxbuf5);k++;if(k>15)k=15;Rxbuf16[r]=5;r--;if(r<0)r=0;break;
case 6:display(i,Rxbuf6); k++;if(k>15)k=15;Rxbuf16[r]=6;r--;if(r<0)r=0;break;
case 7:display(i,Rxbuf7);down_set();lcd_wcmd(0x01);k=0;break; //报警下限设置
case 8:display(i,Rxbuf8);k++; if(k>15)k=15;Rxbuf16[r]=7;r--;if(r<0)r=0;break;
case 9:display(i,Rxbuf9); k++;if(k>15)k=15;Rxbuf16[r]=8;r--;if(r<0)r=0;break;
case 10:display(i,Rxbuf10);k++;if(k>15)k=15;Rxbuf16[r]=9;r--;if(r<0)r=0; break;
case 11:Recepacket2(); break; //显示华氏温度
case 12:;lcd_wcmd(0x01);k=0;r=3;break; //清除LCD的显示内容,单片机复位
case 13:display(i,Rxbuf13);k++;if(k>15)k=15;Rxbuf16[r]=0;r--;if(r<0)r=0;break;
case 14:display(i,Rxbuf14);k++;if(k>15)k=15;r--;if(r<0)r=0;break;
case 15:Recepacket1();break; //显示摄氏温度
}
if((P1IN&0x0f)==0x0f)break;
}
/****************************7***************************switch语句结束******/
if(P1IFG & BIT0)
{
P1IFG &= ~(BIT0);// 清除中断标志位
}
if(P1IFG & BIT1)
{
P1IFG &= ~(BIT1);// 清除中断标志位
}
if(P1IFG & BIT2)
{
P1IFG &= ~(BIT2);// 清除中断标志位
}
if(P1IFG & BIT3)
{
P1IFG &= ~(BIT3);// 清除中断标志位
}
}
/**************************************************************************/
void main()
{
//禁止看门狗
//延时,等待液晶电压上升,大约需要30ms
_DINT(); //禁止中断,一般在设置硬件时都要禁止中断
inot();
lcd_init();
lcd_wcmd(0x01);
delay2();
_EINT(); //打开中断
while(1)
{};
}
/**************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -