📄 lcd_driver.c
字号:
//*****************************************************************************
// File........: LCD_driver.c
// Author(s)...: ATMEL Norway
// Target(s)...: ATmega169
// Compiler....: AVR GCC 20060421
// Description.: Functions used to control the STK502 LCD
// Revisions...: 1.1
// YYYYMMDD - VER. - COMMENT - SIGN.
// 20021015 - 1.0 - General modifications and clean up - JLL
// 20060829 - 1.1 - Ported to AVR GCC - TMF, OL
//*****************************************************************************
// Include files.
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#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)
unsigned int LCD_character_table[] PROGMEM = // 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 = pgm_read_word( &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
*
*******************************************************************************/
ISR(LCD_vect)
{
unsigned char i;
unsigned char *src, *dest;
i = 20;
dest = &pLCDREG; // Destination = LCD Data Register start
src = LCD_displayData; // source = LCD Display located in SRAM
do
{
*dest++ = *src++; // Bulk Copy the data into LCD registers
} while ( --i );
LCDCRA &= ~(1<<LCDIE); //Disable LCD_Start_frame interrupt until needed again
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -