// Very precise thermometer 3_2 - 16_March_2021 #include "msp430G2553.h" #include "math.h" #define Clear 0x00 #define D3 BIT7 #define D4 BIT2 #define D5 BIT3 #define D6 BIT4 #define D7 BIT5 #define RS BIT0 #define EN BIT1 int array_div_mod[4]; float medo[10],medi[10]; long temp, IntDegC; int Int_out_temp,Int_in_temp,data,delay,select_function; int i,tenthso,unitso,decimal1o,decimal2o,tenthsi,unitsi,decimal1i,decimal2i; float int_val_c,ext_val_c,int_val,out_val; float convert_int_temp(float); float convert_ext_temp(float); float bucla_div_mod(float); void move_cursor_xy(int,int); void configure_lcd(int); void ADC_sampling(int); void ADC_convert(int); void ADC_average(int); void ADC_div_mod(int); void display_char(unsigned char); int delay_time(int); int delay_long(int); void main(void){ WDTCTL = WDTPW + WDTHOLD; // disable watch dog timer P1DIR = 0xE7; P2DIR = 0xFF; P3DIR = 0xF8; // 1111 1000 P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; select_function = 0x00; DCOCTL = CALDCO_16MHZ; // set internal oscillator at 16MHz BCSCTL1 = CALBC1_16MHZ; // set internal oscillator at 16MHz //--------------------config backlight PWM P3SEL |= (BIT3); // P3.3 Select as TA1 output TA1CCR0 = 5000; TA1CCR2 = (2500); TA1CCTL2 |= OUTMOD_7; //toggle TA1CTL |= TASSEL_2 + MC_1 +ID_3; //smclk div/8 upmode. ADC10CTL1 |= CONSEQ1 + INCH_5; //continuous sample mode, CH5 ADC10CTL0 |= ADC10SHT_2 + ADC10ON + MSC; //sample and hold time, adc on, cont. sample ADC10AE0 |= 0x20; // select channel A5 ADC10CTL0 |= ADC10SC + ENC; // start conversions delay_time(delay); delay = 5000; configure_lcd(1); move_cursor_xy(1,1); display_char('T'); display_char('-'); display_char('e'); display_char('x'); display_char('t'); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(0xDF); display_char('C'); move_cursor_xy(1,2); display_char('T'); display_char('-'); display_char('i'); display_char('n'); display_char('t'); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(' '); display_char(0xDF); display_char('C'); for(;;) { ADC_sampling(0); ADC_convert(0); ADC_average(0); ADC_div_mod(0); //-----------------------------------------------------selectare functie si canal conversie if ( P1IN >= 0x05 ){ if (( P1IN == 0x08) && ( select_function > 0x01 )){ select_function = select_function - 1; delay_time(delay); move_cursor_xy(6,1); display_char('.'); move_cursor_xy(6,2); display_char(' '); } if (( P1IN == 0x10 ) && ( select_function < 0x02 )){ select_function = select_function + 1; delay_time(delay); move_cursor_xy(6,1); display_char(' '); move_cursor_xy(6,2); display_char('.'); } } move_cursor_xy(8,1); if (out_val < 0){ display_char('-'); } else{ display_char(' '); } display_char(tenthso + 0x30); delay_time(delay); display_char(unitso + 0x30); delay_time(delay); display_char('.'); delay_time(delay); display_char(decimal1o + 0x30); delay_time(delay); display_char(decimal2o + 0x30); move_cursor_xy(8,2); if (int_val < 0){ display_char('-'); } else{ display_char(' '); } display_char(tenthsi + 0x30); delay_time(delay); display_char(unitsi + 0x30); delay_time(delay); display_char('.'); delay_time(delay); display_char(decimal1i + 0x30); delay_time(delay); display_char(decimal2i + 0x30); move_cursor_xy(33,2); delay_long(delay); delay_long(delay); } } //--------------------------------------------------------------------------------------------------------------------------------------- //----------------- FUNCTIONS ----------- PROCEDURES ----------- FUNCTIONS ----------- PROCEDURES ----------- FUNCTIONS ------- //--------------------------------------------------------------------------------------------------------------------------------------- void ADC_sampling(int){ //--------------------------------- Sample the ADC ports for values //-------------------------------------------------read interior temp ADC10CTL1 &= ~(INCH_0); //disable continuous sample mode, CH0 ADC10CTL1 |= INCH_5; //continuous sample mode, CH5 ADC10AE0 |= 0x20; // select channel A5 //0010 0000 ADC10CTL0 |= ADC10SC + ENC; // start conversions delay_time(50); Int_in_temp = ADC10MEM; ADC10CTL0 &= ~(ADC10SC + ENC); // stop conversions //-------------------------------------------------read exterior temp ADC10CTL1 &= ~(INCH_5); //disable continuous sample mode, CH5 ADC10CTL1 |= INCH_0; //continuous sample mode, CH0 ADC10AE0 |= 0x01; // select channel A0 //0000 0001 ADC10CTL0 |= ADC10SC + ENC; // start conversions delay_time(50); Int_out_temp = ADC10MEM; ADC10CTL0 &= ~(ADC10SC + ENC); // stop conversions } void ADC_convert(int){ //---------------------------------- Convert the sampled values int_val_c = convert_int_temp(Int_in_temp); ext_val_c = convert_ext_temp(Int_out_temp); } void ADC_average(int){ //----------------------------- Average last 5 samples for all measurements for(i=0; i<9; i++){ medo[i] = medo[i+1]; medi[i] = medi[i+1]; } medo[9] = ext_val_c; medi[9] = int_val_c; int_val = ((medi[0]+medi[1]+medi[2]+medi[3]+medi[4]+medi[5]+medi[6]+medi[7]+medi[8]+medi[9])/10); out_val = ((medo[0]+medo[1]+medo[2]+medo[3]+medo[4]+medo[5]+medo[6]+medo[7]+medo[8]+medo[9])/10); } float bucla_div_mod(float ref_temp_val){ //---------------------------- Loop for div/mod ------------ unsigned char j; if (ref_temp_val < 0){ ref_temp_val = (ref_temp_val * (-1)); } for(i=0; i<4; i++){ array_div_mod[i] = Clear; } for(j=0; j<4; j++){ if(j > 0){ ref_temp_val = ref_temp_val*10; } for(i=0; i<10; i++){ if ( ref_temp_val >= 10 ){ ref_temp_val = ref_temp_val - 10; array_div_mod[j] ++; } } } return (int)(array_div_mod); } float convert_int_temp (float IntBtemp){ // ------------------------Interior temp conversion float temperature,Ua1,r1_tb,r2_tb,t2k,rdiv; rdiv = 10020; r1_tb = 9980; Ua1 = (3.24/1024*IntBtemp); r2_tb = (3.24*rdiv/Ua1-rdiv); //r2 = vcc*rdiv/uADCin -rdiv if (r2_tb == r1_tb ){ r2_tb++;} // prevents log(1) t2k= ( (298.16*3380)/log(r1_tb/r2_tb) ) / (3380/log(r1_tb/r2_tb)-298.16); //T2= T1*B/ln(R1/R2) / ( B/ln(R1/R2) - T1 ) in Kelvin temperature = ((t2k - 273.16)-1.7); //konstant correction return (float)(temperature); } float convert_ext_temp(float ExtBtemp){ // ------------------------Exterior temp conversion float Etemperature,EUa1,Er1_tb,Er2_tb,Et2k,Erdiv; Erdiv = 10000; Er1_tb = 10050; EUa1 = (3.3/1024*ExtBtemp); Er2_tb = (3.3*Erdiv/EUa1-Erdiv); //r2 = vcc*rdiv/uADCin -rdiv if (Er2_tb == Er1_tb ){ Er2_tb++;} // prevents log(1) Et2k= ( (298.16*3380)/log(Er1_tb/Er2_tb) ) / (3380/log(Er1_tb/Er2_tb)-298.16); //T2= T1*B/ln(R1/R2) / ( B/ln(R1/R2) - T1 ) in Kelvin Etemperature =(Et2k - 273.16); return (float)(Etemperature); } void ADC_div_mod(int){ //------------------------------ Loop for div/mod exterior Values bucla_div_mod(out_val); tenthso = array_div_mod[0]; unitso = array_div_mod[1]; decimal1o = array_div_mod[2]; decimal2o = array_div_mod[3]; //----------------------------- Loop for div/mod interior Values bucla_div_mod(int_val); tenthsi = array_div_mod[0]; unitsi = array_div_mod[1]; decimal1i = array_div_mod[2]; decimal2i = array_div_mod[3]; } void display_char(unsigned char ch){ volatile unsigned char temp; temp = ch; P2OUT = RS ; // R/W = 0 (write mode) RS = 1 (data) delay_time(delay); ch = ch >> 4; ch = ch << 2; P2OUT |= ch; // data char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT = RS ; // Enable = 0 delay_time(delay); ch = temp; ch &= 0x0F; ch = ch << 2; P2OUT |= ch; // data char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~( EN ) ; // Enable = 0 delay_time(delay); } int delay_time (int delay){ //-------------------------- delay--------------------- do delay--; while (delay != 0); return (int)(delay); } int delay_long (int){ // -------------------------- Delay lung------------- int j; j = 200; do{ delay_time(delay); j--; }while (j != 0); return (int)(delay); } void configure_lcd(int){ //-----------------------------LCD-SET-AND-CONFIGURE--------------------------------------- P2OUT = (D3 + D4 + D5); // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = (D3 + D4 + D5); // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = (D3 + D4 + D5); // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); //------------------------------------------------------------------------- P2OUT = D5; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> move right/ shift off delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = D5; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> move right/ shift off delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = D7; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> move right/ shift off delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = Clear; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> move right/ shift off delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = (D7 + D6); // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> move right/ shift off delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = Clear; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> display/ cursor/ blinking delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = (D7 + D6 + D5 + D4); // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> display/ cursor/ blinking delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = Clear; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = D4; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = Clear; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); P2OUT = D4; // comand xxxxxxxxxxxxxxxxxxxx 110000 means >> 8bit, 2lines, 5x8pixel char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~(EN); // Enable = 0 delay_time(delay); } void move_cursor_xy (int x,int y){ // --------------------------------------- Display procedure ------------ unsigned char adress; // volatile to prevent optimization unsigned char temp; // volatile to prevent optimization x = x - 1; y = y - 1; adress = (128 + x + (64 * y)); temp = adress; P2OUT = Clear ; // R/W = 0 (write mode) RS = 1 (data) delay_time(delay); adress = adress >> 4; adress = adress << 2; P2OUT |= adress; // data char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT = Clear ; // Enable = 0 delay_time(delay); adress = temp; adress &= 0x0F; adress = adress << 2; P2OUT |= adress; // data char delay_time(delay); P2OUT |= EN; // Enable = 1 delay_time(delay); P2OUT &= ~( EN ) ; // Enable = 0 delay_time(delay); }