gaobao_1 发表于 2018-5-2 13:35:19

msp430g2xx做的温度度时钟表

//******************************************************************************
#include <msp430g2452.h>
#include"LCMXX.H"
#defineCLR_R100      P2OUT &=~(BIT0)   //R100
#defineSET_R100      P2OUT |= (BIT0)
#defineCLR_R100K       P2OUT&=~(BIT1)   //100K   
#defineSET_R100K       P2OUT|= (BIT1)
#defineCLR_RT10K       P2OUT&=~(BIT2)   //T10K
#defineSET_RT10K       P2OUT|= (BIT2)
#defineCLR_fmq         P1OUT &=~(BIT1)   
#defineSET_fmq         P1OUT |= (BIT1)
unsigned char inou_t,count_s ,count_5s,time_1s,usim_js,usim_ip;//秒计时秒及1秒
unsigned char time_0_5s,implement,implement_5s;//0.5秒计时秒及程序执行标志,5秒标志
unsigned intRt_Value,Temp_Value;
unsigned charMODE,AMPM,Temper; //工作模式
unsigned chardate,hour,cent,second,time_key;
unsigned char    play_data;   //数据显示用数组(S9-S18,5d-1d)
long IntDegC;
unsigned charconst SEG7_1[]={
      0xBE,/*0*/
      0xA0,/*1*/
      0x7C,/*2*/
      0xF8,/*3*/
      0xE2,/*4*/
      0xDA,/*5*/
      0xDE,/*6*/
      0xB0,/*7*/
      0xFE,/*8*/
      0xFA,/*9*/
      0x52,/*c*/
      0x40,/*-*/
   };      

/**SEG_1为LCM045a的段码*/
unsigned int const Temp_Table1[]={3275,3430,3630,3825,4031,4245,4480,4726,4987,5265,5560,
5873,6206,6560,6938,7340,7768,8224,8711,9230,9783,10375,11006}; //-1~-22
unsigned int const Temp_Table[]={3177,3025,2882,2745,2616,2494,2377,2267,2162,2063,1968,
1878,1793,1712,1635,1562,1493,1426,1363,1304,1247,1192,1141,1091,1045,1000,958,917,878,
842,806,773,741,710,682,653,627,602,577,554,532,511,491,472,453,436,419,403,388,373,
359};//0~50度
void Rc_Ad(void);    //rc测温程序
voidbit_bcd (unsigned char Data_h,unsigned char Data_c);//时间bcd转换
voidT_bit_bcd (unsigned int ADC_data);   //转换内温度BCD码
void delay ( unsigned char time )       //长延时函数
{ unsigned charm,tk;
    do
      {
         for (m=20;m>0;m--)
          { for (tk=100;tk>0;tk--) ;}
      }
        while (--time);
}
//获取AD转换的值
long Get_ADCVal(void)
{
long tt=0;
ADC10CTL0 |= ENC + ADC10SC;               // Sampling and conversion start
_NOP();_NOP();_NOP();_NOP();
//while((ADC10CTL0 &ADC10IFG)==0);         //等待ADC10IFG标志变高(转换完成)                                   // Disable ADC conversion
//ADC10CTL0 &= ~(REFON + ADC10ON);      // Ref and ADC10 off
while (ADC10CTL1 & ADC10BUSY != 0);      //判断是否转换完毕
   tt = ADC10MEM;       
                                          // Read conversion value
return tt;
}
//获得温度值
/*void   ADC_T (void)
{ unsigned char i;
for(i=0;i<8;i++)
    IntDegC += ((Get_ADCVal() - 673) * 4230) / 1024;
   //oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
    IntDegC >>=3;
}*/
void main(void)
{ //unsigned char i;
WDTCTL = WDTPW + WDTHOLD;               // Stop WDT
   BCSCTL3=XCAP_1 ;                     //6pf
if (CALBC1_8MHZ != 0xFF)
{
   delay(2);
   DCOCTL = 0x00;
   BCSCTL1 = CALBC1_8MHZ;      /* Set DCO to 8MHz */
   DCOCTL= CALDCO_8MHZ;
}
BCSCTL2 = SELM_0 + DIVM_1+DIVS_2 ;//MCLK==>4MHZ,SMCLK==>2MHZ
//=========================
//ADC10CTL1 = INCH_10 + ADC10DIV_4;         // Temp Sensor ADC10CLK/4+CONSEQ_2
P1DIR |= 0x07;// P1.0 output
P1REN=0x30;   //p1.5,p1.6上拉
P1OUT &= 0xf0;
P2DIR |= 0x7f;
P2OUT |= 0x7f;
delay ( 10 )   ;
LCMInit();
hour=6;
cent=58;
WDTCTL = WDT_ADLY_250;   // WDT 250ms, ACLK, interval timer
IE1 |= WDTIE;            //看门狗中断使能
_EINT();                   //使能中断
while(1)
{   
      if(MODE==0)      
           { if(implement_5s)
            { if(time_1s)
               { if(usim_js>0)      //整点报时
                  {
                      usim_js--;
                      SET_fmq;
                     }   
                  Rc_Ad();   //rc充放电测电阻
                  WRLCD_4(0x15,0x00) ;    //模式指示
                  WRLCD_4(0x1f,0x20) ;    //模式指示
                  WRLCD_8(0x1d,play_data);
                WRLCD_8(0x1b,play_data);
                  WRLCD_4(0x1a,0x00) ;
                WRLCD_8(0x18,play_data);
                WRLCD_8(0x16,0x53);
                  time_1s=0;
                  implement_5s--;
                }
            }
         else if(implement)
               { if(time_1s)      //整点报时
                     { time_1s=0;
                      if(usim_js>0)
                      {
                     usim_js--;
                     SET_fmq;
                     }   
                  }
               bit_bcd(hour,cent); //调时间表
               WRLCD_4(0x15,0x00) ;    //模式指示
               WRLCD_4(0x1f,0x20) ;    //模式指示
               WRLCD_8(0x1d,play_data);
             WRLCD_8(0x1b,play_data);
               if(time_0_5s)
               {WRLCD_4(0x1a,0xf0) ;}
               else
               {WRLCD_4(0x1a,0x00) ;}
             WRLCD_8(0x18,play_data);
             WRLCD_8(0x16,play_data);
               implement=0;
                }
          }
       else if(MODE==1)// 只显示温度
      {if(time_1s)
               { if(usim_js>0)    //整点报时
                      {
                     usim_js--;
                     SET_fmq;
                     }
                     Rc_Ad();   //rc充放电测电阻
                     WRLCD_4(0x15,0x00) ;    //模式指示
                     WRLCD_4(0x1f,0x40) ;    //模式指示
                     WRLCD_8(0x1d,play_data);
                   WRLCD_8(0x1b,play_data);
                     WRLCD_4(0x1a,0x00) ;
                   WRLCD_8(0x18,play_data);
                   WRLCD_8(0x16,0x53);
                     time_1s=0;
                }
      }
       else if(MODE==2)// 只显示时钟
      {if(implement)
               {bit_bcd(hour,cent); //调时间表
               WRLCD_4(0x15,0x00) ;    //模式指示
               WRLCD_4(0x1f,0x80) ;    //模式指示
               WRLCD_8(0x1d,play_data);
             WRLCD_8(0x1b,play_data);
               if(time_0_5s)
               {WRLCD_4(0x1a,0xf0) ;}
               else
               {WRLCD_4(0x1a,0x00) ;}
             WRLCD_8(0x18,play_data);
             WRLCD_8(0x16,play_data);
               implement=0;
                  if(time_1s)
                  {   time_1s=0;
                      if(usim_js>0)
                      {
                     usim_js--;
                     SET_fmq;
                      }   
                  }
                }
         
      }
       else if(MODE==3)// 调整分钟
      {   if(implement)
                { if((P1IN&0x20)==0)
                  {cent++;second=0;}
               if(cent>=60) cent=0;
               bit_bcd(hour,cent); //调时间表
               WRLCD_4(0x15,0x80) ;    //模式指示
               WRLCD_4(0x1f,0x00) ;    //模式指示
               WRLCD_8(0x1d,play_data);
             WRLCD_8(0x1b,play_data);
               if(time_0_5s)
               {WRLCD_4(0x1a,0xf0) ;
                  WRLCD_8(0x18,play_data);
                WRLCD_8(0x16,play_data);
               }
               else
               {WRLCD_4(0x1a,0x00);
                WRLCD_8(0x18,0x00);
                WRLCD_8(0x16,0x00);
               }
               implement=0;
                }
         
      }
      else if(MODE==4)// 调整小时
      {    if(implement)
                { if((P1IN&0x20)==0)
                   {hour++;}
                   if(hour>=24) hour=0;
               bit_bcd(hour,cent); //调时间表
               WRLCD_4(0x15,0x20) ;    //模式指示
               WRLCD_4(0x1f,0x00) ;    //模式指示
               if(time_0_5s)
               { WRLCD_4(0x1a,0xf0) ;
                   WRLCD_8(0x1d,play_data);
                 WRLCD_8(0x1b,play_data);
               }
               else
               { WRLCD_4(0x1a,0x00) ;
                   WRLCD_8(0x1d,0x00);
                 WRLCD_8(0x1b,0x00);
               }
             WRLCD_8(0x18,play_data);
             WRLCD_8(0x16,play_data);
               implement=0;
                }
      }
       LPM2;   //进入低功
}

}
#pragma vector = WDT_VECTOR
__interrupt void watchdog_timer(void)
{
P1OUT ^= BIT0;   //取反,观测用
count_s++;
count_5s++;
if((P1IN&0x10)==0)    //调工作模式
{ if(MODE==4){MODE=0;}
   elseMODE++;
   if(MODE==0)
   {
   WRLCD_4(0x15,0x00) ;    //模式交替
   WRLCD_4(0x1f,0x20) ;    //模式指示
   }
   else if(MODE==1)
   {
      WRLCD_4(0x15,0x00) ;    //模式指示
      WRLCD_4(0x1f,0x40) ;    //模式温度
   }
    else if(MODE==2)
   {
      WRLCD_4(0x15,0x00) ;    //模式指示
      WRLCD_4(0x1f,0x80) ;    //模式时间
   }
    else if(MODE==3)
   {
      WRLCD_4(0x15,0x80) ;    //模式指示
      WRLCD_4(0x1f,0x00) ;    //模式调分钟
      
   }
   else if(MODE==4)
   {
      WRLCD_4(0x15,0x20) ;    //模式指示
      WRLCD_4(0x1f,0x00) ;    //模式调小时间
   
   }
}
/*if(MODE==3)                  //模式调分钟
{if((P1IN&0x20)==0)
      cent++;
      if(cent>=60) cent=0;
}
if(MODE==4)                  //模式调小时间
{ if((P1IN&0x20)==0)
      hour++;
      if(hour>=24) hour=0;
}*/
if (count_5s>19)
{
   implement_5s=5;
}
if(count_5s>39)
{
    count_5s=0;
    implement_5s=0;
}
if(count_s==2 )
{
    time_0_5s=1;         //每1秒闪烁标志
    time_1s=0;
    implement=1;      //0.5秒时间到标志执行程序用
    LPM2_EXIT;
}
if(count_s>3 )
{ count_s = 0;
    time_1s=1;
    time_0_5s=0;
    implement=1;    //0.5秒时间到标志执行程序用
    second++;
   if(second<60);   // 时钟计时开始
   else{
         second=0;
       cent++;
      if(cent<60);
      else
         {
          cent=0;
          hour++;
          if((hour>2)&&(hour<23))
         { // usim_ip=1;
            usim_js=hour;
            if(hour>12){usim_js=usim_js-12;}
            }
         if(hour<24);
         else
         hour=0;
         }
// if((P1IN&0x10)==0)    //调工作模式
//   MODE++;
// if(MODE==5)MODE=0;
      }
    LPM2_EXIT;
}

CLR_fmq;       //   
}

/****温度电阻测量*************/
void Rc_Ad(void)
{
        float T1 = 0,T2 = 0,T_Sum = 0;
        unsigned char i,flag; //温度标志位;
      unsigned intRt_Value,Temp_Value;
      TACTL = TASSEL_2 + MC_0+TACLR;    //SCLK +停止计数
        for(i=0;i<5;i++)
    {          
              P2DIR &= 0xf8;
            _NOP();_NOP();
            P2DIR |= 0x01;
            CLR_R100;          //放电
              delay(2);
              P2DIR &= 0xfe; //设置P2.0 高阻 设置p2.1为输出设置P2.2为高阻
            P2DIR |= 0x02;
            TACTL = TASSEL_2 + MC_2+TACLR;//清零并开始计数
              SET_R100K ;         //通过100K电阻对电容充电
              while(!(P2IN&0x01));//等待高电平
              TACTL = TASSEL_2 + MC_0;    //停止计数//关闭计数器
              T1 = TAR;//得到100K放电时间T1
              P2DIR &= 0xf8;
            _NOP();_NOP();
            P2DIR |= 0x01;
            CLR_R100;          //放电
              delay(2);
              P2DIR &= 0xfe; //设置P2.0 高阻 设置P2.1为高阻设置p2.2为输出
            P2DIR |=0x04;
              TACTL = TASSEL_2 + MC_2+TACLR;   //清零并开始计数
              SET_RT10K ;         //通过热敏电阻充电;
              while(!(P2IN&0x01));//等待低电平
              TACTL = TASSEL_2 + MC_0;    //停止计数//关闭计数器
              T2 = TAR;//得到热电阻放电时间T2
              T_Sum += T2/T1;
        }
        T_Sum =(T_Sum/5)*100;   //;
        Rt_Value=(unsigned int)(T_Sum*100);
      if(Rt_Value>3177)   //温度0度以下
         {   flag=1;    //温度0度以下   
             for(i=1;i<22;i++)
                {
                        Temp_Value=Temp_Table1;
                        if(Rt_Value<=Temp_Value) break;       
                }
                if(Rt_Value!=Temp_Value) i--;
               Temp_Value=i;//保存温度值
         }
        else if(Rt_Value>359)//温度50度以下
        {    flag=0;   //温度0度以上
                for(i=0;i<50;i++)
                {
                        Temp_Value=Temp_Table;
                        if(Rt_Value>=Temp_Value) break;       
                }
                if(Rt_Value!=Temp_Value) i--;
                Temp_Value=i;//保存温度值
        }
      if(flag)
      play_data=0x40;
      else
      play_data=0x00;
        play_data=SEG7_1;
        play_data=SEG7_1;
      
}
voidbit_bcd (unsigned char Data_h,unsigned char Data_c)   //转换时间_BCD码
{          
       play_data= SEG7_1;
       play_data= SEG7_1;
       play_data= SEG7_1;
       play_data= SEG7_1;
}
voidT_bit_bcd (unsigned int ADC_data)   //转换内温度码
{   
       play_data= SEG7_1;
       play_data= SEG7_1;
       play_data= SEG7_1;
}

lisingch 发表于 2018-5-2 16:19:32

楼主配上电路图多好。

gaobao_1 发表于 2018-5-3 17:58:31

好的,就是传电路不太好传

gaobao_1 发表于 2018-5-3 18:13:46

lisingch 发表于 2018-5-2 16:19
楼主配上电路图多好。

电路板照片

gaobao_1 发表于 2018-5-3 18:38:46

传图实在太费事了

gaobao_1 发表于 2018-5-3 18:41:07

有时间再画原理图传上

gaobao_1 发表于 2018-5-3 18:41:07

有时间再画原理图传上

gaobao_1 发表于 2018-5-3 18:41:07

有时间再画原理图传上

gaobao_1 发表于 2018-5-3 19:16:52

gaobao_1 发表于 2018-5-3 18:41
有时间再画原理图传上

手画的,其实看程序也能自己想出来

gaobao_1 发表于 2018-5-3 19:40:16

实物正反面,蜂鸣器用于整点报时,可加可不加

了无 发表于 2018-5-3 21:40:36

支持折腾,谢谢分享,最近在做点阵电子钟,板子刚打烊回来

了无 发表于 2018-5-3 21:40:36

支持折腾,谢谢分享,最近在做点阵电子钟,板子刚打烊回来

gaobao_1 发表于 2018-5-4 08:32:57

/*LCMXX系列液晶显示器的子程序 2017/12/21 gao v1.2*/
#include <msp430g2452.h>
#include"LCMXX.H"
/***********************延时***/
void delay_lcm ( uchar t)   //延时函数
{
   do{
      _NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
      _NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
   }while(--t) ;   //
}

#define del_nop(){_NOP();_NOP();_NOP();_NOP();}

/**************************************************/
void waddr (unsigned charaddr)   /*写地址1 ,0,1,a5,a4,a3,a2,a1,a0*/
{
unsigned char i;
addr=addr|0x40;
      CLR_WR;               //1clk   1
        SET_DA;
        del_nop();
        SET_WR;
        del_nop();
for(i=8;i>0;i--)
    {
      CLR_WR;
      if(addr&0x80)
      SET_DA;
      else
      CLR_DA;
      addr=addr<<1;
      del_nop();
      SET_WR;
      del_nop();
    }
}
/**************************************************/
void wdata (unsigned charDBIT)   /*写一个字节数据*/
{
unsigned char i;
for(i=8;i>0;i--)
    {
       CLR_WR;
       if(DBIT&0x80)
       SET_DA;
       else
       CLR_DA;
       DBIT<<=1;               //_crol_(DBIT,1);
       del_nop();
       SET_WR;
       del_nop();
    }
}

/*****************************************************/
void wdata_4 (unsigned char BBIT)   //写半个字节数据
{
unsigned char i;
for(i=4;i>0;i--)
    {
       CLR_WR;
       if(BBIT&0x80)
       SET_DA;
       else
       CLR_DA;
       BBIT<<=1;                   //_crol_(DBIT,1);
       del_nop();
       SET_WR;
       del_nop();
    }
}
/*****************************************************/
void wrcoom (unsigned char coom)   /*写命令*/
{
unsigned char i;
         CLR_CS;
         del_nop();
         CLR_WR;                  //1clk1
         _NOP();_NOP();
       SET_DA;
       del_nop();
       SET_WR;
       del_nop();
       CLR_WR;                            //2clk0
         _NOP();_NOP();;
       CLR_DA;
       del_nop();
       SET_WR;
       del_nop();
       CLR_WR;
         _NOP();_NOP();
         CLR_DA;                     //3clk0
       del_nop();
       SET_WR;
for(i=8;i>0;i--)
    {
           CLR_WR;
         if(coom&0x80)
         SET_DA;
         else
         CLR_DA;
         coom<<=1;                //_crol_(coom,1);
         del_nop();
         SET_WR;
           del_nop();
    }
      CLR_WR;
      CLR_DA;
      del_nop();
      SET_WR ;
      SET_CS; del_nop();
}
/************LCMXX初始化**********************/
voidLCMInit(void)
{uchar i;
SET_CS;
SET_DA;
SET_WR;
delay_lcm(5);      //延时30us以上
CLR_CS;
delay_lcm(5);
SET_CS;
delay_lcm(5);
CLR_CS;
delay_lcm(5);
SET_CS;
delay_lcm(5);
CLR_CS;
_NOP();         //初始化
wrcoom(0x29);
_NOP();      //定义内部RC
wrcoom(0x18);
_NOP();
_NOP();      //开振荡
wrcoom(0x01);
_NOP();
_NOP();       //开显示
wrcoom(0x03);
_NOP();
CLR_CS;
waddr(0x00);      //清显示屏
for (i=16;i>0;i--)
          {
      wdata(0x00);
          }
SET_CS;
}
/*************写数组到液晶显示器*********************/

/****写一个地址数据数据位在高 D0D1D2D3,0000****/
void WRLCD_4(uchar ADDR,uchar da)
{
      CLR_CS;
      waddr(ADDR);
      wdata_4(da);
      SET_CS;
      SET_DA;
}
/**********写二个地址数据 数据位D0D1D2D3,D0D1D2D3***********/

void WRLCD_8(uchar ADDR,uchar da)
{
      CLR_CS;
      waddr(ADDR);
      wdata(da);
      SET_CS;
      SET_DA;
}

gaobao_1 发表于 2018-5-4 08:33:56

#ifndef __LCMXX
#define __LCMXX         
#define uintunsigned int
#define uchar unsigned char   //
#defineCLR_CS       P2OUT&=~(BIT3)   //LCS
#defineSET_CS       P2OUT|= (BIT3)
#defineCLR_WR       P2OUT&=~(BIT4)   //LWR   
#defineSET_WR       P2OUT|= (BIT4)
#defineCLR_DA       P2OUT&=~(BIT5)   //LDA
#defineSET_DA       P2OUT|= (BIT5)
extern void delay_lcm ( uchar t ) ;
extern voidLCMInit(void);
extern void wrcoom(unsigned charcoom);
extern void wdata (unsigned charDBIT);
extern void waddr (unsigned charaddr);
//extern void WRLCD_N(uchar ADDR,uchar n ,uchar data *dp);
extern void WRLCD_4(uchar ADDR,uchar da) ;
extern void WRLCD_8(uchar ADDR,uchar da);
#endif

gaobao_1 发表于 2018-5-4 08:35:38

不知为什么打包发不了,只能分开发,好在内容不多

grj0719 发表于 2018-5-4 08:50:29

楼主动手能力不错,430的IO应该提供上拉电阻的,自己动手搭,简单点好。
好像楼主温度是用线性的公式计算的吧? 和指数函数算出来在100度相差多少呢?
这个MCU内部信息存储器提供内部温度传感器的校准数据吗?

命运号角 发表于 2018-5-4 08:57:33

支持一下

gaobao_1 发表于 2018-5-4 09:04:01

温度测量用的是RC充电法误差不大,内部温度没用。看门狗做的时钟定时器

lisingch 发表于 2018-5-4 10:34:58

gaobao_1 发表于 2018-5-3 19:16
手画的,其实看程序也能自己想出来

谢谢楼主!这样配合程序方便学习。

go2deathward 发表于 2018-5-4 12:37:05

g2452,用过好久

wintelboy 发表于 2018-5-16 21:08:25

不错不错
页: [1]
查看完整版本: msp430g2xx做的温度度时钟表