📄 lcd_1602_driver.s
字号:
.module LCD_1602_Driver.c
.area data(ram, con, rel)
_new::
.blkb 1
.area idata
.byte 32
.area data(ram, con, rel)
.dbfile E:\刻录的\电子技术\项目\电池放电器\软件V2.0\LCD_1602_Driver.c
.dbsym e new _new c
_num::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
.dbfile E:\刻录的\电子技术\项目\电池放电器\软件V2.0\LCD_1602_Driver.c
.dbsym e num _num i
.area text(rom, con, rel)
.dbfile E:\刻录的\电子技术\项目\电池放电器\软件V2.0\LCD_1602_Driver.c
.dbfunc e LCD_init _LCD_init fV
.even
_LCD_init::
.dbline -1
.dbline 21
; #include <iom8v.h>
; #include <macros.h>
; #include "discharge.h"
; #include "LCD_1602.h"
;
; unsigned char lcd_data[32];//32字节显存,记录LCD上显示的数据
; unsigned char data[32];//32字节缓存,保存将要写入LCD的数据
; unsigned char add;//显存地址标号
; unsigned char new=32;//显存标号
; unsigned int num=0;
; /**********************************************************
; TC1602B LCD DISPLAY
; 建立时间:2005年12月12号
; 修改日期:2005年12月12号
; LCD_write函数功能:当command=0时,向LCD写入数据,否则向LCD写
; 入命令
; LCD第一行显示寄存器地址:0X80-0X8F
; LCD第二行显示寄存器地址:0XC0-0XCF
; **********************************************************/
; void LCD_init(void)
; {
.dbline 22
; LCD_EN_DDR|=LCD_EN;//设定该引脚方向为输出
sbi 0x11,6
.dbline 23
; LCD_RS_DDR|=LCD_RS;//设定该引脚方向为输出
sbi 0x11,7
.dbline 24
; LCD_D4_DDR|=LCD_D4;//设定数据口为输出
sbi 0x11,5
.dbline 25
; LCD_D5_DDR|=LCD_D5;//设定数据口为输出
sbi 0x11,4
.dbline 26
; LCD_D6_DDR|=LCD_D6;//设定数据口为输出
sbi 0x11,3
.dbline 27
; LCD_D7_DDR|=LCD_D7;//设定数据口为输出
sbi 0x11,2
.dbline 29
;
; LCD_EN_PORT&=~LCD_EN;//EN设为低电平
cbi 0x12,6
.dbline 30
; LCD_RS_PORT&=~LCD_RS;//RS设为低电平
cbi 0x12,7
.dbline 31
; LCD_D4_PORT&=~LCD_D4;//数据口置低电平
cbi 0x12,5
.dbline 32
; LCD_D5_PORT&=~LCD_D5;//数据口置低电平
cbi 0x12,4
.dbline 33
; LCD_D6_PORT&=~LCD_D6;//数据口置低电平
cbi 0x12,3
.dbline 34
; LCD_D7_PORT&=~LCD_D7;//数据口置低电平
cbi 0x12,2
.dbline 36
;
; LCD_write_char(0,0x33); //4bit test
ldi R18,51
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 37
; delay_nms(25);
ldi R16,25
ldi R17,0
rcall _delay_nms
.dbline 38
; LCD_write_char(0,0x32);
ldi R18,50
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 39
; delay_nms(15);
ldi R16,15
ldi R17,0
rcall _delay_nms
.dbline 40
; LCD_write_char(0,0x28);
ldi R18,40
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 41
; delay_nms(15);
ldi R16,15
ldi R17,0
rcall _delay_nms
.dbline 42
; LCD_write_char(0,0x0C); //显示开
ldi R18,12
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 43
; delay_nms(15);
ldi R16,15
ldi R17,0
rcall _delay_nms
.dbline 44
; LCD_write_char(0,0x01); //显示清屏
ldi R18,1
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 45
; delay_nms(15);
ldi R16,15
ldi R17,0
rcall _delay_nms
.dbline 46
; LCD_write_char(0,0x06); //显示光标移动设置
ldi R18,6
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 47
; LCD_clear();
rcall _LCD_clear
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e LCD_write_char _LCD_write_char fV
; data -> R20,R21
; command -> R22,R23
.even
_LCD_write_char::
rcall push_gset2
movw R20,R18
movw R22,R16
.dbline -1
.dbline 56
; //LCD_init_CGRAM();
; }
; /*-----------------------------------------------------------------------
; LCD_write_char : 写一个字节到LCD的函数
; 编写日期 :2005-12-12
; 最后修改日期 :2005-12-12
; -----------------------------------------------------------------------*/
; void LCD_write_char(unsigned command,unsigned data)
; {
.dbline 57
; if (command == 0)
cpi R22,0
cpc R22,R23
brne L3
X0:
.dbline 58
; LCD_RS_PORT &= ~LCD_RS; //RS=0 写地址
cbi 0x12,7
rjmp L4
L3:
.dbline 60
; else
; LCD_RS_PORT |= LCD_RS; //RS=1 写数据
sbi 0x12,7
L4:
.dbline 62
;
; LCD_write_DATA_PORT(data);//写高4位
mov R16,R20
rcall _LCD_write_DATA_PORT
.dbline 63
; LCD_write_DATA_PORT(data<<4);//写低4位
mov R16,R20
lsl R16
rol R17
lsl R16
rol R17
lsl R16
rol R17
lsl R16
rol R17
rcall _LCD_write_DATA_PORT
.dbline 64
; delay_nus(250);
ldi R16,250
ldi R17,0
rcall _delay_nus
.dbline 65
; num++;//统计向LCD发送的字节数
lds R24,_num
lds R25,_num+1
adiw R24,1
sts _num+1,R25
sts _num,R24
.dbline -2
L2:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r data 20 i
.dbsym r command 22 i
.dbend
.dbfunc e LCD_write_DATA_PORT _LCD_write_DATA_PORT fV
; data -> R20
.even
_LCD_write_DATA_PORT::
rcall push_gset1
mov R20,R16
.dbline -1
.dbline 75
; }
; /*-----------------------------------------------------------------------
; LCD_write_DATA_PORT : 写数据到LCD数据口函数
;
; 输入参数data :要写入的数据(仅高4位)
; 编写日期 :2005-12-12
; 最后修改日期 :2005-12-12
; -----------------------------------------------------------------------*/
; void LCD_write_DATA_PORT(unsigned char data)
; {
.dbline 76
; if((data>>4)%2)
ldi R17,2
mov R16,R20
swap R16
andi R16,#0x0F
rcall mod8u
tst R16
breq L6
.dbline 77
; LCD_D4_PORT |=LCD_D4;
sbi 0x12,5
rjmp L7
L6:
.dbline 79
; else
; LCD_D4_PORT &=~LCD_D4;
cbi 0x12,5
L7:
.dbline 81
;
; if((data>>5)%2)
ldi R17,2
mov R16,R20
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
rcall mod8u
tst R16
breq L8
.dbline 82
; LCD_D5_PORT |=LCD_D5;
sbi 0x12,4
rjmp L9
L8:
.dbline 84
; else
; LCD_D5_PORT &=~LCD_D5;
cbi 0x12,4
L9:
.dbline 86
;
; if((data>>6)%2)
ldi R17,2
mov R16,R20
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
rcall mod8u
tst R16
breq L10
.dbline 87
; LCD_D6_PORT |=LCD_D6;
sbi 0x12,3
rjmp L11
L10:
.dbline 89
; else
; LCD_D6_PORT &=~LCD_D6;
cbi 0x12,3
L11:
.dbline 91
;
; if((data>>7)%2)
ldi R17,2
mov R16,R20
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
lsr R16
rcall mod8u
tst R16
breq L12
.dbline 92
; LCD_D7_PORT |=LCD_D7;
sbi 0x12,2
rjmp L13
L12:
.dbline 94
; else
; LCD_D7_PORT &=~LCD_D7;
cbi 0x12,2
L13:
.dbline 96
;
; LCD_EN_PORT |= LCD_EN; //EN端产生一个由低电平变高电平,写LCD
sbi 0x12,6
.dbline 97
; delay_nus(25);
ldi R16,25
ldi R17,0
rcall _delay_nus
.dbline 98
; LCD_EN_PORT &= ~LCD_EN; //EN端产生一个由高电平变低电平,写LCD
cbi 0x12,6
.dbline 99
; delay_nus(25);
ldi R16,25
ldi R17,0
rcall _delay_nus
.dbline -2
L5:
rcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbend
.dbfunc e LCD_clear _LCD_clear fV
; i -> R20
.even
_LCD_clear::
rcall push_gset1
.dbline -1
.dbline 109
; }
; /*-----------------------------------------------------------------------
; LCD_clear : 清除屏幕的函数
;
; 输入参数 :无
; 编写日期 :2005/10/18
; 说明 : lcd_data[]也会被清0
; -----------------------------------------------------------------------*/
; void LCD_clear(void)
; {
.dbline 111
; unsigned char i;
; LCD_write_char(0,0x01);//显示清屏
ldi R18,1
ldi R19,0
clr R16
clr R17
rcall _LCD_write_char
.dbline 112
; for(i=0;i<32;i++)
clr R20
rjmp L18
L15:
.dbline 113
.dbline 114
ldi R24,<_lcd_data
ldi R25,>_lcd_data
mov R30,R20
clr R31
add R30,R24
adc R31,R25
clr R2
std z+0,R2
.dbline 115
L16:
.dbline 112
inc R20
L18:
.dbline 112
cpi R20,32
brlo L15
.dbline 116
; {
; lcd_data[i]=0;
; }
; delay_nus(500);
ldi R16,500
ldi R17,1
rcall _delay_nus
.dbline -2
L14:
rcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbend
.dbfunc e LCD_write_string _LCD_write_string fV
; e -> R20
; s -> R22,R23
; y -> R18
; x -> R16
.even
_LCD_write_string::
rcall push_gset2
ldd R22,y+4
ldd R23,y+5
ldd R20,y+6
.dbline -1
.dbline 152
; }
; /*-----------------------------------------------------------------------
; LCD_check : 统计发送数据到LCD次数的函数
;
; 输入参数 :x,y 显示结果的座标
; 编写日期 :2005/10/18
; 说明 :如果每秒调用一次,就是统计每秒的次数
; -----------------------------------------------------------------------
; void LCD_check(unsigned char x,unsigned char y) //检测每秒钟写LCD
; //次数的函数
; {
; unsigned char i;
; unsigned char lcd[2]={0};
; add=y*16+x;//设置起始座标
; lcd[0]=num/10+48;
; lcd[1]=num%10+48;
; num=0;
; for (i=0;i<2;i++)
; {
; if(lcd_data[add]==lcd[i]){}
; else
; {data[add]=lcd[i];}
; add++;
; }
; LCD_updata;
; }*/
; /*-----------------------------------------------------------------------
; LCD_write_string : 英文字符串显示函数
;
; 输入参数:*s :英文字符串指针;
; X、Y : 显示字符串的位置
; e : 把从最后一个字符到x=e之间的内容删除
; 编写日期 :2005/10/18
; -----------------------------------------------------------------------*/
; void LCD_write_string(unsigned char x,unsigned char y, const unsigned char *s,unsigned char e)
; {
.dbline 153
; if(y<2)
cpi R18,2
brsh L23
.dbline 154
; add=y*16+x;//设置起始座标
ldi R24,16
mul R24,R18
mov R2,R0
add R2,R16
sts _add,R2
rjmp L23
L22:
.dbline 156
; while (*s)
; {
.dbline 157
; if(lcd_data[add]==*s)//如果LCD上显示的数和
ldi R24,<_lcd_data
ldi R25,>_lcd_data
lds R30,_add
clr R31
add R30,R24
adc R31,R25
ldd R2,z+0
movw R30,R22
lpm R30,Z
cp R2,R30
brne L25
.dbline 158
; {} //待写入的数相同的话
.dbline 158
rjmp L26
L25:
.dbline 159
; else{data[add]=*s;}//要显示的数据存入显存
.dbline 159
ldi R24,<_data
ldi R25,>_data
lds R30,_add
clr R31
add R30,R24
adc R31,R25
movw R26,R22
st -y,R31
st -y,R30
movw R30,R26
lpm R26,Z
ld R30,y+
ld R31,y+
std z+0,R26
.dbline 159
L26:
.dbline 160
subi R22,255 ; offset = 1
sbci R23,255
.dbline 161
lds R24,_add
subi R24,255 ; addi 1
sts _add,R24
.dbline 162
L23:
.dbline 155
movw R30,R22
lpm R30,Z
tst R30
brne L22
.dbline 163
; s ++;//指针加1
; add++;//显存地址加1
; }
; if(y==1)
cpi R18,1
brne L32
.dbline 164
; e+=16;
subi R20,240 ; addi 16
.dbline 165
; for(;e>=add;add++)
rjmp L32
L29:
.dbline 166
.dbline 166
ldi R24,<_data
ldi R25,>_data
lds R30,_add
clr R31
add R30,R24
adc R31,R25
ldi R24,32
std z+0,R24
.dbline 166
L30:
.dbline 165
lds R24,_add
subi R24,255 ; addi 1
sts _add,R24
L32:
.dbline 165
lds R2,_add
cp R20,R2
brsh L29
.dbline 167
; {data[add]=' ';}
; LCD_updata;
clr R2
sts _new,R2
.dbline -2
L19:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r e 20 c
.dbsym r s 22 pkc
.dbsym r y 18 c
.dbsym r x 16 c
.dbend
.area lit(rom, con, rel)
L34:
.byte 0
.byte 0,0,0,0,0,0,0,0,0
.area text(rom, con, rel)
.dbfile E:\刻录的\电子技术\项目\电池放电器\软件V2.0\LCD_1602_Driver.c
.dbfunc e LCD_write_number _LCD_write_number fV
; c -> R10
; b -> R12
; lcd -> y+0
; i -> R14
; e -> R6
; s -> R8,R9
; dat -> y+24
; d -> y+22
; y -> y+20
; x -> R14
.even
_LCD_write_number::
st -y,r19
st -y,r18
rcall push_gset5
mov R14,R16
sbiw R28,10
ldd R8,y+28
ldd R9,y+29
ldd R6,y+30
.dbline -1
.dbline 181
; }
; /*-----------------------------------------------------------------------
; LCD_write_number : 数字显示函数
;
; 输入参数:
; X、Y : 显示字符串的位置
; d :在第d位插入小数点
; data :要显示的数据 长整形
; *s :数据的单位
; e : 把从最后一个字符到x=e之间的内容删除
; 编写日期 :2005/10/18
; -----------------------------------------------------------------------*/
; void LCD_write_number(unsigned char x,unsigned char y,unsigned char d,unsigned long dat,const unsigned char *s,unsigned char e)
; {
.dbline 183
; unsigned char i;
; unsigned char b=0;
clr R12
.dbline 184
; unsigned char c='.';
ldi R24,46
mov R10,R24
.dbline 185
; unsigned char lcd[10]={0};
ldi R24,<L34
ldi R25,>L34
movw R30,R28
ldi R16,10
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
rcall asgncblk
.dbline 186
; if(y<2)//如果Y>1则不重新计算地址
ldd R24,y+20
cpi R24,2
brsh L35
.dbline 187
; add=y*16+x;//设置起始座标
ldi R24,16
ldd R0,y+20
mul R24,R0
mov R2,R0
add R2,R14
sts _add,R2
L35:
.dbline 189
;
; for (i=10;i>0;i--)
ldi R24,10
mov R14,R24
rjmp L40
L37:
.dbline 190
.dbline 191
ldi R20,10
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+24
ldd R3,z+25
ldd R4,z+26
ldd R5,z+27
st -y,R23
st -y,R22
st -y,R21
st -y,R20
movw R16,R2
movw R18,R4
rcall mod32u
movw R2,R16
movw R4,R18
ldi R20,48
ldi R21,0
ldi R22,0
ldi R23,0
add R2,R20
adc R3,R21
adc R4,R22
adc R5,R23
movw R24,R28
mov R30,R14
clr R31
add R30,R24
adc R31,R25
std z+0,R2
.dbline 192
ldi R20,10
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+24
ldd R3,z+25
ldd R4,z+26
ldd R5,z+27
st -y,R23
st -y,R22
st -y,R21
st -y,R20
movw R16,R2
movw R18,R4
rcall div32u
movw R30,R28
std z+24,R16
std z+25,R17
std z+26,R18
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -