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

📄 lcd.s

📁 使用iccavr的例子
💻 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 + -