📄 lcd12864.lst
字号:
__text_start:
__start:
0036 E5CF LDI R28,0x5F
0037 E0D2 LDI R29,2
0038 BFCD OUT 0x3D,R28
0039 BFDE OUT 0x3E,R29
003A 51C0 SUBI R28,0x10
003B 40D0 SBCI R29,0
003C EA0A LDI R16,0xAA
003D 8308 STD Y+0,R16
003E 2400 CLR R0
003F E6E0 LDI R30,0x60
0040 E0F0 LDI R31,0
0041 E010 LDI R17,0
0042 36E0 CPI R30,0x60
0043 07F1 CPC R31,R17
0044 F011 BEQ 0x0047
0045 9201 ST R0,Z+
0046 CFFB RJMP 0x0042
0047 8300 STD Z+0,R16
0048 E6EB LDI R30,0x6B
0049 E0F0 LDI R31,0
004A E6A0 LDI R26,0x60
004B E0B0 LDI R27,0
004C E010 LDI R17,0
004D 36EB CPI R30,0x6B
004E 07F1 CPC R31,R17
004F F021 BEQ 0x0054
0050 95C8 LPM
0051 9631 ADIW R30,1
0052 920D ST R0,X+
0053 CFF9 RJMP 0x004D
0054 D07C RCALL _main
_exit:
0055 CFFF RJMP _exit
_DelaymS:
j --> R20
k --> R22
i --> R16
0056 D099 RCALL push_gset2
FILE: E:\iccavr代码\实验五_12864汉显LCD模块\lcd12864.c
(0001) //******************************************************************************
(0002) // *
(0003) // FileName : 实验板12864lcd.c ICCAVR V6.31A编译 *
(0004) // Function : 1602字符型LCD的显示 (8位数据方式) *
(0005) // Date : 2006-12-14 *
(0006) // Version : 1.0 *
(0007) // *
(0008) // Author : 开关电源 hongtusy@163.com *
(0009) // Company : 电子信息技术咨询网 http://www.itsn.cn *
(0010) // *
(0011) //***************************描述与记事*****************************************
(0012) //实验板的AVR程序,驱动12864LCM(可显示4行,每行8个汉字)模块显示实验练习。
(0013) //说明:RS高显示/低指令输入 RW高读/低写 EN高读数据/下降沿写数据
(0014) //记事:本程序旨在对LCD驱动的理解与演示,程序适合初学者使用。
(0015) //具体电路可参照使用指南里的说明。共4×8个汉字。
(0016) //使用器件:ATMEGA8535,可更换。 使用默认的片内RC振荡器,1MHz。
(0017) //接线定义:PD4,5,6,7为RS,R/W,EA,RST(可不用)。数据位为PC口。
(0018) //使用的开关:SW2-1,2,3,4.SW1-1,2,3,4,5,6,7,8.SW2-5为背光开关。 SW3-8为系统复位端。
(0019) //PSB脚为串并行模式选择。SW2-7为高并行模式,SW2-8为低串行模式。
(0020) //记事:
(0021) //******************************************************************************
(0022) #include <string.h> //字符串操作函数库
(0023) #include <iom8535v.h> //头文件,ATmega8535单片机的寄存器定义
(0024) #include "macros.h" //可以使用NOP()以及SEI()等指令.
(0025)
(0026) typedef unsigned char uchar; //宏
(0027) typedef unsigned int uint;
(0028)
(0029) /************************************************
(0030) 函 数 名: DelaymS()
(0031) 功 能: 毫秒级延时函数
(0032) 输入参数: 延迟时间/系统晶体
(0033) 输出参数: 做相应的延迟处理
(0034) 描 述: /
(0035) ***********************************************/
(0036) void DelaymS (uint i) //延时函数,参数i为延时时间
(0037) {
(0038) uint j,k; //双重延时
(0039) for (j=0;j<i;j++)
0057 2744 CLR R20
0058 2755 CLR R21
0059 C00C RJMP 0x0066
(0040) {
(0041) for (k=0;k<=50;k++);
005A 2766 CLR R22
005B 2777 CLR R23
005C C002 RJMP 0x005F
005D 5F6F SUBI R22,0xFF
005E 4F7F SBCI R23,0xFF
005F E382 LDI R24,0x32
0060 E090 LDI R25,0
0061 1786 CP R24,R22
0062 0797 CPC R25,R23
0063 F7C8 BCC 0x005D
0064 5F4F SUBI R20,0xFF
0065 4F5F SBCI R21,0xFF
0066 1740 CP R20,R16
0067 0751 CPC R21,R17
0068 F388 BCS 0x005A
0069 D07E RCALL pop_gset2
006A 9508 RET
(0042) }
(0043) }
(0044) /************************************************
(0045) 函 数 名: init_mcu()
(0046) 功 能: 单片机初始化函数
(0047) 输入参数: /
(0048) 输出参数: /
(0049) 描 述: 相关口方向的设置等
(0050) ***********************************************/
(0051) void init_mcu(void)
(0052) {
(0053) DDRC = 0xff; //PC口为推挽1输出,数据位
_init_mcu:
006B EF8F LDI R24,0xFF
006C BB84 OUT 0x14,R24
(0054) DDRD = 0xff; //PD口为推挽1输出,控制信号
006D BB81 OUT 0x11,R24
006E 9508 RET
_write_data:
h --> R20
006F D082 RCALL push_gset1
0070 2F40 MOV R20,R16
(0055) }
(0056) /********************************************************
(0057) 子程序名: write_data()
(0058) 功 能: 写入一字节数据
(0059) 输入参数: /
(0060) 输出参数: /
(0061) 描 述: /
(0062) ********************************************************/
(0063) void write_data(uchar h)
(0064) {
(0065) PORTC = h; //先将数据送出
0071 BB45 OUT 0x15,R20
(0066) PORTD |= (1<<PD4); //RS=1,数据
0072 9A94 SBI 0x12,4
(0067) PORTD &= ~(1<<PD5); //R/W=0,写
0073 9895 CBI 0x12,5
(0068) PORTD &= ~(1<<PD6); //EN=0 ,使能,产生一个下降沿。
0074 9896 CBI 0x12,6
(0069) DelaymS (1);
0075 E001 LDI R16,1
0076 E010 LDI R17,0
0077 DFDE RCALL _DelaymS
(0070) PORTD |= (1<<PD6); //EN=1 ,除能
0078 9A96 SBI 0x12,6
0079 D07B RCALL pop_gset1
007A 9508 RET
_write_code:
h --> R20
007B D076 RCALL push_gset1
007C 2F40 MOV R20,R16
(0071) }
(0072) /********************************************************
(0073) 子程序名: write_code()
(0074) 功 能: 写入一字节指令/地址
(0075) 输入参数: /
(0076) 输出参数: /
(0077) 描 述: /
(0078) ********************************************************/
(0079) void write_code(uchar h)
(0080) {
(0081) PORTC = h; //先将地址送出
007D BB45 OUT 0x15,R20
(0082) PORTD &= ~(1<<PD4); //RS=0,命令或数据
007E 9894 CBI 0x12,4
(0083) PORTD &= ~(1<<PD5); //R/W=0,写
007F 9895 CBI 0x12,5
(0084) PORTD &= ~(1<<PD6); //EN=0 ,使能,产生一个下降沿。
0080 9896 CBI 0x12,6
(0085) DelaymS (1);
0081 E001 LDI R16,1
0082 E010 LDI R17,0
0083 DFD2 RCALL _DelaymS
(0086) PORTD |= (1<<PD6); //EN=1 ,除能
0084 9A96 SBI 0x12,6
0085 D06F RCALL pop_gset1
0086 9508 RET
(0087) }
(0088) /********************************************************
(0089) 子程序名: init_lcd()
(0090) 功 能: 初始化LCD
(0091) 输入参数: /
(0092) 输出参数: /
(0093) 描 述: /
(0094) ********************************************************/
(0095) void init_lcd(void)
(0096) {
(0097) PORTD &= ~(1<<PD7); //RS=0,低电平复位,然后变高后可以正常工作。也可以直接接高电平或NC不用。
_init_lcd:
0087 9897 CBI 0x12,7
(0098) DelaymS (1);
0088 E001 LDI R16,1
0089 E010 LDI R17,0
008A DFCB RCALL _DelaymS
(0099) PORTD |= (1<<PD7); //RS=1,开始工作
008B 9A97 SBI 0x12,7
(0100)
(0101) write_code(0x01); //清除屏幕
008C E001 LDI R16,1
008D DFED RCALL _write_code
(0102) write_code(0b00000011); //光标回到原点
008E E003 LDI R16,3
008F DFEB RCALL _write_code
(0103) write_code(0b00000111); //设定,光标右移,位址加一
0090 E007 LDI R16,7
0091 DFE9 RCALL _write_code
(0104) write_code(0b00001111); //显示状态开关,整体显示,光标显示,光标位置反白
0092 E00F LDI R16,0xF
0093 DFE7 RCALL _write_code
(0105) write_code(0b00010111); //光标向右移动
0094 E107 LDI R16,0x17
0095 DFE5 RCALL _write_code
(0106) write_code(0b00111011); //功能设定,8位数据口,基本指令集
0096 E30B LDI R16,0x3B
0097 DFE3 RCALL _write_code
0098 9508 RET
_display_lcd:
i --> R20
p --> R22
0099 D056 RCALL push_gset2
009A 01B8 MOVW R22,R16
(0107) //write_code(0b01000000); //设定CGRAM位址(列)
(0108) //write_code(0b10000000); //设定DDRAM位址(行)
(0109) }
(0110) /********************************************************
(0111) 子程序名: display_lcd()
(0112) 功 能: 刷新显示一屏数据,独立的LCD显示程序,用户将显存buf内容更新后,只要调用此程序即可更新显示。
(0113) 输入参数: 显存buf
(0114) 输出参数: /
(0115) 描 述: 在写一个字符前,先设定显示的位置地址,然后再写数据。系统可以自动地址加一。
(0116) 此12864LCD使用的是ST7920为驱动芯片。可以显示ASCII码的前128个值,此时为半字宽,数据为8位,
(0117) 即输入的8位数据的最高位为0,范围为0x00~0x7f,比如0x00为空格,0x61为小写字母a,0x7e为~。
(0118) 若最高位为1,则可以显示汉字,且此时为一个字宽,两个字节代表一个汉字。起始数据为0x8000,代表一个字的空格,
(0119) 0x8001代表汉字“啊”,0xffff代表汉字“翰”。
(0120) 也可以使用自定义字库或显示图片等。
(0121) ********************************************************/
(0122) void display_lcd(uchar *p)
(0123) {
(0124) uchar i;
(0125) write_code(0x80); //第一行起始地址,0b10000000B=0x80.即DDRAM位址
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -