📄 lcd_driver.c
字号:
//*****************************************************************************
//
// File........: LCD_driver.c
//
// Author(s)...: ATMEL Norway
//
// Target(s)...: ATmega169
//
// Compiler....: IAR EWAAVR 2.27b
//
// Description.: Functions used to control the STK502 LCD
//
// Revisions...: 1.0
//
// YYYYMMDD - VER. - COMMENT - SIGN.
//
// 20021015 - 1.0 - General modifications and clean up - JLL
//
//*****************************************************************************
// Include files.
#include "Main.h"
#include "LCD_driver.h"
union _LCD_status LCD_status = {0x01}; //LCD_status = {0, 0, 0, 0, 0, 0, FALSE, TRUE};
unsigned char LCD_timer = LCD_TIMER_SEED;
unsigned char LCD_displayData[LCD_REGISTER_COUNT]; // LCD display buffer (for double buffering).
// Look-up table used when converting ASCII to LCD display data (segment control)
__flash unsigned int LCD_character_table[] = // Character definitions table.
{
0x0A51, // '*' (?)
0x2A80, // '+'
0x0000, // ',' (Not defined)
0x0A00, // '-'
0x0A51, // '.' Used in the Application Note AVR064, to write "degree" in the display
0x0000, // '/' (Not defined)
0x5559, // '0'
0x0118, // '1'
0x1e11,
0x1b11,
0x0b50,
0x1b41,
0x1f41,
0x0111,
0x1f51,
0x1b51, // '9'
0x0000, // ':' (Not defined)
0x0000, // ';' (Not defined)
0x0000, // '<' (Not defined)
0x0000, // '=' (Not defined)
0x0000, // '>' (Not defined)
0x0000, // '?' (Not defined)
0x0000, // '@' (Not defined)
0x0f51, // 'A' (+ 'a')
0x3991, // 'B' (+ 'b')
0x1441, // 'C' (+ 'c')
0x3191, // 'D' (+ 'd')
0x1e41,
0x0e41,
0x1d41,
0x0f50,
0x2080,
0x1510,
0x8648,
0x1440,
0x0578,
0x8570,
0x1551,
0x0e51,
0x9551,
0x8e51,
0x9021,
0x2081,
0x1550,
0x4448,
0xc550,
0xc028,
0x2028, // 'Y' (+ 'y')
0x5009, // 'Z' (+ 'z')
0x0000, // '[' (Not defined)
0x0000, // '\' (Not defined)
0x0000, // ']' (Not defined)
0x0000, // '^' (Not defined)
0x0000 // '_' (Not defined)
};
/******************************************************************************************
*
* Function name : LCD_Init
*
* Returns : None
*
* Parameters : None
*
* Purpose : Initialize LCD_displayData buffer. Set up the LCD (timing, contrast, etc.)
*
******************************************************************************************/
void LCD_Init (void)
{
LCD_AllSegments( FALSE ); // Clear segment buffer.
LCDCRA = (1<<LCDEN); // Enable LCD.
LCD_CONTRAST_LEVEL(LCD_INITIAL_CONTRAST); //Set the LCD contrast level
// Select asynchronous clock source, enable all COM pins and enable all segment pins.
LCDCRB = (1<<LCDCS) | (1<<LCDMUX1) | (1<<LCDMUX0) | (1<<LCDPM2) | (1<<LCDPM1)| (1<<LCDPM0);
LCDFRR = (1<<LCDPS0); // Set LCD prescaler to CLK(lcd)/64 = 64Hz.
LCDCRA |= (1<<LCDIE); //Enable LCD_Start_frame interrupt
}
/******************************************************************************************
*
* Function name : LCD_WriteDigit( unsigned char c, unsigned char digit )
*
* Returns : None
*
* Parameters : Inputs
* c - The symbol to be displayed in a LCD digit
* digit - The LCD digit that the symbol should be displayed in
*
* Purpose : Stores LCD control data in the LCD_displayData buffer.
* (The LCD_displayData is latched in the LCD_SOF interrupt).
*
******************************************************************************************/
void LCD_WriteDigit( unsigned char c, unsigned char digit )
{
unsigned int seg;
unsigned char i;
unsigned char mask, nibble;
unsigned char *ptr;
//Lookup character table for segmet data
seg = 0x0000;
if ( (c >= '*') && (c <= 'z') )
{
// c is in character_table.
// Convert to upper if necessarry.
if ( c >= 'a' ) c &= ~0x20;
c -= '*';
seg = LCD_character_table[c];
}
// Adjust mask according to digit
mask = 0x0F; // (1), 3, 5, 7
if ( digit & 0x01 )
{
}
else
{
mask = 0xF0; // (0), 2, 4, 6
}
i = digit-2;
if ( i >= 6 )
return;
i >>= 1;
ptr = LCD_displayData + i; // i = {0,0,1,1,2,2}
i = 4;
do
{
nibble = seg & 0x000F;
seg >>= 4;
if ( digit & 0x01 )
nibble <<= 4;
*ptr = (*ptr & mask) | nibble;
ptr += 5;
} while ( --i );
}
/******************************************************************************************
*
* Function name : LCD_AllSegments( unsigned char input )
*
* Returns : None
*
* Parameters : Inputs->
* input - [TRUE;FALSE]=[DISPLAY;HIDE]
*
* Purpose : display all or hide all LCD segments on the STK502 LCD
*
******************************************************************************************/
void LCD_AllSegments( unsigned char input )
{
unsigned char i;
unsigned char *ptr;
if( input ) // if input == TRUE
input = 0xFF; // set setgemts to 0xFF
// (else set segments to 0x00)
ptr = LCD_displayData;
i = 20;
do // Set all LCD segment register to the variable Segments
{
*ptr++ = input; // Set/clear the bits in all LCD registers
} while ( --i );
}
/******************************************************************************
*
* LCD Interrupt Routine
*
* Returns : None
*
* Parameters : None
*
* Purpose: Latch the LCD_displayData and Set LCD_status.updateComplete
*
*******************************************************************************/
#pragma vector = LCD_SOF_vect
__interrupt void LCD_SOF_interrupt( void )
{
unsigned char i;
unsigned char *src, *dest;
LCD_timer--;
if( LCD_timer == 0 ) // if time out
{
if( LCD_status.updateRequired == TRUE )
{
LCD_timer = LCD_TIMER_SEED; // Reload the LCD_timer
LCD_status.updateComplete = TRUE; // Set the LCD_ScrollReady to true.
LCD_status.blinkLCD = ~LCD_status.blinkLCD; // Toggle LCD_Blink variable.
// Copy display data buffer to I/O segment registers.
i = 20;
dest = &pLCDREG;
src = LCD_displayData;
do
{
*dest++ = *src++;
} while ( --i );
}
else
{
LCD_timer = 1; //If LCD timer allows update of the LCD, but update is blocked
// by LCD_status.updateRequired == FALSE the LCD_timer is preloaded
// with smallest timer seed to ensure fastest LCD update.
LCD_status.updateComplete = FALSE; //Block for further access to the LCD_displayData until
// LCD update has been performed.
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -