📄 lcd.~c
字号:
/* ATmega103 lcd.c file
Author : Robert Stuart
Company : PDL Industries Ltd
Date of Creation : 13 April 2000
Tested : 13 April 2000
Function :
This module controls the operation of a 16x2 lcd for the ATmega603/103.
Auto detection of lcd added. Reads the last character of each line to
determine whether write was successful.
*/
/* include */
#include "lcd.h"
/* Initialises the lcd */
void LCDInitialise( void )
{
MCUCR |= BIT(SRE) | BIT(SRW);
LCDCounter = _50MS; /* delay counter for lcd initialisation */
LCDStatus = 0; /* lcd status flags are reset */
}
/* global function called when writing to the lcd */
void LCDPrintf( char *ptr1, char *ptr2 )
{
if ( !CHECKBIT( LCDStatus, LCD_UPDATE ) )
{ /* check that lcd is not currently updating */
strcpy( LCDStr1, ptr1 ); /* copy strings into local variables */
strcpy( LCDStr2, ptr2 );
if ( LCDStr1[0] == CHARACTER_NULL ) /* line 1 not updated */
{
strcpy( LCDStr1, LCDStr2 );
LCDLine = LINE2;
}
else if ( LCDStr2[0] == CHARACTER_NULL )
LCDLine = LINE1; /* line 2 not updated */
else
LCDLine = LINE1_AND_LINE2;
SETBIT( LCDStatus, LCD_UPDATE ); /* set flags */
CLEARBIT( LCDStatus, LCD_QUEUE );
}
else if ( !CHECKBIT( LCDStatus, LCD_QUEUE ) )
{ /* update after existing update has been completed */
strcpy( LCDQueueStr1, ptr1);
strcpy( LCDQueueStr2, ptr2);
SETBIT( LCDStatus, LCD_QUEUE );
}
}
/* called from the main 1ms interrupt, must allow at least 40ms before lcd can be initialised */
void DelayLCDStartup( void )
{
if ( LCDCounter && !CHECKBIT( LCDStatus, LCD_BUSY ) )
LCDCounter--; /* count down delay timer */
if ( CHECKBIT( LCDStatus, LCD_INITIALISE ) && LCDCounter == 1 )
InitScreen(); /* initialise lcd */
}
void InitScreen( void )
{
sprintf( LCDStr1, "%s", LCDHeader1 ); /* initialise lcd lines */
sprintf( LCDStr2, "%s", LCDHeader2 );
LCDLine = LINE1_AND_LINE2; /* both lines to be updated */
LCDCounter--;
SETBIT( LCDStatus, LCD_UPDATE );
}
/* continously called when not serving interrupts and the micro is doing nothing */
void RefreshLCD( void )
{
if ( CHECKBIT( LCDStatus, LCD_OK ) )
{
if ( CHECKBIT( LCDStatus, LCD_UPDATE ) )
WriteToScreen();
}
else if ( LCDCounter == _20MS )
ConfigureLCD(); /* configure lcd to 2 lines, 8bit interface */
}
/* sets the lcd to 2-line 16-character mode with 8-bit interface and auto incrementation */
void ConfigureLCD( void )
{
static const unsigned char initialise_table[] = {FUNCTION_SET, DISPLAY_ON, DISPLAY_CLEAR};
unsigned char i;
for ( i=0; i<3; i++ )
{
CheckIfBusy();
WriteToDevice( initialise_table[i], INSTRUCTION );
}
LCDCounter--;
SETBIT( LCDStatus, LCD_OK );
SETBIT( LCDStatus, LCD_INITIALISE );
}
void WriteToScreen( void )
{
static unsigned char i;
if ( !CHECKBIT( LCDStatus, LCD_BUSY ) )
{
if ( LCDLine == LINE2 ) /* set which line is to be updated */
WriteToDevice( SECOND_LINE, INSTRUCTION );
else
WriteToDevice( FIRST_LINE, INSTRUCTION );
for ( i=0; i<16; i++ ) /* replace all characters after the null which space characters */
if ( LCDStr1[i] == CHARACTER_NULL )
for ( ; i<16; i++ )
LCDStr1[i] = CHARACTER_SPACE;
i = 0;
SETBIT( LCDStatus, LCD_BUSY );
}
CheckIfBusy();
WriteToDevice( LCDStr1[i++], DATA ); /* write character to screen */
if ( i>15 ) /* finished line */
{
CheckIfBusy(); /* check is lcd is connected */
if ( LCDLine == LINE2 )
WriteToDevice( SECOND_LINE, INSTRUCTION );
else
WriteToDevice( FIRST_LINE, INSTRUCTION );
CheckIfBusy(); /* check if first character is correct */
if ( ReadDevice( DATA ) != LCDStr1[0] )
LCDInitialise(); /* reinitialise lcd otherwise */
if ( LCDLine == LINE1_AND_LINE2 )
{
strcpy( LCDStr1, LCDStr2 ); /* load str2 into str1 and update line 2 */
LCDLine = LINE2;
}
else
{
if ( CHECKBIT( LCDStatus, LCD_QUEUE ) )
LCDPrintf( LCDQueueStr1, LCDQueueStr2 );
CLEARBIT( LCDStatus, LCD_UPDATE );
}
CLEARBIT( LCDStatus, LCD_BUSY );
}
}
/* writes to lcd */
void WriteToDevice( char data, unsigned char select )
{
char *LCD_IO;
if ( select == INSTRUCTION ) /* set RS */
LCD_IO = ( char * ) 0x8000;
else
LCD_IO = ( char * ) 0xC000;
*LCD_IO = data;
}
void CheckIfBusy( void )
{
while ( ReadDevice( INSTRUCTION ) & BUSY_FLAG );
}
/* reads from lcd */
char ReadDevice( unsigned char select )
{
char *LCD_IO;
if ( select == INSTRUCTION ) /* set RS */
LCD_IO = ( char * ) 0x8000;
else
LCD_IO = ( char * ) 0xC000;
return *LCD_IO;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -