📄 lcd.s
字号:
.module lcd.c
.text
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
.area text
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
.dbfunc s LCDInitialise _LCDInitialise fI
.even
_LCDInitialise::
.dbline 22{
; /* 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.
;
; EN timing performed by hardware.
; */
;
; /* include */
; #include "lcd.h"
;
; /* Initialises the lcd */
; void LCDInitialise( void )
; {
.dbline 23
; MCUCR |= BIT(SRE) | BIT(SRW);
in R24,0x35
ori R24,192
out 0x35,R24
.dbline 24
; LCDCounter = _50MS; /* delay counter for lcd initialisation */
ldi R24,50
sts _LCDCounter,R24
.dbline 25
; LCDStatus = 0; /* lcd status flags are reset */
clr R2
sts _LCDStatus,R2
.dbline 26}
; }
L1:
ret
.dbfunc s LCDPrintf _LCDPrintf fI
; ptr2 -> R20,R21
; ptr1 -> R22,R23
.even
_LCDPrintf::
call push_gset2
mov R20,R18
mov R21,R19
mov R22,R16
mov R23,R17
.dbline 30{
;
; /* global function called when writing to the lcd */
; void LCDPrintf( char *ptr1, char *ptr2 )
; {
.dbline 31
; if ( !CHECKBIT( LCDStatus, LCD_UPDATE ) )
lds R2,_LCDStatus
sbrc R2,1
rjmp L3
.dbline 32
; { /* check that lcd is not currently updating */
.dbline 33
; strcpy( LCDStr1, ptr1 ); /* copy strings into local variables */
mov R18,R22
mov R19,R23
ldi R16,<_LCDStr1
ldi R17,>_LCDStr1
call _strcpy
.dbline 34
; strcpy( LCDStr2, ptr2 );
mov R18,R20
mov R19,R21
ldi R16,<_LCDStr2
ldi R17,>_LCDStr2
call _strcpy
.dbline 36
;
; if ( LCDStr1[0] == CHARACTER_NULL ) /* line 1 not updated */
lds R2,_LCDStr1
tst R2
brne L5
.dbline 37
; {
.dbline 38
; strcpy( LCDStr1, LCDStr2 );
ldi R18,<_LCDStr2
ldi R19,>_LCDStr2
ldi R16,<_LCDStr1
ldi R17,>_LCDStr1
call _strcpy
.dbline 39
; LCDLine = LINE2;
ldi R24,2
sts _LCDLine,R24
.dbline 40
; }
jmp L6
L5:
.dbline 41
; else if ( LCDStr2[0] == CHARACTER_NULL )
lds R2,_LCDStr2
tst R2
brne L7
.dbline 42
; LCDLine = LINE1; /* line 2 not updated */
ldi R24,1
sts _LCDLine,R24
jmp L8
L7:
.dbline 44
; else
; LCDLine = LINE1_AND_LINE2;
ldi R24,3
sts _LCDLine,R24
L8:
L6:
.dbline 46
;
; SETBIT( LCDStatus, LCD_UPDATE ); /* set flags */
lds R24,_LCDStatus
ori R24,2
sts _LCDStatus,R24
.dbline 47
; CLEARBIT( LCDStatus, LCD_QUEUE );
andi R24,239
sts _LCDStatus,R24
.dbline 48
; }
jmp L4
L3:
.dbline 49
; else if ( !CHECKBIT( LCDStatus, LCD_QUEUE ) )
lds R2,_LCDStatus
sbrc R2,4
rjmp L9
.dbline 50
; { /* update after existing update has been completed */
.dbline 51
; strcpy( LCDQueueStr1, ptr1);
mov R18,R22
mov R19,R23
ldi R16,<_LCDQueueStr1
ldi R17,>_LCDQueueStr1
call _strcpy
.dbline 52
; strcpy( LCDQueueStr2, ptr2);
mov R18,R20
mov R19,R21
ldi R16,<_LCDQueueStr2
ldi R17,>_LCDQueueStr2
call _strcpy
.dbline 54
;
; SETBIT( LCDStatus, LCD_QUEUE );
lds R24,_LCDStatus
ori R24,16
sts _LCDStatus,R24
.dbline 55
; }
L9:
L4:
.dbline 56}
; }
L2:
call pop_gset2
ret
.dbsym r ptr2 20 pc
.dbsym r ptr1 22 pc
.dbfunc s DelayLCDStartup _DelayLCDStartup fI
.even
_DelayLCDStartup::
.dbline 60{
;
; /* called from the main 1ms interrupt, must allow at least 40ms before lcd can be initialised */
; void DelayLCDStartup( void )
; {
.dbline 61
; if ( LCDCounter && !CHECKBIT( LCDStatus, LCD_BUSY ) )
lds R2,_LCDCounter
tst R2
breq L12
lds R2,_LCDStatus
sbrc R2,2
rjmp L12
.dbline 62
; LCDCounter--; /* count down delay timer */
lds R24,_LCDCounter
subi R24,1
sts _LCDCounter,R24
L12:
.dbline 64
;
; if ( CHECKBIT( LCDStatus, LCD_INITIALISE ) && LCDCounter == 1 )
lds R2,_LCDStatus
sbrs R2,3
rjmp L14
lds R24,_LCDCounter
cpi R24,1
brne L14
.dbline 65
; InitScreen(); /* initialise lcd */
call _InitScreen
L14:
.dbline 66}
; }
L11:
ret
.dbfunc s InitScreen _InitScreen fI
.even
_InitScreen::
sbiw R28,2
.dbline 69{
;
; void InitScreen( void )
; {
.dbline 70
; sprintf( LCDStr1, "%s", LCDHeader1 ); /* initialise lcd lines */
lds R3,_LCDHeader1+1
lds R2,_LCDHeader1
std y+0,R2
std y+1,R3
ldi R18,<L17
ldi R19,>L17
ldi R16,<_LCDStr1
ldi R17,>_LCDStr1
call _sprintf
.dbline 71
; sprintf( LCDStr2, "%s", LCDHeader2 );
lds R3,_LCDHeader2+1
lds R2,_LCDHeader2
std y+0,R2
std y+1,R3
ldi R18,<L17
ldi R19,>L17
ldi R16,<_LCDStr2
ldi R17,>_LCDStr2
call _sprintf
.dbline 72
; LCDLine = LINE1_AND_LINE2; /* both lines to be updated */
ldi R24,3
sts _LCDLine,R24
.dbline 73
; LCDCounter--;
lds R24,_LCDCounter
subi R24,1
sts _LCDCounter,R24
.dbline 74
; SETBIT( LCDStatus, LCD_UPDATE );
lds R24,_LCDStatus
ori R24,2
sts _LCDStatus,R24
.dbline 75}
; }
L16:
adiw R28,2
ret
.dbfunc s RefreshLCD _RefreshLCD fI
.even
_RefreshLCD::
.dbline 79{
;
; /* continously called when not serving interrupts and the micro is doing nothing */
; void RefreshLCD( void )
; {
.dbline 80
; if ( CHECKBIT( LCDStatus, LCD_OK ) )
lds R2,_LCDStatus
sbrs R2,0
rjmp L19
.dbline 81
; {
.dbline 82
; if ( CHECKBIT( LCDStatus, LCD_UPDATE ) )
sbrs R2,1
rjmp L20
.dbline 83
; WriteToScreen();
call _WriteToScreen
.dbline 84
; }
jmp L20
L19:
.dbline 85
; else if ( LCDCounter == _20MS )
lds R24,_LCDCounter
cpi R24,20
brne L23
.dbline 86
; ConfigureLCD(); /* configure lcd to 2 lines, 8bit interface */
call _ConfigureLCD
L23:
L20:
.dbline 87}
; }
L18:
ret
.area lit
L26:
.byte 56,12
.byte 1
.area text
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
.dbfunc s ConfigureLCD _ConfigureLCD fI
.dbsym s initialise_table L26 Ac[3:3]
; i -> R20
.even
_ConfigureLCD::
call push_gset1
.dbline 91{
;
; /* sets the lcd to 2-line 16-character mode with 8-bit interface and auto incrementation */
; void ConfigureLCD( void )
; {
.dbline 95
; static const unsigned char initialise_table[] = {FUNCTION_SET, DISPLAY_ON, DISPLAY_CLEAR};
; unsigned char i;
;
; for ( i=0; i<3; i++ )
clr R20
jmp L30
L27:
.dbline 96
.dbline 97
call _CheckIfBusy
.dbline 98
clr R18
clr R19
ldi R24,<L26
ldi R25,>L26
mov R2,R20
clr R3
add R2,R24
adc R3,R25
mov R30,R2
mov R31,R3
lpm
mov R16,R0
clr R17
call _WriteToDevice
.dbline 99
L28:
.dbline 95
subi R20,255 ; addi 1
L30:
.dbline 95
cpi R20,3
brlo L27
.dbline 101
; {
; CheckIfBusy();
; WriteToDevice( initialise_table[i], INSTRUCTION );
; }
;
; LCDCounter--;
lds R24,_LCDCounter
subi R24,1
sts _LCDCounter,R24
.dbline 102
; SETBIT( LCDStatus, LCD_OK );
lds R24,_LCDStatus
ori R24,1
sts _LCDStatus,R24
.dbline 103
; SETBIT( LCDStatus, LCD_INITIALISE );
ori R24,8
sts _LCDStatus,R24
.dbline 104}
; }
L25:
call pop_gset1
ret
.dbsym r i 20 c
.area bss
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
L32:
.blkb 1
.area text
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
.dbfunc s WriteToScreen _WriteToScreen fI
.dbsym s i L32 c
.even
_WriteToScreen::
.dbline 107{
;
; void WriteToScreen( void )
; {
.dbline 110
; static unsigned char i;
;
; if ( !CHECKBIT( LCDStatus, LCD_BUSY ) )
lds R2,_LCDStatus
sbrc R2,2
rjmp L33
.dbline 111
; {
.dbline 112
; if ( LCDLine == LINE2 ) /* set which line is to be updated */
lds R24,_LCDLine
cpi R24,2
brne L35
.dbline 113
; WriteToDevice( SECOND_LINE, INSTRUCTION );
clr R18
clr R19
ldi R16,192
ldi R17,0
call _WriteToDevice
jmp L36
L35:
.dbline 115
; else
; WriteToDevice( FIRST_LINE, INSTRUCTION );
clr R18
clr R19
ldi R16,128
ldi R17,0
call _WriteToDevice
L36:
.dbline 117
;
; for ( i=0; i<16; i++ ) /* replace all characters after the null which space characters */
clr R2
sts L32,R2
jmp L40
L37:
.dbline 118
; if ( LCDStr1[i] == CHARACTER_NULL )
ldi R24,<_LCDStr1
ldi R25,>_LCDStr1
lds R30,L32
clr R31
add R30,R24
adc R31,R25
ldd R2,z+0
tst R2
brne L41
.dbline 119
; for ( ; i<16; i++ )
jmp L46
L43:
.dbline 120
ldi R24,<_LCDStr1
ldi R25,>_LCDStr1
lds R30,L32
clr R31
add R30,R24
adc R31,R25
ldi R24,32
std z+0,R24
L44:
.dbline 119
lds R24,L32
subi R24,255 ; addi 1
sts L32,R24
L46:
.dbline 119
lds R24,L32
cpi R24,16
brlo L43
L41:
L38:
.dbline 117
lds R24,L32
subi R24,255 ; addi 1
sts L32,R24
L40:
.dbline 117
lds R24,L32
cpi R24,16
brlo L37
.dbline 121
; LCDStr1[i] = CHARACTER_SPACE;
; i = 0;
clr R2
sts L32,R2
.dbline 122
; SETBIT( LCDStatus, LCD_BUSY );
lds R24,_LCDStatus
ori R24,4
sts _LCDStatus,R24
.dbline 123
; }
L33:
.dbline 125
;
; CheckIfBusy();
call _CheckIfBusy
.dbline 126
; WriteToDevice( LCDStr1[i++], DATA ); /* write character to screen */
ldi R18,1
ldi R19,0
lds R2,L32
clr R3
mov R24,R2
mov R25,R3
adiw R24,1
sts L32,R24
ldi R24,<_LCDStr1
ldi R25,>_LCDStr1
mov R30,R2
mov R31,R3
add R30,R24
adc R31,R25
ldd R16,z+0
clr R17
call _WriteToDevice
.dbline 128
;
; if ( i>15 ) /* finished line */
ldi R24,15
lds R2,L32
cp R24,R2
brlo X0
jmp L47
X0:
.dbline 129
; {
.dbline 130
; CheckIfBusy(); /* check is lcd is connected */
call _CheckIfBusy
.dbline 131
; if ( LCDLine == LINE2 )
lds R24,_LCDLine
cpi R24,2
brne L49
.dbline 132
; WriteToDevice( SECOND_LINE, INSTRUCTION );
clr R18
clr R19
ldi R16,192
ldi R17,0
call _WriteToDevice
jmp L50
L49:
.dbline 134
; else
; WriteToDevice( FIRST_LINE, INSTRUCTION );
clr R18
clr R19
ldi R16,128
ldi R17,0
call _WriteToDevice
L50:
.dbline 136
;
; CheckIfBusy(); /* check if first character is correct */
call _CheckIfBusy
.dbline 137
; if ( ReadDevice( DATA ) != LCDStr1[0] )
ldi R16,1
ldi R17,0
call _ReadDevice
lds R2,_LCDStr1
cp R16,R2
breq L51
.dbline 138
; LCDInitialise(); /* reinitialise lcd otherwise */
call _LCDInitialise
L51:
.dbline 140
;
; if ( LCDLine == LINE1_AND_LINE2 )
lds R24,_LCDLine
cpi R24,3
brne L53
.dbline 141
; {
.dbline 142
; strcpy( LCDStr1, LCDStr2 ); /* load str2 into str1 and update line 2 */
ldi R18,<_LCDStr2
ldi R19,>_LCDStr2
ldi R16,<_LCDStr1
ldi R17,>_LCDStr1
call _strcpy
.dbline 143
; LCDLine = LINE2;
ldi R24,2
sts _LCDLine,R24
.dbline 144
; }
jmp L54
L53:
.dbline 146
; else
; {
.dbline 147
; if ( CHECKBIT( LCDStatus, LCD_QUEUE ) )
lds R2,_LCDStatus
sbrs R2,4
rjmp L55
.dbline 148
; LCDPrintf( LCDQueueStr1, LCDQueueStr2 );
ldi R18,<_LCDQueueStr2
ldi R19,>_LCDQueueStr2
ldi R16,<_LCDQueueStr1
ldi R17,>_LCDQueueStr1
call _LCDPrintf
L55:
.dbline 150
;
; CLEARBIT( LCDStatus, LCD_UPDATE );
lds R24,_LCDStatus
andi R24,253
sts _LCDStatus,R24
.dbline 151
; }
L54:
.dbline 153
;
; CLEARBIT( LCDStatus, LCD_BUSY );
lds R24,_LCDStatus
andi R24,251
sts _LCDStatus,R24
.dbline 154
; }
L47:
.dbline 155}
; }
L31:
ret
.dbfunc s WriteToDevice _WriteToDevice fI
; LCD_IO -> R20,R21
; select -> R18
; data -> R16
.even
_WriteToDevice::
call push_gset1
.dbline 159{
;
; /* writes to lcd */
; void WriteToDevice( char data, unsigned char select )
; {
.dbline 162
; char *LCD_IO;
;
; if ( select == INSTRUCTION ) /* set RS */
tst R18
brne L58
.dbline 163
; LCD_IO = ( char * ) 0x8000;
ldi R20,0
ldi R21,128
jmp L59
L58:
.dbline 165
; else
; LCD_IO = ( char * ) 0xC000;
ldi R20,0
ldi R21,192
L59:
.dbline 167
;
; *LCD_IO = data;
mov R30,R20
mov R31,R21
std z+0,R16
.dbline 168}
; }
L57:
call pop_gset1
ret
.dbsym r LCD_IO 20 pc
.dbsym r select 18 c
.dbsym r data 16 c
.dbfunc s CheckIfBusy _CheckIfBusy fI
.even
_CheckIfBusy::
.dbline 171{
;
; void CheckIfBusy( void )
; {
L61:
.dbline 172
L62:
.dbline 172
; while ( ReadDevice( INSTRUCTION ) & BUSY_FLAG );
clr R16
clr R17
call _ReadDevice
sbrc R16,7
rjmp L61
.dbline 173}
; }
L60:
ret
.dbfunc s ReadDevice _ReadDevice fI
; LCD_IO -> R20,R21
; select -> R16
.even
_ReadDevice::
call push_gset1
.dbline 177{
;
; /* reads from lcd */
; char ReadDevice( unsigned char select )
; {
.dbline 180
; char *LCD_IO;
;
; if ( select == INSTRUCTION ) /* set RS */
tst R16
brne L65
.dbline 181
; LCD_IO = ( char * ) 0x8000;
ldi R20,0
ldi R21,128
jmp L66
L65:
.dbline 183
; else
; LCD_IO = ( char * ) 0xC000;
ldi R20,0
ldi R21,192
L66:
.dbline 185
;
; return *LCD_IO;
mov R30,R20
mov R31,R21
ldd R16,z+0
clr R17
L64:
call pop_gset1
ret
.dbline 186}
.dbsym r LCD_IO 20 pc
.dbsym r select 16 c
.area bss
.dbfile C:\Documents\Software\AVR\lcd16x2\code\lcd.c
_LCDQueueStr2:
.blkb 17
.dbfile c:/documents/software/avr/lcd16x2/include/lcd.h
.dbsym s LCDQueueStr2 _LCDQueueStr2 Ac[17:17]
_LCDQueueStr1:
.blkb 17
.dbsym s LCDQueueStr1 _LCDQueueStr1 Ac[17:17]
_LCDStr2:
.blkb 17
.dbsym s LCDStr2 _LCDStr2 Ac[17:17]
_LCDStr1:
.blkb 17
.dbsym s LCDStr1 _LCDStr1 Ac[17:17]
_LCDLine:
.blkb 1
.dbsym s LCDLine _LCDLine c
_LCDCounter:
.blkb 1
.dbsym s LCDCounter _LCDCounter c
.area data
.dbfile c:/documents/software/avr/lcd16x2/include/lcd.h
L17:
.blkb 3
.area idata
.byte 37,'s,0
.area data
.dbfile c:/documents/software/avr/lcd16x2/include/lcd.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -