⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msp4302274_1602.c

📁 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 + -