This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

【MSP430 LaunchPad设计心得】基于MSP430G2231分辨率为0.1℃普通IO口驱动LCD的温度计

Other Parts Discussed in Thread: MSP430G2231
       基于MSP430G2231分辨率为0.1℃普通IO口驱动LCD的温度计
 
                                     wenyangzeng     2012/04/30
为了降低成本,采用MSP430G2231单片机普通IO口驱动段码型LCD,本设计使用了2个中断源,CCR0中断中顺序产生1/2BiasCOM0COM3位码扫描信号,并通过USI-SPI功能控制174HC595产生8位段码信号,驱动了48LCD显示屏。在CCR1中断中清零LCD显示数据,并产生ADC允许转换信号。温度传感器则利用MSP430G2231内部温度传感器,主程序检测到ADC允许转换信号后进行一次ADC转换,通过采用过采样技术,在采样10次温度值后,进行运算,得到精度达0.1℃的温度测量结果。
设计直接利用LanuchPad 实验板扩展槽,连接1PCB板,板上焊接74HC595LCDCOM分压电阻等。编译环境使用IARMSP430 for 5.40限制版,该版本将仿真窗口中变量、寄存器观察窗的显示值都屏蔽掉了,有点太吝舍了,给调试过程带来不少麻烦。

 运行结果见图1。

 

               

 
                        图1 运行结果
                     
                                               图2  原理图

附:代码
#include <msp430g2231.h>
#define setbit(var,bit)  ((var)|=(1<<(bit)))
#define clrbit(var,bit)  ((var)&=~(1<<(bit)))
unsigned char  frame[4];    /* LCD frame buffer  */
unsigned char  digit[4];    /* Digit frame buffer */ 
// LCD segment definitions (SoftBaugh SBLCDA4)
#define SEG_D   0x01                            //  AAAA
#define SEG_C   0x04                            // F    B
#define SEG_B   0x40                            // F    B
#define SEG_A   0x80                            //  GGGG
#define SEG_H   0x02                            // E    C
#define SEG_E   0x08                            // E    C
#define SEG_G   0x10                            //  DDDD
#define SEG_F   0x20
#define DIG_c   (SEG_E + SEG_G+ SEG_D)                                      // Displays 'c'
unsigned char const number[17] = {
  (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F),             // "0"
  (SEG_B | SEG_C),                                           // "1"
  (SEG_A + SEG_B + SEG_D + SEG_E + SEG_G),                  // "2"
  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_G),                  // "3"
  (SEG_B + SEG_C + SEG_F + SEG_G),                          // "4"
  (SEG_A + SEG_C + SEG_D + SEG_F + SEG_G),                  // "5"
  (SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G),          // "6"
  (SEG_A + SEG_B + SEG_C),                                  // "7"
  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G),  // "8"
  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G),          // "9"
  (SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G),          // "A"
  (SEG_C + SEG_D + SEG_E + SEG_F + SEG_G),                          // "B"
  (SEG_A + SEG_D + SEG_E + SEG_F),                          // "C"
  (SEG_B + SEG_C + SEG_D + SEG_E + SEG_G),                           // "D"
  (SEG_A + SEG_D + SEG_E + SEG_F +SEG_G),                   // "E"
  (SEG_A + SEG_E + SEG_F + SEG_G),                            // "F"
  0x00                                                       // Blank
};
long temp;
long DegC;
long IntDegC;
unsigned char Seg_Old,dispbuf[4];
unsigned char var=0,lcdcr=0,ADC_EN=0,t=0;
void display(unsigned int Number,unsigned char D_OR_H);
void main(void)
{unsigned char j=0;
  WDTCTL = WDTPW + WDTHOLD; 
  P1OUT   = 0X00;
  P1DIR   = 0xFF;
  USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE;
  USICTL1 |= USICKPH;             
  USICKCTL = USIDIV_1 + USISSEL_2;
  USICTL0 &= ~USISWRST; 
  USICNT = 8;
    CCTL0   = OUTMOD_3 + CCIE;
  CCTL1   = OUTMOD_3 + CCIE;
  TACCR0  = 200;
  TACTL   = TASSEL_2 +  MC_2 ;
  ADC10CTL1 = INCH_10 ;//+ ADC10DIV_3;        
  ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON ;
  _EINT();
  temp=0;
  for(;;)
  {
   if(ADC_EN==1)
    {  ADC_EN=0;
       ADC10CTL0 |= ENC + ADC10SC;
          while (!(ADC10IFG & ADC10CTL0));
     temp += ADC10MEM;
     j++;
     if(j==10)
     {
     IntDegC = ((temp - 673) * 423) / 1024;
     display(IntDegC,1);
     j=0;temp=0;
     }
    }
   }
}
//--------------------------------------------
// Timer A0 interrupt service routine
//-------------------------------------------
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0 (void)
{ unsigned char i;
   if(var==0)
    {
      var++;
        if(lcdcr==0)
            Seg_Old=frame[0];
        else
        if(lcdcr==1) 
            Seg_Old=frame[1];
        else
        if(lcdcr==2) 
            Seg_Old=frame[2];
        else
        if(lcdcr==3) 
            Seg_Old=frame[3];
     while (!(USIIFG & USICTL1));
      USISRL = Seg_Old;
      USICNT = 8;
          for(i=4;i>0;i--);
      P1OUT |= BIT4;
      P1OUT &=~BIT4;
      P1DIR &=~0X0F;
      clrbit(P1OUT,lcdcr);  
      setbit(P1DIR,lcdcr);
    }
  else
  {
    var=0;
     while (!(USIIFG & USICTL1));
     Seg_Old=~Seg_Old;;
      USISRL = Seg_Old;    
      USICNT = 8;
      for(i=4;i>0;i--);
      P1OUT |= BIT4;
      P1OUT &=~BIT4;
      P1DIR &=~0X0F;
      setbit(P1OUT,lcdcr); 
      setbit(P1DIR,lcdcr);
      lcdcr++;
         if (lcdcr>3) lcdcr =0;
  }
  CCR0 += 2300;                             
}
//---------------------------------------------------
// Timer_A2 Interrupt Vector (TAIV) handler
//--------------------------------------------------
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{
  switch( TAIV )
  {unsigned char i;
  case  2:
    {  t++;
      if(t==50)
      {ADC_EN=1; 
      t=0;
      }
            while (!(USIIFG & USICTL1));
            USISRL = 0x00;
            USICNT = 8;
                for(i=4;i>0;i--);
            P1OUT |= BIT4;
            P1OUT &=~BIT4;
            P1OUT &=~0x0f;   //com全为0
            P1DIR  |=0X0F;
            CCR1 += 2300;
          
            break;
          }
  case 10: break;
  }
}
//------------------------------------------------------
//显示4位数字函数
//入口参数116位数值
//入口参数2016进制/1-十进制
//-----------------------------------------------------
void display(unsigned int Number,unsigned char D_OR_H)
{ unsigned char a,b,c,d;
  if(D_OR_H==1)
  {
  a=Number%10000/1000;
  b=Number%1000/100;
  c=Number%100/10;
  d=Number%10;
  }
  else
  {  a=(Number>>12)&0x0f;
    b=(Number>>8)&0x0f;
    c=(Number>>4)&0x0f;
    d=Number&0x0f;
  }
  dispbuf[0]= DIG_c ;//number[d];
  dispbuf[1]= number[c]|SEG_H;
  dispbuf[2]= number[b];
  dispbuf[3]= number[a];
 
  frame[0]=dispbuf[0]&0x03;           
  frame[0] |=(dispbuf[1]<<2)&0x0c;
  frame[0] |=(dispbuf[2]<<4)&0x30;
  frame[0] |=(dispbuf[3]<<6)&0xc0;
 
  frame[1]=(dispbuf[0]>>2)&0x03;
  frame[1] |=(dispbuf[1]&0x0c);
  frame[1] |=(dispbuf[2]<<2)&0x30;
  frame[1] |=(dispbuf[3]<<4)&0xc0;
 
  frame[2]  =(dispbuf[0]>>4)&0x03;
  frame[2] |=(dispbuf[1]>>2)&0x0c;
  frame[2] |=dispbuf[2]&0x30;
  frame[2] |=(dispbuf[3]<<2)&0xc0;
 
  frame[3]  =(dispbuf[0]>>6)&0x03;
  frame[3] |=(dispbuf[1]>>4)&0x0c;
  frame[3] |=(dispbuf[2]>>2)&0x30;
  frame[3] |=(dispbuf[3]&0xc0);
 
}