📄 lcd1602.lst
字号:
(0079) 12.D5 -------- 由外部程序定义
(0080) 13.D6 -------- 由外部程序定义
(0081) 14.D7 -------- 由外部程序定义
(0082) 15.LED+ -------- VCC
(0083) 16.LED- -------- GND
(0084)
(0085) 说明:
(0086) (1)使用ATmega16的7根IO口操作LCD1602
(0087) (2)该程序的优点是:7根IO可任意定义,不需分布在固定的一组PORT口上
(0088) (3)该程序的缺点是:IO定义的写法较为繁琐
(0089) ----------------------------------------------------------------------
(0090) 待定参数说明:
(0091) //#define DELAY() {_nop_();_nop_();_nop_();}
(0092)
(0093) ----------------------------------------------------------------------
(0094) 对外变量说明:
(0095)
(0096) ----------------------------------------------------------------------
(0097) 对外函数说明:
(0098)
(0099) ----------------------------------------------------------------------
(0100) 10101010101010101010101010101010101010101010101010101010101010101010*/
(0101)
(0102) #ifndef LCD1602_H
(0103) #define LCD1602_H
(0104)
(0105) #include "D:\ICC_H\CmmICC.H"
(0106)
(0107) /* 待定参数 */
(0108) #define DELAY() {NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();}
(0109)
(0110) /* 不考虑移植性的写法 */
(0111) //uint8 bdata bdat;
(0112) //sbit bdat0=bdat^0;
(0113) //sbit bdat1=bdat^1;
(0114) //sbit bdat2=bdat^2;
(0115) //sbit bdat3=bdat^3;
(0116) //sbit bdat4=bdat^4;
(0117) //sbit bdat5=bdat^5;
(0118) //sbit bdat6=bdat^6;
(0119) //sbit bdat7=bdat^7;
(0120) /* 考虑移植性的写法 */
(0121) uint8 bdat;
(0122) #define bdat0 (bdat&0x01)
(0123) #define bdat1 (bdat&0x02)
(0124) #define bdat2 (bdat&0x04)
(0125) #define bdat3 (bdat&0x08)
(0126) #define bdat4 (bdat&0x10)
(0127) #define bdat5 (bdat&0x20)
(0128) #define bdat6 (bdat&0x40)
(0129) #define bdat7 (bdat&0x80)
(0130)
(0131) #define CGRAM0 0x00
(0132) #define CGRAM1 0x01
(0133) #define CGRAM2 0x02
(0134) #define CGRAM3 0x03
(0135) #define CGRAM4 0x04
(0136) #define CGRAM5 0x05
(0137) #define CGRAM6 0x06
(0138) #define CGRAM7 0x07
(0139)
(0140) #define TRUE 1
(0141) #define FALSE 0
(0142) bool LCD1602Err = FALSE;
(0143)
(0144) /*--------------------------------------------------------------------
(0145) 函数名称:LCD1602读读读读读忙~
(0146) 函数功能:都说是读读读读读忙咯~
(0147) 注意事项:对于高速CPU,应加延时,好像是废话~
(0148) 提示说明:无
(0149) 输 入:
(0150) 返 回:无
(0151) --------------------------------------------------------------------*/
(0152) void busy(void)
(0153) {
(0154) uint16 busyCounter=0;
_busy:
busySta --> R16
busyCounter --> R18
0258 2722 CLR R18
0259 2733 CLR R19
(0155) bool busySta; //用于探测 lcd busy status
(0156) IN_BF;
025A 988F CBI 0x11,7
(0157) SET_D4;
025B 9A94 SBI 0x12,4
(0158) SET_D5;
025C 9A95 SBI 0x12,5
(0159) SET_D6;
025D 9A96 SBI 0x12,6
(0160) SET_D7;
025E 9A97 SBI 0x12,7
(0161) DELAY();
025F 0000 NOP
0260 0000 NOP
0261 0000 NOP
0262 0000 NOP
0263 0000 NOP
0264 0000 NOP
0265 0000 NOP
0266 0000 NOP
(0162) CLR_RS;
0267 98C5 CBI 0x18,5
(0163) DELAY();
0268 0000 NOP
0269 0000 NOP
026A 0000 NOP
026B 0000 NOP
026C 0000 NOP
026D 0000 NOP
026E 0000 NOP
026F 0000 NOP
(0164) SET_RW;
0270 9AC6 SBI 0x18,6
(0165) DELAY();
0271 0000 NOP
0272 0000 NOP
0273 0000 NOP
0274 0000 NOP
0275 0000 NOP
0276 0000 NOP
0277 0000 NOP
0278 0000 NOP
(0166)
(0167) do
(0168) {
(0169) SET_E;
0279 9AC7 SBI 0x18,7
(0170) DELAY();
027A 0000 NOP
027B 0000 NOP
027C 0000 NOP
027D 0000 NOP
027E 0000 NOP
027F 0000 NOP
0280 0000 NOP
0281 0000 NOP
(0171) /* 这里读取AC4-AC6位及BF的值,程序不需记录AC4-AC6的值,所以不存储 */
(0172) busySta=(bool)GET_BF;
0282 B300 IN R16,0x10
0283 2711 CLR R17
0284 7800 ANDI R16,0x80
0285 7010 ANDI R17,0
(0173) CLR_E;
0286 98C7 CBI 0x18,7
(0174) DELAY();
0287 0000 NOP
0288 0000 NOP
0289 0000 NOP
028A 0000 NOP
028B 0000 NOP
028C 0000 NOP
028D 0000 NOP
028E 0000 NOP
(0175) /* 读取 "BUSY"时,"D4-D7"状态可能已经改变,必须再次设为输出"1" */
(0176) SET_D4;
028F 9A94 SBI 0x12,4
(0177) SET_D5;
0290 9A95 SBI 0x12,5
(0178) SET_D6;
0291 9A96 SBI 0x12,6
(0179) SET_D7;
0292 9A97 SBI 0x12,7
(0180) DELAY();
0293 0000 NOP
0294 0000 NOP
0295 0000 NOP
0296 0000 NOP
0297 0000 NOP
0298 0000 NOP
0299 0000 NOP
029A 0000 NOP
(0181) SET_E;
029B 9AC7 SBI 0x18,7
(0182) DELAY();
029C 0000 NOP
029D 0000 NOP
029E 0000 NOP
029F 0000 NOP
02A0 0000 NOP
02A1 0000 NOP
02A2 0000 NOP
02A3 0000 NOP
(0183) /* 这里读取AC0-AC3位的值,程序不需记录AC0-AC3的值,所以不存储 */
(0184) CLR_E;
02A4 98C7 CBI 0x18,7
(0185) DELAY();
02A5 0000 NOP
02A6 0000 NOP
02A7 0000 NOP
02A8 0000 NOP
02A9 0000 NOP
02AA 0000 NOP
02AB 0000 NOP
02AC 0000 NOP
(0186) if(busyCounter==1000)
02AD 3E28 CPI R18,0xE8
02AE E0E3 LDI R30,3
02AF 073E CPC R19,R30
02B0 F421 BNE 0x02B5
(0187) {
(0188) LCD1602Err=TRUE; //标识LCD1602错误,方便上缴系统报错
02B1 E081 LDI R24,1
02B2 93800060 STS LCD1602Err,R24
(0189) return ; //避免由于LCD1602错误而导致程序阻塞
02B4 C00A RJMP 0x02BF
(0190) }
(0191) busyCounter++;
02B5 5F2F SUBI R18,0xFF
02B6 4F3F SBCI R19,0xFF
(0192) }
(0193) while(busySta);
02B7 2300 TST R16
02B8 F009 BEQ 0x02BA
02B9 CFBF RJMP 0x0279
(0194)
(0195) LCD1602Err=FALSE;
02BA 2422 CLR R2
02BB 92200060 STS LCD1602Err,R2
(0196) CLR_E;
02BD 98C7 CBI 0x18,7
(0197) OUT_BF;
02BE 9A8F SBI 0x11,7
02BF 9508 RET
_write:
dat --> R22
flag --> R20
02C0 940E0773 CALL push_gset2
02C2 2F62 MOV R22,R18
02C3 2F40 MOV R20,R16
(0198) }
(0199) /*--------------------------------------------------------------------
(0200) 函数名称:LCD1602写操作
(0201) 函数功能:
(0202) 注意事项:对于高速CPU,应加延时,好像是废话~
(0203) 提示说明:无
(0204) 输 入:
(0205) 返 回:无
(0206) --------------------------------------------------------------------*/
(0207) void write(bool flag,uint8 dat) //flag=0:command,flag=1:data
(0208) {
(0209) bdat=dat;
02C4 93600103 STS bdat,R22
(0210) busy();
02C6 DF91 RCALL _busy
(0211) if(flag)
02C7 2344 TST R20
02C8 F011 BEQ 0x02CB
(0212) SET_RS;
02C9 9AC5 SBI 0x18,5
02CA C001 RJMP 0x02CC
(0213) else
(0214) CLR_RS;
02CB 98C5 CBI 0x18,5
(0215) DELAY();
02CC 0000 NOP
02CD 0000 NOP
02CE 0000 NOP
02CF 0000 NOP
02D0 0000 NOP
02D1 0000 NOP
02D2 0000 NOP
02D3 0000 NOP
(0216) CLR_RW;
02D4 98C6 CBI 0x18,6
(0217) DELAY();
02D5 0000 NOP
02D6 0000 NOP
02D7 0000 NOP
02D8 0000 NOP
02D9 0000 NOP
02DA 0000 NOP
02DB 0000 NOP
02DC 0000 NOP
(0218) if(bdat4)
02DD 90200103 LDS R2,bdat
02DF FE24 SBRS R2,4
02E0 C002 RJMP 0x02E3
(0219) SET_D4;
02E1 9A94 SBI 0x12,4
02E2 C001 RJMP 0x02E4
(0220) else
(0221) CLR_D4;
02E3 9894 CBI 0x12,4
(0222) if(bdat5)
02E4 90200103 LDS R2,bdat
02E6 FE25 SBRS R2,5
02E7 C002 RJMP 0x02EA
(0223) SET_D5;
02E8 9A95 SBI 0x12,5
02E9 C001 RJMP 0x02EB
(0224) else
(0225) CLR_D5;
02EA 9895 CBI 0x12,5
(0226) if(bdat6)
02EB 90200103 LDS R2,bdat
02ED FE26 SBRS R2,6
02EE C002 RJMP 0x02F1
(0227) SET_D6;
02EF 9A96 SBI 0x12,6
02F0 C001 RJMP 0x02F2
(0228) else
(0229) CLR_D6;
02F1 9896 CBI 0x12,6
(0230) if(bdat7)
02F2 90200103 LDS R2,bdat
02F4 FE27 SBRS R2,7
02F5 C002 RJMP 0x02F8
(0231) SET_D7;
02F6 9A97 SBI 0x12,7
02F7 C001 RJMP 0x02F9
(0232) else
(0233) CLR_D7;
02F8 9897 CBI 0x12,7
(0234) DELAY();
02F9 0000 NOP
02FA 0000 NOP
02FB 0000 NOP
02FC 0000 NOP
02FD 0000 NOP
02FE 0000 NOP
02FF 0000 NOP
0300 0000 NOP
(0235) SET_E;
0301 9AC7 SBI 0x18,7
(0236) DELAY();
0302 0000 NOP
0303 0000 NOP
0304 0000 NOP
0305 0000 NOP
0306 0000 NOP
0307 0000 NOP
0308 0000 NOP
0309 0000 NOP
(0237) CLR_E;
030A 98C7 CBI 0x18,7
(0238) DELAY();
030B 0000 NOP
030C 0000 NOP
030D 0000 NOP
030E 0000 NOP
030F 0000 NOP
0310 0000 NOP
0311 0000 NOP
0312 0000 NOP
(0239)
(0240) if(bdat0)
0313 90200103 LDS R2,bdat
0315 FE20 SBRS R2,0
0316 C002 RJMP 0x0319
(0241) SET_D4;
0317 9A94 SBI 0x12,4
0318 C001 RJMP 0x031A
(0242) else
(0243) CLR_D4;
0319 9894 CBI 0x12,4
(0244) if(bdat1)
031A 90200103 LDS R2,bdat
031C FE21 SBRS R2,1
031D C002 RJMP 0x0320
(0245) SET_D5;
031E 9A95 SBI 0x12,5
031F C001 RJMP 0x0321
(0246) else
(0247) CLR_D5;
0320 9895 CBI 0x12,5
(0248) if(bdat2)
0321 90200103 LDS R2,bdat
0323 FE22 SBRS R2,2
0324 C002 RJMP 0x0327
(0249) SET_D6;
0325 9A96 SBI 0x12,6
0326 C001 RJMP 0x0328
(0250) else
(0251) CLR_D6;
0327 9896 CBI 0x12,6
(0252) if(bdat3)
0328 90200103 LDS R2,bdat
032A FE23 SBRS R2,3
032B C002 RJMP 0x032E
(0253) SET_D7;
032C 9A97 SBI 0x12,7
032D C001 RJMP 0x032F
(0254) else
(0255) CLR_D7;
032E 9897 CBI 0x12,7
(0256) DELAY();
032F 0000 NOP
0330 0000 NOP
0331 0000 NOP
0332 0000 NOP
0333 0000 NOP
0334 0000 NOP
0335 0000 NOP
0336 0000 NOP
(0257) SET_E;
0337 9AC7 SBI 0x18,7
(0258) DELAY();
0338 0000 NOP
0339 0000 NOP
033A 0000 NOP
033B 0000 NOP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -