[资料分享] 基于MSP430G2231分辨率为0.1℃普通IO口驱动LCD的温度计

l4568527193   2012-5-13 14:20 楼主
基于MSP430G2231分辨率为0.1℃普通IO口驱动LCD的温度计



                                     wenyangzeng     2012/04/30



为了降低成本,采用MSP430G2231单片机普通IO口驱动段码型LCD,本设计使用了2个中断源,在CCR0中断中顺序产生1/2Bias的COM0-COM3位码扫描信号,并通过USI-SPI功能控制1片74HC595产生8位段码信号,驱动了4位8段LCD显示屏。在CCR1中断中清零LCD显示数据,并产生ADC允许转换信号。温度传感器则利用MSP430G2231内部温度传感器,主程序检测到ADC允许转换信号后进行一次ADC转换,通过采用过采样技术,在采样10次温度值后,进行运算,得到精度达0.1℃的温度测量结果。

设计直接利用LanuchPad 实验板扩展槽,连接1片PCB板,板上焊接74HC595和LCD和COM分压电阻等。编译环境使用IAR-MSP430 for 5.40限制版,该版本将仿真窗口中变量、寄存器观察窗的显示值都屏蔽掉了,有点太吝舍了,给调试过程带来不少麻烦。



运行结果见图1。


                 



                        图1 运行结果















                     

                                               图2  原理图





附:代码

#include

#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位数字函数

//入口参数1:16位数值

//入口参数2:0-16进制/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;

  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);

  

}

回复评论 (7)

原理图怎么看不到

把图再发一遍吧 我想尝试做一下 求指导呀
点赞  2012-5-21 21:00
看看,东西有点稀奇
学习无止境,天天向上咯!!
点赞  2012-5-22 09:21
没有看到原理图呀!楼主能不能补一下!
点赞  2012-6-9 17:04
我这里怎么都不显示图的 我浏览器问题??
点赞  2012-6-9 17:07

感谢楼主

感谢楼主啊
点赞  2012-6-9 18:24
感谢楼主

感谢楼主啊
点赞  2016-8-13 04:47
感谢楼主

感谢楼主啊
点赞  2023-1-19 15:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复