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

📄 timedatetemp.c

📁 用msp4301F122通过led显示年、月、日
💻 C
📖 第 1 页 / 共 2 页
字号:
      if(sleepcount >= 15360) { // 512 Hz * 30 seconds = 15360 cycles
        awake = FALSE;  // system sleeps after 15 seconds
        autowakecount = 0; //reset auto wake clock
        P1OUT = 0x00;  // turn off analog system
        P2OUT = 0x00;
        P3OUT = blank;
        CCR0 = 32767; // slow to 1 Hz interrupt speed
      }
    }
    else sleepcount = 0;
  }

  // Push Button Debounce - run at 32 Hz
  if(awake) {
    if((P1IN & 0xC0) == 0x40) { // P1.7 = TOGGLE
      sleepcount = 0;
      if((mainstate == SET_HOUR) | (mainstate == SET_MIN) |
         (mainstate == SET_MONTH) | (mainstate == SET_DAY) |
         (mainstate == SET_YEAR)) {
        toggle_count++;
        if(toggle_count >= 80) { // update button held for 80/512 seconds
          toggle_count = 0;
          buttonpress = 1;  // send another button press signal
        }
      }
      if((mainstate == SHOW_TIME) | (mainstate == SHOW_DATE) |
         (mainstate == SHOW_YEAR) | (mainstate == SHOW_TEMP)) {
        toggle_count++;
        if(toggle_count >= 1024) {  // 2 second hold
          toggle_count = 0;
          togglestate = mainstate;
          mainstate = AUTO_TOGGLE;
          if(togglestate == SHOW_TEMP) {
            if(temp_type)
              togglestate = SHOW_TEMP_F;
            else togglestate = SHOW_TEMP_C;
          }
        }
      }
    }
    else if((P1IN & 0xC0) == 0x80) { // P1.6 = MODE
      sleepcount = 0;
    }
    else P1IFG = 0x00; // Button Released  
  }

  // Display a digit - run at 512 Hz
  if(awake) { // runs only if system is awake
    display();
    LPM3_EXIT;
  }
  else {  // clear LEDs and shut down analog since system is sleeping
    P1OUT = 0x00;
    P2OUT = 0x00;
    P3OUT = blank;
  }
}


// System Clock - runs at 1 Hz
void clocktick(void)
{
  sec++;

  // update minutes
  if(sec >= SEC_PER_MIN) {
    sec = 0;
    min++;
    if ((min == 20) || (min == 40) || (min == 60)) {
      autowakecount = 0;
      toggle_count = 0;
      sleepcount = 0;
      awake = TRUE;  // system wakes up - auto wake
      P1OUT = 0x18;  // turn on analog system
      CCR0 = 63; // return to 512 Hz interrupt speed
    }
  }
  // update hours
  if(min >= MIN_PER_HR) {
    min = 0;
    hour++;
    if(hour == 12) {
      ampm ^= 0x01;
      if(!ampm) {
        day++;
      }
    }
  }
  if(hour > 12) {
    hour = 1;
  }
  // update days
  // February update
  if((year % 4) == 0) {  // leap year
    if((month == FEB) && (day > 29)) {
      day = 1;
      month++;
    }
  }
  else {  // non leap year
    if((month == FEB) && (day > 28)) {
      day = 1;
      month++;
    }
  }
  // 30 day month update
  if(((month == APR) || (month == JUN) || (month == SEP) || (month == NOV)) && (day > 30)) {
    day = 1;
    month++;
  }
  // 31 day month update
  if(day > 31) {
    day = 1;
    month++;
  }
  // update year
  if(month > DEC) {
    month = 1;
    year++;
  }
  // reset year when max is reached
  if(year >= MAX_YEAR) {
    year = MIN_YEAR;
  }
}


// initialize ports, Timer A0 and variables - run once at start
void initialize(void)
{
  WDTCTL = WDTPW + WDTHOLD;    // Stop watchdog timer
  TACTL = TASSEL_1 + TACLR;    // ACLK, clear TAR
  CCTL0 = CCIE;                // CCR0 interrupt enabled
  CCR0 = 63;                   // TimerA interupts at 512 Hz

  digcount = 0;  // reset digit buffer
  dig1 = 0;
  dig2 = 0;
  dig3 = 0;
  dig4 = 0;

  clock_count = 0;  // reset clock vars
  sec = 0;                             
  min = 0;
  hour = 12;
  ampm = 0;
  
  month = JAN;   // reset date vars
  day = 1;
  year = MIN_YEAR;

  mainstate = SHOW_TIME;   // reset state machines
  togglestate = SHOW_TIME;
  buttonpush = NOPUSH;
  buttonpress = 0;
  toggle_count = 0;
  toggletimer = 0;
  awake = TRUE; // system is awake
  sleepcount = 0;
  autowakecount = 0;
  
  timer = 0;  // initialize blinking functionality
  blink = 0;
  
  temp = 0;  // set temp output
  data = 0;
  temp_type = 1;
  temp_count = 0;
  temp_done = 0;                 

  P1DIR = 0x3F; // Set I/O ports
  P2DIR = 0xFF;
  P3DIR = 0x7F;
  
  P1IES = 0xC0;
  P1IFG = 0x00;
  P1IE = 0xC0;
  P1OUT = 0x18;  // Turn A/D off
  
  TACTL |= ID_0;
  TACTL |= MC_1;   // Start Timer_a in upmode
  _EINT();         // Enable interrupts
}  


// Fill 4-digit buffer - runs continuously
void fillbuffer(void)
{
  unsigned int counter;
  
  // determine clock digits
  if((mainstate == SHOW_TIME) || (mainstate == SET_HOUR) || (mainstate == SET_MIN) ||
     ((mainstate == AUTO_TOGGLE) && (togglestate == SHOW_TIME))) {
    dig1 = hour / 10;                 
    dig2 = hour % 10;
    dig3 = min / 10;
    dig4 = min % 10;
          
    if(ampm)  // AM/PM lights
      P1OUT = 0x1F;
    else P1OUT = 0x1B;
  }
  // determine date digits
  else if ((mainstate == SHOW_DATE) || (mainstate == SET_MONTH) || (mainstate == SET_DAY) ||
           ((mainstate == AUTO_TOGGLE) && (togglestate == SHOW_DATE))) {
    dig1 = month / 10;
    dig2 = month % 10;
    dig3 = day / 10;
    dig4 = day % 10;
    
    P1OUT = 0x1A;
  }
  // determine year digits
  else if ((mainstate == SHOW_YEAR) || (mainstate == SET_YEAR) ||
           ((mainstate == AUTO_TOGGLE) && (togglestate == SHOW_YEAR))) {
    dig1 = year / 1000;
    dig2 = (year / 100) % 10;
    dig3 = (year / 10) % 10;
    dig4 = year % 10;
    
    P1OUT = 0x18;
  }
  // determine temp digits
  else if ((mainstate == SHOW_TEMP) || ((mainstate == AUTO_TOGGLE) && (togglestate >= SHOW_TEMP))) {
    if(!temp_done) { // update temp once per second
      data = 0;
      P1OUT &= 0x17;  // Turn A/D on
      for(counter = 10; counter > 0;)
      {
        data = data << 1;
        if((P3IN & 0x80) == 0x80) // P3.7 = A/D temp input
        {
          data |= 0x01;
        }
        counter--;
        P1OUT |= 0x20;  // send a clock tick to A/D converter
        P1OUT &= 0x17;
      }
      P1OUT &= 0x1F;  // Turn A/D off

      if(data <= 712)
        temp = temp_array[0][temp_type];
      else if (data <= 820) {
        temp = temp_array[(data-712)/4][temp_type];
        if(temp_type)
          temp += ((data-2)%4) * 6;
        else temp += ((data-2)%4) * 3;
      }
      else if (data != 1023) {
        temp = temp_array[27][temp_type];
      }

      temp_done = 1;  // temp recorded
    }
    
    // Fill Temperature Buffer
    dig1 = temp / 100;
    dig2 = (temp / 10) % 10;
    dig3 = temp % 10;
    
    if(temp_type)
      dig4 = 10;  // display Fahrenheit
    else dig4 = 11;  // display Celcius
    
    P1OUT = 0x1A;
  }
  else {  // system has gone into invalid state
    dig1 = 0;
    dig2 = 0;
    dig3 = 0;
    dig4 = 0;
    P1OUT = 0x18;
  }
}


// System Display Routine - runs at 512 Hz
void display(void)
{
  P2OUT = 0xFF;  // clear digit
  displaydigit(-1);
  
  // update digit counter
  digcount++;
  digcount %= 4; 

  // update blink controller
  if((clock_count % 256) == 0)
    blink ^= 0x01;
    
  switch(digcount) {
    case 0:  // display digit 1
      if(blink || (mainstate == SHOW_TIME) || (mainstate == SET_MIN) || (mainstate == SHOW_DATE) || (mainstate == SET_DAY) ||
        (mainstate == SHOW_YEAR) || (mainstate == SHOW_TEMP)  || (mainstate == AUTO_TOGGLE)) {
        if(dig1 || (mainstate == SHOW_DATE) || (mainstate == SET_DAY) || (mainstate == SET_MONTH) || (mainstate == SHOW_YEAR) ||
          (mainstate == SET_YEAR) || ((mainstate == AUTO_TOGGLE) && (togglestate != SHOW_TIME)))
          displaydigit(dig1);                     
        else displaydigit(-1);
        if(blink && ((mainstate == SHOW_TIME) || ((mainstate == AUTO_TOGGLE) && (togglestate == SHOW_TIME))))
          P2OUT = 0xDE;  // Display Digit 1 without clock colon
        else
          P2OUT = 0xCE;  // Display Digit 1 with clock colon
      }
      else P2OUT = 0xCF; // Digit off for blinking
      break;
    case 1:  // display digit 2
      if(blink || (mainstate == SHOW_TIME) || (mainstate == SET_MIN) || (mainstate == SHOW_DATE) || (mainstate == SET_DAY) ||
        (mainstate == SHOW_YEAR) || (mainstate == SHOW_TEMP) || (mainstate == AUTO_TOGGLE)) {    
        displaydigit(dig2);
        P2OUT = 0xFD;  // Display Digit 2
      }
      else P2OUT = 0xFF; // Digit off for blinking
      break;
    case 2:  // display digit 3
      if(blink || (mainstate == SHOW_TIME) || (mainstate == SET_HOUR) || (mainstate == SHOW_DATE) || (mainstate == SET_MONTH) ||
        (mainstate == SHOW_YEAR) || (mainstate == SHOW_TEMP) || (mainstate == AUTO_TOGGLE)) {
        displaydigit(dig3); 
        P2OUT = 0xFB;  // Display Digit 3
      }
      else P2OUT = 0xFF; // Digit off for blinking
      break;
    case 3:  // display digit 4
      if(blink || (mainstate == SHOW_TIME) || (mainstate == SET_HOUR) || (mainstate == SHOW_DATE) || (mainstate == SET_MONTH) ||
        (mainstate == SHOW_YEAR) || (mainstate == SHOW_TEMP) || (mainstate == AUTO_TOGGLE)) {
        displaydigit(dig4);
        P2OUT = 0xF7;  // Display Digit 4
      }
      else P2OUT = 0xFF; // Digit off for blinking
      break;
  }  
}


// Routine for converting integer number into display value
// Runs when called
void displaydigit(int number)
{
  switch(number) {
    case 0: P3OUT = (P3OUT & 0x80) | zero;
            break;
    case 1: P3OUT = (P3OUT & 0x80) | one;
            break;
    case 2: P3OUT = (P3OUT & 0x80) | two;
            break;
    case 3: P3OUT = (P3OUT & 0x80) | three;
            break;
    case 4: P3OUT = (P3OUT & 0x80) | four;
            break;
    case 5: P3OUT = (P3OUT & 0x80) | five;
            break;
    case 6: P3OUT = (P3OUT & 0x80) | six;
            break;
    case 7: P3OUT = (P3OUT & 0x80) | seven;
            break;
    case 8: P3OUT = (P3OUT & 0x80) | eight;
            break;
    case 9: P3OUT = (P3OUT & 0x80) | nine;
            break;
    case 10: P3OUT = (P3OUT & 0x80) | fahrenheit;
             break;
    case 11: P3OUT = (P3OUT & 0x80) | celcius;
             break;
    default: P3OUT = (P3OUT & 0x80) | blank;
             break;
  }
}

⌨️ 快捷键说明

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