📄 eeprom读写演示程序.lst
字号:
(0006) 硬件连接:采用串行方式显示,分配PA.0,PA.1,PA.2
(0007) 三个I/O口分别作为LCM片选CS,数据SID,时钟信
(0008) 号CLK的控制。PA3置为低电平,用来串行选择信号。
(0009) PA4置位时开启背光。
(0010)
(0011) ****************************************************************************************/
(0012)
(0013) #include <iom16v.h>
(0014) #include <macros.h>
(0015) #include <stdio.h>
(0016) #define LCDDDR DDRA
(0017) #define LCDDDR_IN LCDDDR&=~BIT(PA1);
(0018) #define LCDDDR_OUT LCDDDR|=BIT(PA0)|BIT(PA1)|BIT(PA2)|BIT(PA3)|BIT(PA4);
(0019) /*===============================================================*/
(0020) #define LCDCTL PORTA
(0021) #define LCD_RS_H LCDCTL |= BIT(PA0) //片选
(0022) #define LCD_RS_L LCDCTL &= ~BIT(PA0)
(0023) #define LCD_RW_H LCDCTL |= BIT(PA1) //数据
(0024) #define LCD_RW_L LCDCTL &= ~BIT(PA1)
(0025) #define LCD_EN_H LCDCTL |= BIT(PA2) //时钟
(0026) #define LCD_EN_L LCDCTL &= ~BIT(PA2)
(0027) #define LCD_PSB LCDCTL &= ~BIT(PA3) //串行选择
(0028) #define LCD_AK LCDCTL |= BIT(PA4) //开启背光
(0029) #define uchar unsigned char
(0030) /***********************函数体部分*********************************/
(0031)
(0032) void dm12864_inputbyte(uchar comm) // 写入一字节数据
(0033) {
(0034) uchar i;
(0035) uchar mid;
(0036) for (i=0;i<8;i++)
0350 2766 CLR R22
0351 C00A RJMP 0x035C
(0037) {
(0038) mid=comm&0x80;
0352 2F40 MOV R20,R16
0353 7840 ANDI R20,0x80
(0039) if (mid==0)
0354 F411 BNE 0x0357
(0040) LCD_RW_L ;
0355 98D9 CBI 0x1B,1
0356 C001 RJMP 0x0358
(0041) else
(0042) LCD_RW_H ;
0357 9AD9 SBI 0x1B,1
(0043) LCD_EN_H ;
0358 9ADA SBI 0x1B,2
(0044) //delay(15);
(0045) LCD_EN_L;
0359 98DA CBI 0x1B,2
(0046) comm=comm<<1;
035A 0F00 LSL R16
035B 9563 INC R22
035C 3068 CPI R22,0x8
035D F3A0 BCS 0x0352
035E 940E0693 CALL pop_gset2
0360 9508 RET
(0047) }
(0048) }
(0049) uchar dm12864_outputbyte(void) //读取一字节数据
(0050) {
(0051) uchar i,mid=0;
_dm12864_outputbyte:
i --> R16
mid --> R18
0361 2722 CLR R18
(0052) for (i=0;i<8;i++)
0362 2700 CLR R16
0363 C00E RJMP 0x0372
(0053) {
(0054) //delay(15);
(0055) LCDDDR_IN;
0364 98D1 CBI 0x1A,1
(0056) LCD_RS_H ;
0365 9AD8 SBI 0x1B,0
(0057) mid=mid<<1;
0366 0F22 LSL R18
(0058) if ((PINA&0x02)==0)
0367 99C9 SBIC 0x19,1
0368 C002 RJMP 0x036B
(0059) mid&=~BIT(PD0);
0369 7F2E ANDI R18,0xFE
036A C001 RJMP 0x036C
(0060) else
(0061) mid|=BIT(PD0);
036B 6021 ORI R18,1
(0062) LCDDDR_OUT;
036C B38A IN R24,0x1A
036D 618F ORI R24,0x1F
036E BB8A OUT 0x1A,R24
(0063) LCD_EN_H ;
036F 9ADA SBI 0x1B,2
(0064) //delay(15);
(0065) LCD_EN_L;
0370 98DA CBI 0x1B,2
0371 9503 INC R16
0372 3008 CPI R16,0x8
0373 F380 BCS 0x0364
(0066) }
(0067) return(mid);
0374 2F02 MOV R16,R18
0375 9508 RET
_DetectLCMBusyState:
BF --> R20
0376 940E06A7 CALL push_gset1
(0068) }
(0069)
(0070) /*-----------------读取标志位,判断控制器是否为忙状态--------------*/
(0071) void DetectLCMBusyState()
(0072) {
(0073) char BF = 0x00;
0378 2744 CLR R20
(0074) LCDDDR_OUT;
0379 B38A IN R24,0x1A
037A 618F ORI R24,0x1F
037B BB8A OUT 0x1A,R24
(0075) LCD_RS_H ;
037C 9AD8 SBI 0x1B,0
(0076) LCD_EN_L ;
037D 98DA CBI 0x1B,2
(0077) do
(0078) {
(0079) dm12864_inputbyte(0xfc);
037E EF0C LDI R16,0xFC
037F DFCE RCALL _dm12864_inputbyte
(0080) BF=dm12864_outputbyte();
0380 DFE0 RCALL _dm12864_outputbyte
0381 2F40 MOV R20,R16
(0081) } while(BF==0x80);
0382 3840 CPI R20,0x80
0383 F3D1 BEQ 0x037E
(0082) LCD_RS_L ;
0384 98D8 CBI 0x1B,0
(0083) LCD_EN_H ;
0385 9ADA SBI 0x1B,2
0386 940E06AA CALL pop_gset1
0388 9508 RET
_LCMWriteCommand:
b --> R20
a --> R22
DisplayCmd --> R20
0389 940E06A5 CALL push_gset2
038B 2F40 MOV R20,R16
(0084) //delay(15);
(0085) }
(0086)
(0087) /*----------------------------写入命令-----------------------------*/
(0088) void LCMWriteCommand(char DisplayCmd)
(0089) {
(0090) uchar a,b;
(0091) a=DisplayCmd&0xf0;
038C 2F64 MOV R22,R20
038D 7F60 ANDI R22,0xF0
(0092) b=(DisplayCmd<<4)&0xf0;
038E 2F84 MOV R24,R20
038F 708F ANDI R24,0xF
0390 9582 SWAP R24
0391 7F80 ANDI R24,0xF0
0392 2F48 MOV R20,R24
(0093) LCDDDR_OUT;
0393 B38A IN R24,0x1A
0394 618F ORI R24,0x1F
0395 BB8A OUT 0x1A,R24
(0094) LCD_RS_H ;
0396 9AD8 SBI 0x1B,0
(0095) LCD_EN_L ;
0397 98DA CBI 0x1B,2
(0096) dm12864_inputbyte(0xf8);
0398 EF08 LDI R16,0xF8
0399 DFB4 RCALL _dm12864_inputbyte
(0097) dm12864_inputbyte(a);
039A 2F06 MOV R16,R22
039B DFB2 RCALL _dm12864_inputbyte
(0098) dm12864_inputbyte(b);
039C 2F04 MOV R16,R20
039D DFB0 RCALL _dm12864_inputbyte
(0099) LCD_EN_H ;
039E 9ADA SBI 0x1B,2
(0100) LCD_RS_L ;
039F 98D8 CBI 0x1B,0
03A0 940E0693 CALL pop_gset2
03A2 9508 RET
_LCMWriteData:
b --> R20
a --> R22
DisplayData --> R20
03A3 940E06A5 CALL push_gset2
03A5 2F40 MOV R20,R16
(0101) //delay(15);
(0102) }
(0103)
(0104) /*-----------------------写入一字节数据--------------------------*/
(0105) void LCMWriteData(char DisplayData)
(0106) {
(0107) uchar a,b;
(0108) a=DisplayData&0xf0;
03A6 2F64 MOV R22,R20
03A7 7F60 ANDI R22,0xF0
(0109) b=(DisplayData<<4)&0xf0;
03A8 2F84 MOV R24,R20
03A9 708F ANDI R24,0xF
03AA 9582 SWAP R24
03AB 7F80 ANDI R24,0xF0
03AC 2F48 MOV R20,R24
(0110) LCDDDR_OUT;
03AD B38A IN R24,0x1A
03AE 618F ORI R24,0x1F
03AF BB8A OUT 0x1A,R24
(0111) LCD_RS_H ;
03B0 9AD8 SBI 0x1B,0
(0112) LCD_EN_L ;
03B1 98DA CBI 0x1B,2
(0113) dm12864_inputbyte(0xfa);
03B2 EF0A LDI R16,0xFA
03B3 DF9A RCALL _dm12864_inputbyte
(0114) dm12864_inputbyte(a);
03B4 2F06 MOV R16,R22
03B5 DF98 RCALL _dm12864_inputbyte
(0115) dm12864_inputbyte(b);
03B6 2F04 MOV R16,R20
03B7 DF96 RCALL _dm12864_inputbyte
(0116) LCD_EN_H ;
03B8 9ADA SBI 0x1B,2
(0117) LCD_RS_L ;
03B9 98D8 CBI 0x1B,0
03BA 940E0693 CALL pop_gset2
03BC 9508 RET
_LCMSetXYAddress:
DisplayRow --> R22
DisplayCol --> R20
03BD 940E06A5 CALL push_gset2
03BF 2F62 MOV R22,R18
03C0 2F40 MOV R20,R16
(0118) //delay(15);
(0119) }
(0120)
(0121) /*------------设置显示位置DisplayCol(1~8),DisplayRow(1~4)---------*/
(0122) void LCMSetXYAddress(char DisplayCol,char DisplayRow)
(0123) {
(0124) switch(DisplayRow)
03C1 2777 CLR R23
03C2 3061 CPI R22,1
03C3 E0E0 LDI R30,0
03C4 077E CPC R23,R30
03C5 F069 BEQ 0x03D3
03C6 3062 CPI R22,2
03C7 E0E0 LDI R30,0
03C8 077E CPC R23,R30
03C9 F069 BEQ 0x03D7
03CA 3063 CPI R22,3
03CB E0E0 LDI R30,0
03CC 077E CPC R23,R30
03CD F069 BEQ 0x03DB
03CE 3064 CPI R22,4
03CF E0E0 LDI R30,0
03D0 077E CPC R23,R30
03D1 F069 BEQ 0x03DF
03D2 C00F RJMP 0x03E2
(0125) {
(0126) case 1:LCMWriteCommand(0x7f + DisplayCol);
03D3 2F04 MOV R16,R20
03D4 5801 SUBI R16,0x81
03D5 DFB3 RCALL _LCMWriteCommand
(0127) break;
03D6 C00B RJMP 0x03E2
(0128) case 2:LCMWriteCommand(0x8f + DisplayCol);
03D7 2F04 MOV R16,R20
03D8 5701 SUBI R16,0x71
03D9 DFAF RCALL _LCMWriteCommand
(0129) break;
03DA C007 RJMP 0x03E2
(0130) case 3:LCMWriteCommand(0x87 + DisplayCol);
03DB 2F04 MOV R16,R20
03DC 5709 SUBI R16,0x79
03DD DFAB RCALL _LCMWriteCommand
(0131) break;
03DE C003 RJMP 0x03E2
(0132) case 4:LCMWriteCommand(0x97 + DisplayCol);
03DF 2F04 MOV R16,R20
03E0 5609 SUBI R16,0x69
03E1 DFA7 RCALL _LCMWriteCommand
(0133) break;
03E2 940E0693 CALL pop_gset2
03E4 9508 RET
_LCMDisplayASC:
ASCCharacter --> Y+4
DisplayRow --> R22
DisplayCol --> R20
03E5 940E06A5 CALL push_gset2
03E7 2F62 MOV R22,R18
03E8 2F40 MOV R20,R16
(0134) }
(0135) }
(0136)
(0137) /*-------------------在指定位置显示一半角字符-----------------------*/
(0138) void LCMDisplayASC(char DisplayCol,char DisplayRow,char ASCCharacter)
(0139) {
(0140) LCMSetXYAddress(DisplayCol,DisplayRow);
03E9 2F26 MOV R18,R22
03EA 2F04 MOV R16,R20
03EB DFD1 RCALL _LCMSetXYAddress
(0141) LCMWriteData(ASCCharacter);
03EC 810C LDD R16,Y+4
03ED DFB5 RCALL _LCMWriteData
03EE 940E0693 CALL pop_gset2
03F0 9508 RET
_LCMDisplayString:
LCD_temp --> R20
DisplayString --> R22
DisplayRow --> R10
DisplayCol --> R20
03F1 940E06A3 CALL push_gset3
03F3 2EA2 MOV R10,R18
03F4 2F40 MOV R20,R16
03F5 816E LDD R22,Y+6
03F6 817F LDD R23,Y+7
(0142) }
(0143)
(0144) /*----------------------在指定位置显示字符串-------------------------*/
(0145) void LCMDisplayString(char DisplayCol,char DisplayRow,char *DisplayString)
(0146) {
(0147) char LCD_temp;
(0148) LCMSetXYAddress(DisplayCol,DisplayRow);
03F7 2D2A MOV R18,R10
03F8 2F04 MOV R16,R20
03F9 DFC3 RCALL _LCMSetXYAddress
(0149) LCD_temp=*DisplayString;
03FA 01FB MOVW R30,R22
03FB 8140 LDD R20,Z+0
03FC C007 RJMP 0x0404
(0150) while(LCD_temp!=0x00)
(0151) {
(0152) LCMWriteData(LCD_temp);
03FD 2F04 MOV R16,R20
03FE DFA4 RCALL _LCMWriteData
(0153) LCD_temp=*(++DisplayString);
03FF 01CB MOVW R24,R22
0400 9601 ADIW R24,1
0401 01BC MOVW R22,R24
0402 01FC MOVW R30,R24
0403 8140 LDD R20,Z+0
0404 2344 TST R20
0405 F7B9 BNE 0x03FD
0406 940E0696 CALL pop_gset3
0408 9508 RET
_LCMDisplayNummber:
flag --> R20
LCD_temp --> R22
DisplayNum --> R10
DisplayRow --> R14
DisplayCol --> R12
0409 940E069F CALL push_gset5
040B 2EE2 MOV R14,R18
040C 2EC0 MOV R12,R16
040D 84AA LDD R10,Y+10
040E 84BB LDD R11,Y+11
(0154) }
(0155) }
(0156)
(0157) /*-------------------------显示一个整形数字,范围-32767~32767---------------------------*/
(0158) //宏定义判断函数,其中\是连接符
(0159)
(0160) void LCMDisplayNummber(char DisplayCol,char DisplayRow,int DisplayNum)
(0161) {
(0162) char LCD_temp=0,flag=0;
040F 2766 CLR R22
0410 2744 CLR R20
(0163) LCMSetXYAddress(DisplayCol,DisplayRow);
0411 2D2E MOV R18,R14
0412 2D0C MOV R16,R12
0413 DFA9 RCALL _LCMSetXYAddress
(0164) if(DisplayNum < 0)
0414 01C5 MOVW R24,R10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -