;SMG12864C标准图形点阵型液晶显示模块的演示程序[ASM51编程语言][MCS51总线接口方式] ;应用产品: SMG12864C SMG12864BV SMG12864A SMG12864D3 标准图形点阵型液晶显示模块 ; 本演示程序适用于SMG12864C液晶显示模块与MCS51系列单片机采用MCS51总线的 ;硬件连线方式。 ; 本演示程序包括KS0108B兼容芯片的MCS51总线接口子程序集,KS0108B兼容芯片的12864 ;液晶显示模块的基本子程序,12864系列绘图子程序集,12864系列图形子程序集,12864系列 ;精简中英文字库子程序集,以及SMG12864C系列标准图形点阵型液晶显示的演示子程序. ; 本演示的内容为,在128列X64行的点阵液晶显示屏上清屏,图片演示,英文字符串演示, ;中文字符串演示,反白显示字符串,绘制矩形,写点,绘制直线,全屏显示. ;------------------------------------------------------------------------------- ;创建日期: 2009.08.31 ;软件环境: VW For Windows ;硬件环境: AT89C52 MCU,MCS-51系列 MCU,etc. ;创建人: 褚建军(chujianjun@sunman.cn),谭超(tanchao@sunman.cn). ;技术支持: 电话(0731-84167806,84167807),传真(0731-84167807),网址(www.sunman.cn) ;版权信息: 长沙太阳人电子有限公司版权所有,转载请指明出处. ;参考网页: http:/www.sunman.cn/lcm/product/SMG12864C.html ;------------------------------------------------------------------------------- ;SMG12864C产品引脚说明及演示连线 ;PIN1: VSS [电源地] ;PIN2: VDD [电源正极] ;PIN3: Vo [LCD偏压输入] ;PIN4: RS [数据/命令选择端 1:数据 0:命令] ;PIN5: RW [读写信号选择端 1:读操作 0:写操作] ;PIN6: E [使能信号输入 高有效] ;PIN7: DB0 [Data I/O] ;PIN8: DB1 [Data I/O] ;PIN9: DB2 [Data I/O] ;PIN10:DB3 [Data I/O] ;PIN11:DB4 [Data I/O] ;PIN12:DB5 [Data I/O] ;PIN13:DB6 [Data I/O] ;PIN14:DB7 [Data I/O] ;PIN15:CS1 [片选1信号输入 高有效] ;PIN16:CS2 [片选2信号输入 高有效] ;PIN17:RST [复位信号输入(H:正常工作,L:复位)] ;PIN18:VEE [LCD驱动负压输出(-10V)] ;PIN19:EL-E [EL 使能端(低电平有效)] ;PIN20:NC [空脚] ;注:8031的晶振频率为12MHz. ;请参见http://download.sunman.cn/lcm/product/1/SMG12864C.pdf ;------------------------------------------------------------------------------- ;以下为产品接口引脚在演示程序中的预定义 ;用户在编写应用程序时,需按自己的实际硬件连线来重新定义 ;以下CS(P2.7)=1 LCDC1RADDR EQU 8C00H ;地址CS1(P2.2)=1,RS(P2.0)=0,RW(P2.3)=1 LCDC1WADDR EQU 8400H ;地址CS1(P2.2)=1,RS(P2.0)=0,RW(P2.3)=0 LCDC2RADDR EQU 8A00H ;地址CS2(P2.1)=1,RS(P2.0)=0,RW(P2.3)=1 LCDC2WADDR EQU 8200H ;地址CS2(P2.1)=1,RS(P2.0)=0,RW(P2.3)=0 LCDD1RADDR EQU 8D00H ;地址CS1(P2.2)=1,RS(P2.0)=1,RW(P2.3)=1 LCDD1WADDR EQU 8500H ;地址CS1(P2.2)=1,RS(P2.0)=1,RW(P2.3)=0 LCDD2RADDR EQU 8B00H ;地址CS2(P2.1)=1,RS(P2.0)=1,RW(P2.3)=1 LCDD2WADDR EQU 8300H ;地址CS2(P2.1)=1,RS(P2.0)=1,RW(P2.3)=0 ;------------------------------------------------------------------------------- ;以下XPOS,YPOS变量用于指示当前操作点的位置的预定义 ;用户在编写应用程序时,需按自己的实际软件程序需要来重新定义 XPOS EQU 20H ;列方向LCD点阵位置指针 YPOS EQU 21H ;行方向LCD点阵位置指针 LCDBITMASK EQU 22H ;PUTSIZEIMAGE,POINT保留变量 CHARIMAGEREVERSE EQU 23H ;字符及图形的反显控制,0(正常显示),1(反显) XDOTS EQU 128 ;图形空间X方向大小 YDOTS EQU 64 ;图形空间Y方向大小 ;------------------------------------------------------------------------------- ORG 0000H ; JMP START ;------------------------------------------------------------------------------- ;以下为精简版中英文字库 ;实际使用时请包含由Sunman精简版中英文字符库代码生成器.exe自动生成的CHARLIB.ASM文 ;文件来替换该部分 ENGLISHCHARNUMBER EQU 5 ;精简版英文字符库中的英文字符的个数 CHINESECHARNUMBER EQU 5 ;精简版中文字符库中的中文字符的个数 ENGLISHCHARSIZE EQU 8 ;英文字符X方向显示点的个数 CHINESECHARSIZE EQU 16 ;中文字符X方向及中英文字符Y方向显示点的个数 ENGLISHCHARDOTSIZE EQU 16 ;单个英文字符点阵的字节数 CHINESECHARDOTSIZE EQU 32 ;单个中文字符点阵的字节数 ENGLISHCODETAB: ;精简版英文字符库的字符代码表 DB 041H ;字符001:[A] DB 04dH ;字符002:[M] DB 04eH ;字符003:[N] DB 053H ;字符004:[S] DB 055H ;字符005:[U] CHINESECODETAB: ;精简版中文字符库的字符代码表 DW 0b5e7H ;字符001:[电] DW 0c8cbH ;字符002:[人] DW 0ccabH ;字符003:[太] DW 0d1f4H ;字符004:[阳] DW 0d7d3H ;字符005:[子] ENGLISHCHARDOTTAB: ;精简版英文字符库的字符点阵表 DB 000H,020H,000H,03cH,0c0H,023H,038H,002H ;字符001:[A] DB 0e0H,002H,000H,027H,000H,038H,000H,000H DB 008H,020H,0f8H,03fH,0f8H,000H,000H,03fH ;字符002:[M] DB 0f8H,000H,0f8H,03fH,008H,020H,000H,000H DB 008H,020H,0f8H,03fH,030H,020H,0c0H,000H ;字符003:[N] DB 000H,007H,008H,018H,0f8H,03fH,000H,000H DB 000H,000H,070H,038H,088H,020H,008H,021H ;字符004:[S] DB 008H,021H,008H,022H,038H,01cH,000H,000H DB 008H,000H,0f8H,01fH,008H,020H,000H,020H ;字符005:[U] DB 000H,020H,008H,020H,0f8H,01fH,000H,000H CHINESECHARDOTTAB: ;精简版中文字符库的字符点阵表 DB 000H,000H,000H,000H,0f8H,00fH,048H,004H ;字符001:[电] DB 048H,004H,048H,004H,048H,004H,0ffH,03fH DB 048H,044H,048H,044H,048H,044H,048H,044H DB 0f8H,04fH,000H,040H,000H,070H,000H,000H DB 000H,000H,000H,040H,000H,020H,000H,010H ;字符002:[人] DB 000H,00cH,000H,003H,0c0H,000H,03fH,000H DB 0c2H,001H,000H,006H,000H,00cH,000H,018H DB 000H,030H,000H,060H,000H,020H,000H,000H DB 000H,000H,010H,080H,010H,040H,010H,020H ;字符003:[太] DB 010H,010H,010H,00cH,010H,003H,0ffH,008H DB 010H,071H,010H,022H,010H,004H,010H,018H DB 010H,030H,010H,0e0H,010H,040H,000H,000H DB 000H,000H,0feH,0ffH,002H,004H,022H,008H ;字符004:[阳] DB 05aH,004H,086H,003H,000H,000H,0feH,03fH DB 042H,010H,042H,010H,042H,010H,042H,010H DB 042H,010H,0feH,03fH,000H,000H,000H,000H DB 000H,001H,000H,001H,002H,001H,002H,001H ;字符005:[子] DB 002H,001H,002H,041H,002H,081H,0e2H,07fH DB 012H,001H,00aH,001H,006H,001H,002H,001H DB 000H,001H,080H,001H,000H,001H,000H,000H ;------------------------------------------------------------------------------- ;以下为图片库点阵代码 ;实际使用时请包含由SUNMAN图形点阵代码生成器.EXE自动生成的IMAGELIB.ASM文件来替换该 ;部分 IMG_sunman_32TAB: DB 32,32 DB 000H,0f0H,00fH,000H DB 000H,0feH,07fH,000H DB 080H,00fH,0f6H,001H DB 0c0H,003H,0c6H,003H DB 0e0H,070H,00eH,007H DB 070H,07cH,03eH,00eH DB 038H,07fH,0feH,01cH DB 09cH,07fH,0feH,039H DB 0ccH,07fH,0feH,033H DB 0ceH,07fH,0feH,073H DB 0e6H,07fH,0feH,067H DB 0e6H,007H,0e0H,067H DB 0f3H,007H,0e0H,0cfH DB 0f3H,0cfH,0ffH,0cfH DB 073H,09eH,0ffH,0cfH DB 033H,03cH,0ffH,0cfH DB 033H,03cH,0ffH,0cfH DB 073H,09eH,0ffH,0cfH DB 0f3H,0cfH,0ffH,0cfH DB 0f3H,007H,0e0H,0cfH DB 0e6H,007H,0e0H,067H DB 0e6H,07fH,0feH,067H DB 0ceH,07fH,0feH,073H DB 0ccH,07fH,0feH,033H DB 09cH,07fH,0feH,039H DB 038H,07fH,0feH,01cH DB 070H,07cH,03eH,00eH DB 0e0H,070H,00eH,007H DB 0c0H,063H,0c0H,003H DB 080H,06fH,0f0H,001H DB 000H,0feH,07fH,000H DB 000H,0f0H,00fH,000H ;------------------------------------------------------------------------------- START: MOV SP,#60H MAIN: CALL LCDRESET ;LCD显示初始化子程序 CALL EXSAMPLE ;演示程序 JMP MAIN STR1: DB "SUNMAN",0 STR2: DB "太阳人电子",0 EXSAMPLE: ;演示程序 ;0.演示前的准备,将LCD液晶显示全部清空 MOV CHARIMAGEREVERSE,#0 ;反显关闭 MOV A,#0 ;清屏 CALL LCDFILL ;1.图片测试: 在(8,16)位置显示32点阵SUNMAN图标 MOV XPOS,#8 ;起始位置为第9列 MOV YPOS,#16 ;起始位置为第17行 MOV DPTR,#IMG_sunman_32TAB ; CALL PUTIMAGE ;显示图象 CALL EXDELAY ;延时约600mS ;2.字符串测试: 在(56,16)位置显示"SUNMAN"字符串. MOV XPOS,#56 ;起始位置为第57列 MOV YPOS,#16 ;起始位置为第17行 MOV DPTR,#STR1 ; CALL PUTSTR ;显示字符串 CALL EXDELAY ;延时约600mS ;3.字符串测试: 在(40,32)位置显示"太阳人电子"字符串. MOV XPOS,#40 ;起始位置为第41列 MOV YPOS,#32 ;起始位置为第33行 MOV DPTR,#STR2 ; CALL PUTSTR ;显示字符串 CALL EXDELAY ;延时约600mS ;4.反显测试: 在(40,32)位置反显"太阳人电子"字符串. MOV XPOS,#40 ;起始位置为第41列 MOV YPOS,#32 ;起始位置为第33行 MOV CHARIMAGEREVERSE,#1 MOV DPTR,#STR2 ; CALL PUTSTR ;显示字符串 MOV CHARIMAGEREVERSE,#0 CALL EXDELAY ;延时约600mS ;5.绘图测试: RECT(6,14)-(122,50),画矩形. MOV R4,#6 ; MOV R5,#14 MOV R6,#122 MOV R7,#50 MOV R1,#1 CALL RECT CALL EXDELAY ;延时约600mS ;6.绘图测试: POINT(6,52),画点. MOV XPOS,#6 ; MOV YPOS,#52 MOV R1,#1 CALL POINT CALL EXDELAY ;延时约600mS ;7.绘图测试: LINE(6,52)-(63,63),画线. MOV R4,#6 ; MOV R5,#52 MOV R6,#63 ; MOV R7,#63 MOV R1,#1 CALL LINE CALL EXDELAY ;延时约600mS ;8.绘图测试: LINETO(122,52),画线. MOV R6,#122 ; MOV R7,#52 MOV R1,#1 CALL LINETO CALL EXDELAY ;延时约600mS ;9.绘图测试: LINETO(6,52),画线. MOV R6,#6 ; MOV R7,#52 MOV R1,#1 CALL LINETO CALL EXDELAY ;延时约600mS ;10.全屏测试: 所有坐标点全部显示. MOV A,#0FFH ;全显 CALL LCDFILL CALL EXDELAY ;延时约600mS RET EXDELAY: ;示例延时子程序 MOV R2,#60 ;延时约1S EDY_PA: MOV R1,#100 EDY_PB: MOV R0,#49 DJNZ R0,$ DJNZ R1,EDY_PB DJNZ R2,EDY_PA RET ;------------------------------------------------------------------------------- ;以下PUTCHAR为字符对象的基本子程序,PUTSTR为字符对象的扩充子程序,GETSTRCHAR, ;GETCHINESECODE,GETCHINESECODECMP,GETENGLISHCODE为字符对象的辅助子程序. ;------------------------------------------------------------------------------- ;子程序名称:PUTCHAR(A,B). ;功能:写单个字符点阵,若B>127且A>127 表示为中文字符 此时中文字符码为A/B;否则为西 ; 文字符A. ;输入:A/B表示中文字符码 或 A表示ASCII西文字符码. ;输出:. ;影响:R0,R1,R2,R3,R4,R5,R6,R7,A,B. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- PUTCHAR: ;定位写字符子程序 PUSH DPL PUSH DPH JNB ACC.7,PSR_LBY JNB B.7,PSR_LBY ;CHINESE: CALL GETCHINESECODEPOS ;定位中文字库位置 MOV R6,#CHINESECHARSIZE ;写中文字符点阵 MOV R7,#CHINESECHARSIZE CALL PUTSIZEIMAGE JMP PSR_LBX PSR_LBY: ;ENGLISH: CALL GETENGLISHCODEPOS ;定位西文字库位置 MOV R6,#ENGLISHCHARSIZE ;写西文字符点阵 MOV R7,#CHINESECHARSIZE CALL PUTSIZEIMAGE PSR_LBX: POP DPH POP DPL RET ;------------------------------------------------------------------------------- ;子程序名称:PUTSTR(*S). ;功能:写字符串点阵,若*S=0 表示字符串结束. ;输入:*S. ;输出:. ;影响:R0,R1,R2,R3,R4,R5,R6,R7,A,B. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- PUTSTR: ;显示字符串子程序,字符码为0时退出 CALL GETSTRCHAR JZ PSR_LAX CALL PUTCHAR JMP PUTSTR PSR_LAX: RET ;------------------------------------------------------------------------------- ;子程序名称:GETSTRCHAR(*S). ;功能:读单个字符串字符代码,本子程序仅供PUTSTR使用,若*S<128 表示字符为ASCII码, ; A=*S后退出;否则表示为中文汉字代码,B=*S后,再读一个字符置入A中. ;输入:*S(DPTR). ;输出:. ;影响:R0,R1,R2,R3,R4,R5,R6,R7,A,B. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- GETSTRCHAR: ;字符串中取字符码子程序 GSC_PA: CLR A MOVC A,@A+DPTR INC DPTR JNB ACC.7,GSC_LAX MOV B,A CLR A MOVC A,@A+DPTR INC DPTR GSC_LAX: RET ;------------------------------------------------------------------------------- ;子程序名称:GETCHINESECODEPOS(A,B). ;功能:根据当前中文字符码查表后计算得到当前中文字符码的字库点阵位置. ;输入:当前中文字符码=A/B[L/H]. ;输出:DPTR=*S,R0/R1=A/B. ;影响:R0,R2,R3,R4,R5,R6,R7,A,B. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- GETCHINESECODEPOS: ;根据当前中文字符码设置字库点阵位置子程序 MOV R0,A ;当前字符码置入[R0/R1] MOV R1,B ; MOV R2,#00H ;小值[R2/R3]置0 MOV R3,#00H ; MOV R4,#(CHINESECHARNUMBER-1)%256;大值[R4/R5]置为最后一个位置 MOV R5,#(CHINESECHARNUMBER-1)/256; ;折半查找搜索当前值 GCI_PA: CLR C ;MAX-MIN<->2 MOV A,R4 SUBB A,R2 MOV B,A MOV A,R5 SUBB A,R3 CLR C XCH A,B SUBB A,#2 MOV A,B SUBB A,#0 ; JNC GCI_LAX ;MAX-MIN>=2 ;MAX-MIN<2 MOV A,R2 ;MID=MIN MOV R6,A MOV A,R3 MOV R7,A CALL GETCHINESECODECMP ;MIDCODE<->CURCODE JZ GCI_PAX ;MIDCODE=CURCODE,搜索完成 MOV A,R4 ;MID=MAX MOV R6,A MOV A,R5 MOV R7,A CALL GETCHINESECODECMP ;MIDCODE<->CURCODE JZ GCI_PAX ;MIDCODE=CURCODE,搜索完成 NOP ;CURCODE字符不在字库表中 MOV R6,#00H ;用户可在此设置断点,若程序执行到此 MOV R7,#00H ;请重新生成包含该字符字库文件 JMP GCI_PAX GCI_LAX: MOV A,R4 ;MID=(MIN+MAX)/2 ADD A,R2 MOV R6,A MOV A,R5 ADDC A,R3 RRC A MOV R7,A MOV A,R6 RRC A MOV R6,A ; CALL GETCHINESECODECMP ;MIDCODE<->CURCODE JZ GCI_PAX ;MIDCODE=CURCODE,搜索完成 JC GCI_LBY ;MIDCODECURCODE CLR C ;MAX=MID-1 MOV A,R6 SUBB A,#1 MOV R4,A MOV A,R7 SUBB A,#0 MOV R5,A ; JMP GCI_LBX GCI_LBY: ;MIDCODECURCODE SUBB A,R0 XCH A,B SUBB A,R1 ORL A,B RET ;------------------------------------------------------------------------------- ;子程序名称:GETENGLISHCODEPOS(A). ;功能:根据当前ASCII字符码查表后计算得到当前ASCII字符码的字库点阵位置. ;输入:当前ASCII字符码=A. ;输出:DPTR=*S. ;影响:R0,R2,R3,R4,R5,R6,R7,A,B. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- GETENGLISHCODEPOS: ;根据当前ASCII字符码设置字库点阵位置子程序 MOV R0,A ;当前字符码置入[R0] MOV R2,#00H ;MIN[R2]置0 MOV R4,#ENGLISHCHARNUMBER-1 ;MAX[R4]置为最后一个位置 ;折半查找搜索当前值 GEI_PA: CLR C ;MAX-MIN<->2 MOV A,R4 SUBB A,R2 SUBB A,#2 JNC GEI_LAX ;MAX-MIN>=2 ;MAX-MIN<2 MOV DPTR,#ENGLISHCODETAB ;A=MIDCODE MOV A,R2 ;MID=MIN MOV R6,A MOVC A,@A+DPTR ;MIDCODE<->CURCODE XRL A,R0 JZ GEI_PAX ;MIDCODE=CURCODE,搜索完成 MOV A,R4 ;MID=MAX MOV R6,A MOVC A,@A+DPTR ;MIDCODE<->CURCODE XRL A,R0 JZ GEI_PAX ;MIDCODE=CURCODE,搜索完成 NOP ;CURCODE字符不在字库表中 MOV R6,#00H ;用户可在此设置断点,若程序执行到此 ;请重新生成包含该字符字库文件 JMP GEI_PAX GEI_LAX: MOV A,R4 ;MID[R6]=(MIN+MAX)/2 ADD A,R2 RRC A MOV R6,A ; MOV DPTR,#ENGLISHCODETAB ;A=MIDCODE MOV A,R6 MOVC A,@A+DPTR ; CLR C ;MIDCODE<->CURCODE SUBB A,R0 JZ GEI_PAX ;MIDCODE=CURCODE,搜索完成 JC GEI_LBY ;MIDCODECURCODE MOV A,R6 ;MAX=MID-1 MOV R4,A DEC R4 ; JMP GEI_LBX GEI_LBY: ;MIDCODE0,则R1=LCDBITMASK JMP PIT_LAX PIT_LAY:MOV R1,LCDBITMASK PIT_LAX: XRL LCDBITMASK,#0FFH ;LCDBITMASK=~LCDBITMASK CALL LCDPOS ;绘图地址指针定位 CALL LCDRD ;读数据到A ANL A,LCDBITMASK ;清待写点位置的数据 ORL A,R1 ;置待写点位置的数据 CALL LCDPOS ;绘图地址指针再定位 CALL LCDWD ;写待写点位置的数据 RET ;------------------------------------------------------------------------------- ;子程序名称:LINE(X0,Y0,X1,Y1,BITDATA) ;功能:按BITDATA的数据绘制(X0,Y0)-(X1,Y1)的直线 ;输入:BITDATA=R1,X0=R4,Y0=R5,X1=R6,Y1=R7 ;输出:XPOS=X1,YPOS=Y1 ;影响:R0,R1,R2,R3,A ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LINE: MOV A,R4 ;置当前操作的坐标=(R4,R5) MOV XPOS,A MOV A,R5 MOV YPOS,A ; CALL POINT ;写初始点(X0,Y0) CLR C ;R2=ABS(X1-X0) MOV A,R6 SUBB A,R4 JNC LXY_LAX CLR C MOV A,R4 SUBB A,R6 LXY_LAX:MOV R2,A ; CLR C ;R3=ABS(Y1-Y0) MOV A,R7 SUBB A,R5 JNC LXY_LBX CLR C MOV A,R5 SUBB A,R7 LXY_LBX:MOV R3,A ; CLR C SUBB A,R2 JNC LXY_LCY ;ABS(Y1-Y0)>=ABS(X1-X0) ;ABS(X1-X0)>ABS(Y1-Y0) MOV A,#8 ;R3(K)=R3*256/R2 MOV R0,A MOV B,#00H LXY_PB: CLR C MOV A,B RLC A MOV B,A MOV A,R3 RLC A MOV R3,A JC LXY_LDY SUBB A,R2 JC LXY_LDX LXY_LDY: CLR C MOV A,R3 SUBB A,R2 MOV R3,A INC B LXY_LDX:DJNZ R0,LXY_PB MOV A,B MOV R3,A ; MOV B,#00H ;B=0 为位置小数字节 LXY_PA: CLR C ;X1<->X0 MOV A,R6 SUBB A,R4 JC LXY_LGY ;X1=X0 INC XPOS JMP LXY_LGX LXY_LGY: ;X1Y0 MOV A,R7 SUBB A,R5 JC LXY_LFY ;Y1=Y0 MOV A,B ;YPOS=YPOS+K ADD A,R3 MOV B,A MOV A,YPOS ADDC A,#00H MOV YPOS,A ; JNB B.7,$+5 ;如果B>127,则四舍五入,YPOS加1 INC YPOS ; CALL POINT ;写点 CJNE R2,#01H,$+5 ;如果是最后一个点,则不减回四舍五入的数 AJMP LXY_LFX ; JNB B.7,$+5 ;如果B>127,则将四舍五入的数减掉,YPOS减1 DEC YPOS ; JMP LXY_LFX LXY_LFY: ;Y1127,则四舍五入,YPOS加1 INC YPOS ; CALL POINT ;写点 CJNE R2,#01H,$+5 ;如果是最后一个点,则不减回四舍五入的数 AJMP LXY_LFX ; JNB B.7,$+5 ;如果B>127,则将四舍五入的数减掉,YPOS减1 DEC YPOS ; LXY_LFX: DJNZ R2,LXY_PA ;按X方向循环写点 JMP LXY_LCX LXY_LCY: ;ABS(Y1-Y0)>=ABS(X1-X0) MOV A,R3 JZ LXY_LCX ;ABS(Y1-Y0)=0 直接退出 MOV A,#8 ;R2(K)=R2*256/R3 MOV R0,A MOV B,#00H LXY_PC: CLR C MOV A,B RLC A MOV B,A MOV A,R2 RLC A MOV R2,A JC LXY_LHY SUBB A,R3 JC LXY_LHX LXY_LHY: CLR C MOV A,R2 SUBB A,R3 MOV R2,A INC B LXY_LHX:DJNZ R0,LXY_PC MOV A,B MOV R2,A ; MOV B,#00H ;B=0 为位置小数字节 LXY_PD: CLR C ;Y1<->Y0 MOV A,R7 SUBB A,R5 JC LXY_LJY ;Y1=Y0 INC YPOS JMP LXY_LJX LXY_LJY: ;Y1X0 MOV A,R6 SUBB A,R4 JC LXY_LIY ;X1=X0 MOV A,B ;XPOS=XPOS+K ADD A,R2 MOV B,A MOV A,XPOS ADDC A,#00H MOV XPOS,A ; JNB B.7,$+5 ;如果B>127,则四舍五入,XPOS加1 INC XPOS ; CALL POINT ;写点 CJNE R3,#01H,$+5 ;如果是最后一个点,则不减回四舍五入的数 AJMP LXY_LIX ; JNB B.7,$+5 ;如果B>127,则将四舍五入的数减掉,XPOS减1 DEC XPOS ; JMP LXY_LIX LXY_LIY: ;X1127,则四舍五入,XPOS加1 INC XPOS ; CALL POINT ;写点 CJNE R3,#01H,$+5 ;如果是最后一个点,则不减回四舍五入的数 AJMP LXY_LIX ; JNB B.7,$+5 ;如果B>127,则将四舍五入的数减掉,XPOS减1 DEC XPOS ; LXY_LIX: DJNZ R3,LXY_PD LXY_LCX: RET ;------------------------------------------------------------------------------- ;子程序名称:LINETO(X1,Y1,BITDATA) ;功能:按BITDATA的数据绘制(XPOS,YPOS)-(X1,Y1)的直线 ;输入:BITDATA=A,X1=R6,Y1=R7 ;输出:XPOS=X1,YPOS=Y1,R4=初始点的XPOS,R5=初始点的YPOS ;影响:R0,R1,R2,R3,R4,R5,A ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LINETO: ;绘制(XPOS,YPOS)-(X1,Y1)的直线, MOV A,XPOS MOV R4,A MOV A,YPOS MOV R5,A CALL LINE RET ;------------------------------------------------------------------------------- ;子程序名称:RECT(X0,Y0,X1,Y1,BITDATA) ;功能:按BITDATA的数据绘制(X0,Y0)-(X1,Y1)的矩形 ;输入:BITDATA=R1,X0=R4,Y0=R5,X1=R6,Y1=R7 ;输出:XPOS=X1,YPOS=Y1 ;影响:R0,R1,R2,R3,A ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- RECT: ;绘制(X0,Y0)-(X1,Y1)的矩形 MOV A,R7 ; PUSH ACC ;STACK:Y1 MOV A,R5 MOV R7,A CALL LINE ;(X0,Y0)-(X1,Y0) POP ACC ;Y1 MOV R7,A MOV A,R4 PUSH ACC ;STACK:X0 MOV A,R6 MOV R4,A CALL LINE ;(X1,Y0)-(X1,Y1) POP ACC ;X0 MOV R6,A MOV A,R5 PUSH ACC ;STACK:Y0 MOV A,R7 MOV R5,A CALL LINE ;(X1,Y1)-(X0,Y1) POP ACC ;Y0 MOV R7,A MOV A,R4 PUSH ACC ;STACK:X1 MOV A,R6 MOV R4,A CALL LINE ;(X0,Y1)-(X0,Y0) POP ACC ;X1 MOV R6,A MOV A,R5 XCH A,R7 MOV R5,A ;(X0,Y0),(X1,Y1) RET ;------------------------------------------------------------------------------- ;以下PUTSIZEIMAGE为图形对象的基本子程序,PUTIMAGE为图形对象的扩充子程序 ;------------------------------------------------------------------------------- ;子程序名称:PUTSIZEIMAGE(XPOS,YPOS,XSIZE,YSIZE,*S). ;功能:在(XPOS,YPOS)位置绘制XSIZE列及YISZE行点阵的图形*S. ;输入:位置XPOS,YPOS;XSIZE=R6,YSIZE=R7,S=DPTR. ;输出:XPOS=XPOS+XSIZE;如果XPOS>=XDOTS 则XPOS=0,YPOS=YPOS+YSIZE. ;影响:R0,R1,R2,R3,R4,R5,R6,R7. ;修改日期:2009.8.28 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- PUTSIZEIMAGE: ;显示图形子程序 ;图形的大小,XSIZE=R6,YSIZE=R7 ;图形的大小循环变量LX=R4,LY=R5 ;图形数据1变量A1=R1,图形数据2变量A2=R2 MOV A,YPOS ;第一列数据的BIT位移变量K=R3 ANL A,#07H ;K=YPOS&0X7 MOV R3,A ; MOV A,R7 ;YSIZE+=K ADD A,R3 MOV R7,A ; MOV R5,#00H ;LX=0 CLR C ;DPTR到前一个字节 MOV A,DPL SUBB A,#1 MOV DPL,A MOV A,DPH SUBB A,#0 MOV DPH,A ; PIM_PA: PUSH YPOS ;保存YPOS位置,准备进行一行数据的处理 MOV A,R3 ;LY=K MOV R4,A MOV R1,#00H ;A1=0 PIM_PB: ;写一行图形数据 CLR A ;A1=*S MOVC A,@A+DPTR MOV R1,A INC DPTR ;S++ CLR A ;A2=*S MOVC A,@A+DPTR MOV R2,A MOV A,CHARIMAGEREVERSE ; JZ PIM_LFX ; MOV A,R1 ;反显 XRL A,#0FFH ;A1=~A1 MOV R1,A MOV A,R2 ;A2=~A2 XRL A,#0FFH MOV R2,A PIM_LFX: MOV A,R3 ;如果K=0 则不进行数据处理 JZ PIM_LAY PUSH ACC ;保存K的值 PIM_PC: ;按K的位置将数据进行移位对齐处理 CLR C MOV A,R1 ;移位处理后,A2的数据为有效字节 RRC A MOV R1,A MOV A,R2 RRC A MOV R2,A DJNZ R3,PIM_PC POP ACC ;恢复K的值 MOV R3,A JMP PIM_LAX ;需读液晶显示控制器中RAM的值 PIM_LAY: CLR C ;YSIZE与LY比较 MOV A,R7 SUBB A,R4 CLR C SUBB A,#8 JC PIM_LAX ;YSIZE<(LY+8) LY+8变量超出范围 ;YSIZE>=(LY+8):K=0且为中间字节,不需读原来 ;液晶显示控制器中的数据,直接送数 CALL LCDPOS ;绘图地址指针定位 MOV A,R4 ;LY+=8 ADD A,#08H MOV R4,A MOV A,YPOS ;YPOS+=8 ADD A,#08H MOV YPOS,A MOV A,R2 JMP PIM_LEX PIM_LAX: CALL LCDPOS ;绘图地址指针定位 CALL LCDRD ; MOV R1,A ;A1=LCDRD() CALL LCDPOS ;绘图地址指针定位 MOV LCDBITMASK,#0FFH ;LCDBITMASK初始值为0FFH MOV A,R4 ;LY+=8 ADD A,#08H MOV R4,A MOV A,YPOS ;YPOS+=8 ADD A,#08H MOV YPOS,A MOV A,R4 ;LY&7是否为零,表示左边界是否为字节字位的 ANL A,#07H ;开始 JZ PIM_LBX ;LY&7=0 表示左边界是字节字位的开始 ;LY&7=1 表示左边界不是字节字位的开始 MOV R0,A ;LCDMASK>>(LX&7) PIM_PD: CLR C MOV A,LCDBITMASK RRC A MOV LCDBITMASK,A DEC R4 ;LY-=K DEC YPOS ;YPOS-=K DJNZ R0,PIM_PD PIM_LBX: MOV R0,#0FFH ;R0=RIGHTMASK[P] PIM_PE: CLR C ;YSIZE与LY比较 MOV A,R7 SUBB A,R4 JNC PIM_PEX ;YSIZE>=LY ;YSIZELY PIM_PBX: MOV A,R3 JZ PIM_LCX ;K=0 DPTR不处理 MOV A,R7 ;R0=P ANL A,#07H JZ PIM_LCX ;P=0 DPTR不处理 MOV R0,A CLR C ;K-P MOV A,R3 SUBB A,R0 JC PIM_LCX ;K

=P CLR C ;DPTR到前一个字节 MOV A,DPL SUBB A,#1 MOV DPL,A MOV A,DPH SUBB A,#0 MOV DPH,A PIM_LCX: POP YPOS ;恢复列首位置 INC XPOS ;位置转下一列 INC R5 ;LX++ MOV A,R6 ;XSIZE与LX比较 XRL A,R5 JZ PIM_PAX ;XSIZE=LX JMP PIM_PA ;XSIZE<>LX PIM_PAX: RET ;------------------------------------------------------------------------------- ;子程序名称:PUTIMAGE(XPOS,YPOS,*S). ;功能:在(XPOS,YPOS)位置绘制XSIZE列及YISZE行点阵的图形*(S+2). ;输入:位置XPOS,YPOS;XSIZE=*S,YSIZE=*(S+1),S=DPTR+2. ;输出:XPOS=XPOS+XSIZE;如果XPOS>=XDOTS 则XPOS=0,YPOS=YPOS+YSIZE. ;影响:R0,R1,R2,R3,R4,R5,R6,R7. ;修改日期:2009.7.17 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- PUTIMAGE: ;显示图象子程序,在(XPOS,YPOS)位置显示一幅 ;图象,图象地址指针为DPTR, ;第2个字节为Y方向点阵数,随后的数据为图象 ;点阵数据. CLR A ;图象数据的第1个字节为X方向点阵数 MOVC A,@A+DPTR ;XSIZE=*S MOV R6,A ; INC DPTR ;S++ CLR A ;图象数据的第2个字节为Y方向点阵数 MOVC A,@A+DPTR ;YSIZE=*S MOV R7,A ; INC DPTR ;S++ CALL PUTSIZEIMAGE ;绘制图形 RET ;------------------------------------------------------------------------------- ;以下LCDFILL,LCDPOS,LCDRESET为KS0108B型硬件接口的12864液晶显示模块的基本子程序 ;------------------------------------------------------------------------------- ;子程序名称:LCDRESET() ;功能:液晶显示控制器初始化 ;输入:无 ;输出:无 ;影响:R0,A ;修改日期:2009.8.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDRESET: ;液晶显示控制器初始化子程序 MOV A,#0C0H ;设置显示初始行 CALL LCDWC1 CALL LCDWC2 MOV A,#3FH ;开显示 CALL LCDWC1 CALL LCDWC2 RET ;------------------------------------------------------------------------------- ;子程序名称:LCDPOS(XPOS,YPOS). ;功能:设置(XPOS,YPOS)位置对应的内部RAM地址. ;输入:位置XPOS,YPOS. ;输出:无 ;影响:R0. ;修改日期:2009.8.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDPOS: ;设置(XPOS,YPOS)内部RAM地址的子程序 PUSH ACC ;保护ACC的值 PUSH B ;保护B的值 MOV A,YPOS ;YPOS/8 ANL A,#78H RR A RR A RR A ADD A,#0B8H MOV B,A MOV A,XPOS CJNE A,#64,$+3 JNC LPS_LA1 ANL A,#3FH ORL A,#40H CALL LCDWC1 MOV A,B CALL LCDWC1 JMP LPS_LAX LPS_LA1:CJNE A,#128,$+3 JNC LPS_LA2 CLR C SUBB A,#64 ORL A,#40H CALL LCDWC2 MOV A,B CALL LCDWC2 JMP LPS_LAX LPS_LA2: LPS_LAX: POP B ;恢复B的值 POP ACC ;恢复ACC的值 RET ;------------------------------------------------------------------------------- ;子程序名称:LCDFILL(A). ;功能:整屏显示A表示的字节数据. ;输入:A. ;输出:B=A. ;影响:R0,R2,A,B. ;修改日期:2009.8.28 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDFILL: ;整屏显示A代表的字节数据子程序 MOV B,A MOV YPOS,#0 ;第1行位置 LFL_PA: MOV XPOS,#0 ;第1列位置 CALL LCDPOS MOV R2,#64 LFL_PB: MOV A,B CALL LCDWD DJNZ R2,LFL_PB MOV XPOS,#64 ;第64列位置 CALL LCDPOS MOV R2,#64 LFL_PC: MOV A,B CALL LCDWD DJNZ R2,LFL_PC MOV A,YPOS ADD A,#8 MOV YPOS,A CJNE A,#64,LFL_PA MOV XPOS,#0 MOV YPOS,#0 RET ;------------------------------------------------------------------------------- ;以下LCDWC1,LCDWC2,LCDWD,LCDRD为MCS51总线接口的KS0108B液晶显示控制器的基本 ;子程序,LCDWD1,LCDWD2,LCDRD1,LCDRD2,LCDWAITIDLE1,LCDWAITIDLE2为内部子程序. ;------------------------------------------------------------------------------- ;子程序名称:LCDWC1(A). ;功能:送控制字到液晶显示控制器1. ;输入:A. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWC1: ;送控制字1子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE1 ;液晶显示控制器1忙检测 MOV DPTR,#LCDC1WADDR MOVX @DPTR,A POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWC2(A). ;功能:送控制字到液晶显示控制器2. ;输入:A. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWC2: ;送控制字2子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE2 ;液晶显示控制器2忙检测 MOV DPTR,#LCDC2WADDR MOVX @DPTR,A POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWD(A). ;功能:送数据到液晶显示控制器. ;输入:A. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWD: ;送数据子程序 PUSH ACC MOV A,XPOS JB ACC.6,LWD_LAY POP ACC ;XPOS<64,送数据到IC1 CALL LCDWD1 JMP LWD_LAX LWD_LAY: POP ACC ;XPOS>=64,送数据到IC2 CALL LCDWD2 LWD_LAX: RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWD1(A). ;功能:送数据到液晶显示控制器1. ;输入:A. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWD1: ;送数据1子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE1 ;液晶显示控制器1忙检测 MOV DPTR,#LCDD1WADDR MOVX @DPTR,A POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWD2(A). ;功能:送数据到液晶显示控制器2. ;输入:A. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWD2: ;送数据2子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE2 ;液晶显示控制器2忙检测 MOV DPTR,#LCDD2WADDR MOVX @DPTR,A POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDRD(). ;功能:从液晶显示控制器读数据. ;输入:无. ;输出:A. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDRD: ;读数据子程序 MOV A,XPOS JB ACC.6,LRD_LAY CALL LCDRD1 ;XPOS<64,送数据到IC1 CALL LCDRD1 ;DUMMY READ JMP LRD_LAX LRD_LAY: CALL LCDRD2 ;XPOS>=64,送数据到IC2 CALL LCDRD2 ;DUMMY READ LRD_LAX: RET ;------------------------------------------------------------------------------- ;子程序名称:LCDRD1(). ;功能:从液晶显示控制器1读数据. ;输入:无. ;输出:A. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDRD1: ;读数据1子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE1 ;液晶显示控制器1忙检测 MOV DPTR,#LCDD1RADDR MOVX A,@DPTR POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDRD2(). ;功能:从液晶显示控制器2读数据. ;输入:无. ;输出:A. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDRD2: ;读数据2子程序 PUSH DPH PUSH DPL CALL LCDWAITIDLE2 ;液晶显示控制器2忙检测 MOV DPTR,#LCDD2RADDR MOVX A,@DPTR POP DPL POP DPH RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWAITIDLE1(). ;功能:IC1忙检测. ;输入:无. ;输出:无. ;影响:R0. ;修改日期:2010.05.21 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWAITIDLE1: ;IC1忙检测子程序 ;正常读写操作之前必须检测LCD控制器状态 PUSH ACC ;状态字的D7位为0表示LCD控制器空闲,可以 ;进行读写操作 MOV DPTR,#LCDC1RADDR MOV R0,#20 WT1_PA: MOVX A,@DPTR JNB ACC.7,WT1_LAX ;D7=0 表示LCD控制器空闲,则退出检测 DJNZ R0,WT1_PA ;D7=1 表示LCD控制器忙,则继续检测 ;若忙时间超过100uS,则表示LCD控制器硬件 ;出错,退出检测 NOP ;用户可在此设置错误代码,或仿真时设置断点 WT1_LAX: POP ACC RET ;------------------------------------------------------------------------------- ;子程序名称:LCDWAITIDLE2(). ;功能:IC2忙检测. ;输入:无. ;输出:无. ;影响:R0. ;修改日期:2009.08.31 ;修改人:chujianjun@sunman.cn,tanchao@sunman.cn ;------------------------------------------------------------------------------- LCDWAITIDLE2: ;IC2忙检测子程序 ;正常读写操作之前必须检测LCD控制器状态 PUSH ACC ;状态字的D7位为0表示LCD控制器空闲,可以 ;进行读写操作 MOV DPTR,#LCDC2RADDR MOV R0,#20 WT2_PA: MOVX A,@DPTR ; JNB ACC.7,WT2_LAX ;D7=0 表示LCD控制器空闲,则退出检测 DJNZ R0,WT2_PA ;D7=1 表示LCD控制器忙,则继续检测 ;若忙时间超过100uS,则表示LCD控制器硬件 ;出错,退出检测 NOP ;用户可在此设置错误代码,或仿真时设置断点 WT2_LAX: POP ACC RET