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

📄 lcdinterface.c

📁 CYGNAL单片机
💻 C
📖 第 1 页 / 共 2 页
字号:
   TMR2CN = 0x00;                      // STOP Timer2; Clear TF2H and TF2L;
                                       // disable low-byte interrupt; disable
                                       // split mode; select internal timebase
   CKCON |= 0x10;                      // Timer2 uses SYSCLK as its timebase

   TMR2RL  = -counts;                  // Init reload values
   TMR2    = TMR2RL;                   // Init Timer2 with reload value
   ET2 = 1;                            // enable Timer2 interrupts
   TR2 = 1;                            // start Timer2
}

//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure the Timer to overflow without interrupts
// The overflow will be used in the wait function
//
void Timer3_Init (int count)
{
   TMR3CN = 0x00;                      // STOP Timer3; Clear TF3H and TF3L;
                                       // disable low-byte interrupt; disable
                                       // split mode; select internal timebase

   CKCON |= 0x40;                      // Timer3 uses SYSCLK as its timebase

   TMR3RL  =  -count;                  // Init reload values
   TMR3    =  TMR3RL;                  // Init Timer3 with reload value
   EIE1    &= 0x7F;                    // disable Timer3 interrupts

   TMR3CN  |= 0x01;                    // start Timer3
}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

// LCDrefresh is triggered on a Timer2 Overflow

// Takes what is in the LCD bar bits and shift them into the two 74HC595
// shift registers depending on the COM cycle; The most signficant
// LCD pin (pin 16) gets shifted out first; Only 15 bits get shifted each
// COM cycle;

void LCDrefresh_ISR (void) interrupt 5
{
   int i = 0;

   if (com_cycle == 1)
   {
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D6A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D5A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D4A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D3A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D2A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = D1A  ^ com_invert; Strobe();
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = 1    ^ com_invert; Strobe();         // non-existent segment
      SER = 1    ^ com_invert; Strobe();         // non-existent segment

      RCLK = 1;                        // put shifted data to LCD - rising edge
      for (i=0; i<PULSE_LENGTH; i++);  // keep clock high for a while
      RCLK = 0;                        // turn off clock

      P1MDIN  &= ~0x80;                // configure COM4 to ANALOG_IN;
      P1MDIN  |= 0x10;                 // and COM1 to digital

      P1MDOUT &= ~0x80;                // make COM4 an open-drain
      P1MDOUT |= 0x10;                 // make COM1 a push-pull
      COM4    = 1;                     // set COM4 to high impedance
      COM1    = 1 ^ com_invert;        // start the COM1 cycle
      com_cycle = 2;                   // next state
   }

   else if (com_cycle == 2)
   {
      SER = D6B  ^ com_invert;     Strobe();
      SER = D6F  ^ com_invert;     Strobe();
      SER = D5B  ^ com_invert;     Strobe();
      SER = D5F  ^ com_invert;     Strobe();
      SER = D4B  ^ com_invert;     Strobe();
      SER = D4F  ^ com_invert;     Strobe();
      SER = D3B  ^ com_invert;     Strobe();
      SER = D3F  ^ com_invert;     Strobe();
      SER = D2B  ^ com_invert;     Strobe();
      SER = D2F  ^ com_invert;     Strobe();
      SER = D1B  ^ com_invert;     Strobe();
      SER = D1F  ^ com_invert;     Strobe();
      SER = 1    ^ com_invert;     Strobe();      // non-existent segment
      SER = 1    ^ com_invert;     Strobe();      // non-existent segment
      SER = 1    ^ com_invert;     Strobe();      // non-existent segment

      RCLK = 1;                        // put shifted data to LCD - rising edge
      for (i=0; i<PULSE_LENGTH; i++);  // keep clock high for a while
      RCLK = 0;                        // turn off clock

      P1MDIN  &= ~0x10;                // configure COM1 to ANALOG_IN;
      P1MDIN  |= 0x20;                 // and COM2 to digital

      P1MDOUT &= ~0x10;                // make COM1 an open-drain
      P1MDOUT |= 0x20;                 // make COM2 a push-pull
      COM1    = 1;                     // set COM1 to high impedance
      COM2    = 1 ^ com_invert;        // start the COM2 cycle
      com_cycle = 3;                   // next state
   }

   else if (com_cycle == 3)
   {
      SER = D6C ^ com_invert;     Strobe();
      SER = D6G ^ com_invert;     Strobe();
      SER = D5C ^ com_invert;     Strobe();
      SER = D5G ^ com_invert;     Strobe();
      SER = D4C ^ com_invert;     Strobe();
      SER = D4G ^ com_invert;     Strobe();
      SER = D3C ^ com_invert;     Strobe();
      SER = D3G ^ com_invert;     Strobe();
      SER = D2C ^ com_invert;     Strobe();
      SER = D2G ^ com_invert;     Strobe();
      SER = D1C ^ com_invert;     Strobe();
      SER = D1G ^ com_invert;     Strobe();
      SER = 1   ^ com_invert;     Strobe();      // non-existent segment
      SER = 1   ^ com_invert;     Strobe();      // non-existent segment
      SER = 1   ^ com_invert;     Strobe();      // non-existent segment

      RCLK = 1;                        // put shifted data to LCD - rising edge
      for (i=0; i<PULSE_LENGTH; i++);  // keep clock high for a while
      RCLK = 0;                        // turn off clock

      P1MDIN  &= ~0x20;                // configure COM2 to ANALOG_IN;
      P1MDIN  |= 0x40;                 // and COM3 to digital

      P1MDOUT &= ~0x20;                // make COM2 an open-drain
      P1MDOUT |= 0x40;                 // make COM3 a push-pull
      COM2    = 1;                     // set COM2 to high impedance
      COM3    = 1 ^ com_invert;        // start the COM3 cycle
      com_cycle = 4;                   // next state
   }

   else if (com_cycle == 4)
   {
      SER = D6D ^ com_invert;     Strobe();
      SER = D6E ^ com_invert;     Strobe();
      SER = D5D ^ com_invert;     Strobe();
      SER = D5E ^ com_invert;     Strobe();
      SER = D4D ^ com_invert;     Strobe();
      SER = D4E ^ com_invert;     Strobe();
      SER = D3D ^ com_invert;     Strobe();
      SER = D3E ^ com_invert;     Strobe();
      SER = D2D ^ com_invert;     Strobe();
      SER = D2E ^ com_invert;     Strobe();
      SER = D1D ^ com_invert;     Strobe();
      SER = D1E ^ com_invert;     Strobe();
      SER = 1   ^ com_invert;     Strobe();         // non-existent segment
      SER = 1   ^ com_invert;     Strobe();         // non-existent segment
      SER = 1   ^ com_invert;     Strobe();         // non-existent segment

      RCLK = 1;                        // put shifted data to LCD - rising edge
      for (i=0; i<PULSE_LENGTH; i++);  // keep clock high for a while
      RCLK = 0;                        // turn off clock

      P1MDIN  &= ~0x40;                // configure COM3 to ANALOG_IN;
      P1MDIN  |= 0x80;                 // and COM4 to digital

      P1MDOUT &= ~0x40;                // make COM3 an open-drain
      P1MDOUT |= 0x80;                 // make COM4 a push-pull
      COM3    = 1;                     // set COM3 to high impedance
      COM4    = 1 ^ com_invert;        // start the COM4 cycle
      com_cycle = 1;                   // next state

      com_invert = com_invert ^ 1;     // toggle com_invert
   }

   TF2H = 0;                           // clear TF2

} // end LCDrefresh_ISR

//-----------------------------------------------------------------------------
// Strobe
//-----------------------------------------------------------------------------
//
// Strobe is used to clock the data into the 74HC595 shift registers
//
void Strobe()
{
   int i = 0;

   SRCLK = 1;
   for (i = 0; i < PULSE_LENGTH; i++);          // wait a few cycles
   SRCLK = 0;
   for (i = 0; i < PULSE_LENGTH; i++);          // wait a few cycles

}

//-----------------------------------------------------------------------------
// wait_one_msec
//-----------------------------------------------------------------------------
//
// Assumes Timer3 overflows once every 500 usec
//
void wait_one_ms(unsigned int count)
{
   count = count * 2;                  // overflows once every 500 usec
                                       // so double that is 1 ms

   TMR3CN &= ~0x80;                    // Clear Timer3 overflow flag
   TMR3 = TMR3RL;
   TMR3CN  = 0x04;                     // Start Timer3

   while (count--)
   {
      while (!(TMR3CN & 0x80)) {}      // wait for overflow
      TMR3CN &= ~0x80;                 // clear overflow indicator
   }

   TMR3CN &= ~0x04;                    // Stop Timer3
}

//-----------------------------------------------------------------------------
// LCD functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// putchar
//-----------------------------------------------------------------------------
//
// putchar only handles the digit components on the LCD screen.
// This functions shifts the digit values to the left, shifting out the
// left-most digit.  This function has 3 potential actions based on the input:
//
// 1. Any input whose ASCII code is between 0 and 127 gets translated
//    according to the translation table above
//
// 2. Any input whose ASCII code is between 128 and 255 is directly sent to
//    the LCD. The lower 7 bits indicate which of the seven segments are lit.
//
// 3. Passing a newline char '\n' to this function clears all 6 digits
//
// This function, unlike standard putchar, does not have any error return msgs.
//
// This function will not cause an interrupt to force output.  The input char
// will be displayed on the screen on the next refresh cycle

char putchar(char charIN)
{
   unsigned char iter = 0;

   if (charIN != '\n')                              // not a new line
   {
      if ((charIN & 0x80) == 0) {                   // translation necesssary
        charIN = translation_table [charIN]; }      // quick lookup

      EA = 0;                                       // prevent partial display

      for (iter = 0; iter < 5; iter++) {            // shift the digits left
         LCD_digits[iter] = LCD_digits[iter+1]; }

      LCD_digits[5] = charIN;                       // new digit is rightmost

      EA = 1;                                       // enable interrupts again
   }

   else                                             // input is a newline
   {
      EA = 0;                                       // disable interrupts
      for (iter = 0; iter < 6; iter++) {
         LCD_digits[iter] = 0xFF; }                 // clear all digits
      EA = 1;                                       // enable interrupts
   }

   if (charIN == 0xFF) {                            // couldn't interpret OR space
      charIN = ' '; }                               // return space

   return charIN;                                   // just like putchar
}

⌨️ 快捷键说明

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