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

📄 msp430dayii_democ.c

📁 MSP430 RTC temperature compensation
💻 C
📖 第 1 页 / 共 2 页
字号:
    getTemp();
    displayTemp();
  } 
  while( (~P2IN & PB_TEMP) && (~P2IN & PB_ALT) ); // pause until user stops holding down buttons
  tempModeTime = 0;
  P2IFG = 0;
  P2IE |= PB_TEMP + PB_ALT;           // Enable interrupts for switches
 
  flash_erase((void *)&Refcal_flash);   // Erase Flash INFO segment A
  flash_write((void *)&Refcal_flash, Refcal_ram);// Write cal data to Refcal
  flash_write((void *)&Temp_offset, Temp_offset_ram);// Write offset data
  flash_write((void *)&Temp_slope, Temp_slope_ram);// Write slope data
  
  _EINT();                              // Re-enable general interrupts
  
  Refcal_ram = Refcal_flash;            // Make RAM copy of Vref cal value
  Temp_slope_ram = Temp_slope;          // Make RAM copy of Temp slope value
  Temp_offset_ram = Temp_offset;        // Make RAM copy of Temp offset value

}

void getTemp(void)
{
  ADC12CTL0 &= ~ENC;                    // Clear ENC first
  ADC12CTL0 = SHT0_15 + REFON + ADC12ON;
  ADC12MCTL0 = INCH_10 + SREF_1;        // Sample channel 10 using internal reference
  #if !defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
  TACTL = TASSEL0 + TACLR + MC1;        // TACLK = ACLK, 16-bit up-mode
  #endif
  CCR1 = 1500;                          // Delay to allow Ref to settle
  CCTL1 = CCIE;                         // Compare-mode interrupt
  LPM3;                                 // Wait for delay
  ADC12CTL0 |= ENC + ADC12SC;           // Start conversion
  LPM3;                                 // Wait for conversion completion
  ADC12CTL0 &= ~ENC;                    // Clear ENC first
  ADC12CTL0 = 0;                        // Turn-off ADC12
    
  tempF = (((long) ADC12MEM0 * Temp_slope_ram) / 4096 - Temp_offset_ram); 
}

void displayTemp(void)
{
  clearLCD();
  
  if( unitMode == ENGLISH )
  {
    displayValue(tempF, 2);
    LCDM7 = char_gen[15];               // Display "F' 
    LCDM6 = char_gen[13];               // Display degree
  }
  else
  {
//  tempF -= 32;
//  tempF *= .5555;                     // 5/9 using floating point - uses lots of code
//  displayValue(tempF, 2);

    // Using *5/9 is much cheaper in terms of code bytes then * 0.5555
    int tempC = tempF - 32;
    tempF *= 5;                         // Convert from 'F to 'C by scaling by 5/9
    tempF /= 9;
    displayValue(tempC, 2);
        
    LCDM7 = char_gen[12];               // Display "C"
    LCDM6 = char_gen[13];               // Display degree
  } 
}

void displayTime(void)
{
  LCDM7 = 0;
    
  LCDM6 = char_gen[seconds&0x0f];
  LCDM5 = char_gen[(seconds>>4)&0x0f]+char_gen[16];
    
  LCDM4 = char_gen[minutes&0x0f];
  LCDM3 = char_gen[(minutes>>4)&0x0f]+char_gen[16];
    
  LCDM2 = char_gen[hours&0x0f];
  if( hours & 0x10 )
  {
    LCDM1 = char_gen[1];
  }
  else
  {
    LCDM1 = 0;
  }
}

void displayValue( int value, int stop )
{
  int i;
  int sign = 0;
  if( value < 0 )
  {
    value = ~value +1;
    sign = 1;
  }
  i = 6-stop;
  while( value > 9 )
  {
    LCD[i] = char_gen[value%10];
    value = value/10;
    i--;
  }
  LCD[i] = char_gen[value];
  if( sign )
  {
    LCD[i-1] = char_gen[17];
  }
}

void incHours (void)
{    
  hours = __bcd_add_short(hours, 0x01);
  
  if (hours == 0x13)
    hours = 0x01;                       // If hrs transition is 12 to 13, hrs = 1

}

void incMinutes(void)
{    
  minutes = __bcd_add_short(minutes, 0x01);
  if (minutes == 0x60)
  {
    minutes = 0;
    incHours();
  }  
}

void decMinutes(void)
{
  if( (--minutes & 0x0f) == 0x0f )
  {
    minutes = (minutes & 0xf0)+0x09;
    if( minutes == 0xf9 )
    {
      minutes = 0x59;
      if( --hours == 0x00)
      {
        hours = 0x12;
      }
      else if( hours == 0x0f )
      {
        hours = 0x09;
      }
    }
  }

}


void clearLCD(void)
{
  int i;
  for( i = 0; i < 20; i++ ){
    LCD[i] = 0;
  }
}

void changeUnitMode(void)
{

  unitMode ^= 1;                        // Toggle between 1 and 0
  clearLCD();
  if(unitMode == METRIC)
  {
    LCDM7 = char_gen[12];               // Display degrees C for indication
    LCDM6 = char_gen[13];
  }
  else
  {
    LCDM7 = char_gen[15];               // Display degrees F for indication
    LCDM6 = char_gen[13];
  }
}


void flash_write(word* address, int data)// Write the (integer) data to the addressed flash
{ 
  word gie = _BIC_SR(GIE) & GIE;        // Disable interrupts

  FCTL3 = FWKEY;                        // Unlock the flash
  FCTL1 = FWKEY + WRT;                  // Enable flash write
  *address = data;                      // Write the data to the flash
  FCTL1 = FWKEY;                        // Disable flash write
  FCTL3 = FWKEY + LOCK;                 // Lock the flash
  _BIS_SR(gie);                         // Restore interrupts (to previous state)
}

void flash_erase(word* address)         // Erase the addressed flash segment
{
  word gie = _BIC_SR(GIE) & GIE;        // Disable interrupts
  
  FCTL3 = FWKEY;                        // Unlock the flash
  FCTL1 = FWKEY + ERASE;                // Enable flash segment erase
  *address = 0;                         // Erase the flash segment
  FCTL1 = FWKEY;                        // Disable flash segment erase
  FCTL3 = FWKEY + LOCK;                 // Lock the flash
  _BIS_SR(gie);                         // Restore interrupts (to previous state)
}

// Basic Timer interrupt service routine
#pragma vector=BASICTIMER_VECTOR
__interrupt void bt_isr(void)
{ 
 #if !defined (OPTION_USING_TIMERA_3_FOR_RTC)
  seconds = __bcd_add_short(seconds, 0x01);
  if( seconds == 0x60 )
  {
    seconds = 0;
    minutes = __bcd_add_short(minutes, 0x01);
    if( minutes == 0x60 )
    {
      minutes = 0;
      hours = __bcd_add_short(hours, 0x01);
      if( hours == 0x13 )
      {
        hours = 0x01;
      }
    } 
  }

  LPM3_EXIT;                            // Exit LPM3 mode on return
 #endif
}


#pragma vector=PORT2_VECTOR
__interrupt void p2_isr(void)
{ unsigned volatile int i;

  for (i = 0x3000; i>0 ; i--);          //Debounce
  
  if( (~P2IN & PB_TEMP)&&(P2IFG&PB_ALT) )//If temp button held, and alt button pressed...
  {
    incMinutes();
    tempModeTime = 0;
    displayTime();
    P1OUT &= ~0x01;
  }
  else if( (~P2IN & PB_ALT)&&(P2IFG&PB_TEMP) )//If alt button held, and temp button pressed...
  {

    unitMode ^= 1;                      // Toggle between 1 and 0
    incHours();
    displayTime();
    tempModeTime = 0;
    P1OUT &= ~0x01;
    held_down = 0;
  }
  else if ( tempModeTime > 0 && P2IFG & PB_TEMP ){
    LCDCTL &= ~LCDON;
    lcdOffModeTime = LCD_OFF_TIME;
    tempModeTime = 0;
  }
  else if( P2IFG & PB_TEMP )            // If temp button pressed, start displaying temp
  {         
    tempModeTime = MODE_TIME;
  }
  
  else if ( P2IFG & PB_ALT )            // If alt button pressed, toggle degrees C & F
  {        
    changeUnitMode();
  }
  
  P2IFG = 0;
}

#pragma vector=ADC_VECTOR
__interrupt void adc_isr(void)
{
  ADC12IFG &= ~BIT0;                    // Clear MEM0 interrupt flag
  LPM3_EXIT;                            // The ADC value is available in ADC12MEM0
}

enum
{
  NO_INT = 0,
  CC1_INT = 2,
  CC2_INT = 4,
  TA_INT = 10
};

#if !defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
#pragma vector=TIMERA1_VECTOR
__interrupt void ta1_isr(void)
{
  switch (TAIV)
  {
    case NO_INT: break;
    case CC1_INT: TACTL = 0; break;     // Disable TimerA
    case CC2_INT: break;
    case TA_INT: break;
    default: break;
  }
  LPM3_EXIT;                            // Exit LPM3 on return
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -