📄 demo.lst
字号:
(0082) TIMSK = 0x04; //注意这里允许定时器一溢出
0145 E084 LDI R24,4
0146 BF89 OUT 0x39,R24
(0083) SEI(); //re-enable interrupts
0147 9478 BSET 7
0148 9508 RET
(0084) //all peripherals are now initialized
(0085) }
(0086) /******************************************************************************/
(0087) //以下显示模式只保留一个,查看效果
(0088) /******************************************************************************/
(0089)
(0090) //综合应用例子
(0091)
(0092) void main(void)
(0093) {
(0094) init_devices2(); //比init_devices()多了timer1_init(),TIMSK = 0x04;
_main:
0149 DFF3 RCALL _init_devices2
014A C007 RJMP 0x0152
(0095) while(1)
(0096) {
(0097) display(countdata,0); //普通模式,显示countdata的值,countdata将在timer1定时一秒溢出时改变
014B 2722 CLR R18
014C 91000060 LDS R16,countdata
014E 91100061 LDS R17,countdata+1
0150 940E0173 CALL _display
0152 CFF8 RJMP 0x014B
0153 9508 RET
FILE: C:\DOCUME~1\administrator\桌面\教程\7断数码管\led.c
(0001) /**********************************
(0002) ** file_name led.c **
(0003) ** describe 七段数码管函数 **
(0004) ** auther 古欣 www.avrvi.com **
(0005) ** Time 200-2-25 **
(0006) ** temp=(data*1000)%1; 这个式子中的%为取余数,temp为data的第三位小数,0.023(data) --> 3(temp)
(0007) ***********************************/
(0008) #include "config.h"
(0009)
(0010)
(0011) //LED数据 不显点,亮的段为1,连接为P0~P7对应a~g,dp
(0012) const led_data[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x73,0x39,0x63,0x79};
(0013)
(0014) /***********************
(0015) ** 初始化对应端口为输出
(0016) ** ABCD 和 abcdefg dpi 共12个IO口
(0017) ** 默认为 PB(0123) 和 PA
(0018) ***********************/
(0019) void led_init(void)
(0020) {
(0021) led_ddr = 0xFF; //abcdefg dpi 各位设为输出
_led_init:
0154 EF8F LDI R24,0xFF
0155 BB8A OUT 0x1A,R24
(0022) led_contrl_ddr |= (1<<led_a)|(1<<led_b)|(1<<led_c)|(1<<led_d); //ABCD四个控制设为输出
0156 B387 IN R24,0x17
0157 608F ORI R24,0xF
0158 BB87 OUT 0x17,R24
0159 9508 RET
_display_one:
data --> R22
count --> R20
015A 940E0960 CALL push_gset2
015C 2F62 MOV R22,R18
015D 2F40 MOV R20,R16
(0023)
(0024) // 以下两句将会使LED全亮,如果立即更改状态,将看不出来效果
(0025) // led_port = 0xFF;
(0026) // led_contrl_port |= (1<<led_a)|(1<<led_b)|(1<<led_c)|(1<<led_d);
(0027) }
(0028)
(0029) /***********************
(0030) ** 显示一位
(0031) ** 输入:count显示在第几位(3210),data 要显示的数(0~f)
(0032) ************************/
(0033) void display_one(uint8 count, uint8 data)
(0034) {
(0035) led_port = led_data[data]; //显示的数
015E E082 LDI R24,2
015F 9F86 MUL R24,R22
0160 01F0 MOVW R30,R0
0161 E584 LDI R24,0x54
0162 E090 LDI R25,0
0163 0FE8 ADD R30,R24
0164 1FF9 ADC R31,R25
0165 9005 LPM R0,Z+
0166 9014 LPM R1,0(Z)
0167 01F0 MOVW R30,R0
0168 BBEB OUT 0x1B,R30
(0036) led_contrl_port |= (1<<count); //选中对应要显示的位,从右至左,0123
0169 E001 LDI R16,1
016A 2F14 MOV R17,R20
016B 940E0996 CALL lsl8
016D B228 IN R2,0x18
016E 2A20 OR R2,R16
016F BA28 OUT 0x18,R2
0170 940E0954 CALL pop_gset2
0172 9508 RET
_display:
temp --> R20
mode --> R10
data --> R22
0173 940E095E CALL push_gset3
0175 2EA2 MOV R10,R18
0176 01B8 MOVW R22,R16
(0037) //如果对位进行了调整,就不在是0123,而是对应的值
(0038) }
(0039)
(0040) /***********************
(0041) ** 显示四位整数
(0042) ** 输入:要显示的四位数data,显示模式mode,1为补零显示模式,默认不显示零
(0043) ** 说明:可以小于四位数,mode=1时 自动补零
(0044) ************************/
(0045) void display(uint16 data,uint8 mode)
(0046) {
(0047) uint8 temp;
(0048) //千位
(0049) if(data>=1000)
0177 3E68 CPI R22,0xE8
0178 E0E3 LDI R30,3
0179 077E CPC R23,R30
017A F078 BCS 0x018A
(0050) {
(0051) temp=data/1000;
017B EE28 LDI R18,0xE8
017C E033 LDI R19,3
017D 018B MOVW R16,R22
017E 940E093A CALL div16u
0180 2F40 MOV R20,R16
(0052) display_one(3,temp);
0181 2F24 MOV R18,R20
0182 E003 LDI R16,3
0183 DFD6 RCALL _display_one
(0053) delay_ms(6); //6ms 是个经验值,刚好无闪烁,并且亮度较高
0184 E006 LDI R16,6
0185 E010 LDI R17,0
0186 940E00AE CALL _delay_ms
(0054) led_contrl_port &=~ (1<<3);
0188 98C3 CBI 0x18,3
(0055) }
0189 C00B RJMP 0x0195
(0056) else
(0057) {//补零
(0058) if(mode==1)
018A 2D8A MOV R24,R10
018B 3081 CPI R24,1
018C F441 BNE 0x0195
(0059) {
(0060) display_one(3,0);
018D 2722 CLR R18
018E E003 LDI R16,3
018F DFCA RCALL _display_one
(0061) delay_ms(6);
0190 E006 LDI R16,6
0191 E010 LDI R17,0
0192 940E00AE CALL _delay_ms
(0062) led_contrl_port &=~ (1<<3);
0194 98C3 CBI 0x18,3
(0063) }
(0064) }
(0065) //百位
(0066) if(data>=100)
0195 3664 CPI R22,0x64
0196 E0E0 LDI R30,0
0197 077E CPC R23,R30
0198 F098 BCS 0x01AC
(0067) {
(0068) temp=(data%1000)/100;
0199 EE28 LDI R18,0xE8
019A E033 LDI R19,3
019B 018B MOVW R16,R22
019C 940E0938 CALL mod16u
019E E624 LDI R18,0x64
019F E030 LDI R19,0
01A0 940E093A CALL div16u
01A2 2F40 MOV R20,R16
(0069) display_one(2,temp);
01A3 2F24 MOV R18,R20
01A4 E002 LDI R16,2
01A5 DFB4 RCALL _display_one
(0070) delay_ms(6);
01A6 E006 LDI R16,6
01A7 E010 LDI R17,0
01A8 940E00AE CALL _delay_ms
(0071) led_contrl_port &=~ (1<<2);
01AA 98C2 CBI 0x18,2
(0072) }
01AB C00B RJMP 0x01B7
(0073) else
(0074) {
(0075) if(mode==1)
01AC 2D8A MOV R24,R10
01AD 3081 CPI R24,1
01AE F441 BNE 0x01B7
(0076) {
(0077) display_one(2,0);
01AF 2722 CLR R18
01B0 E002 LDI R16,2
01B1 DFA8 RCALL _display_one
(0078) delay_ms(6);
01B2 E006 LDI R16,6
01B3 E010 LDI R17,0
01B4 940E00AE CALL _delay_ms
(0079) led_contrl_port &=~ (1<<2);
01B6 98C2 CBI 0x18,2
(0080) }
(0081) }
(0082) //十位
(0083) if(data>=10)
01B7 306A CPI R22,0xA
01B8 E0E0 LDI R30,0
01B9 077E CPC R23,R30
01BA F098 BCS 0x01CE
(0084) {
(0085) temp=(data%100)/10;
01BB E624 LDI R18,0x64
01BC E030 LDI R19,0
01BD 018B MOVW R16,R22
01BE 940E0938 CALL mod16u
01C0 E02A LDI R18,0xA
01C1 E030 LDI R19,0
01C2 940E093A CALL div16u
01C4 2F40 MOV R20,R16
(0086) display_one(1,temp);
01C5 2F24 MOV R18,R20
01C6 E001 LDI R16,1
01C7 DF92 RCALL _display_one
(0087) delay_ms(6);
01C8 E006 LDI R16,6
01C9 E010 LDI R17,0
01CA 940E00AE CALL _delay_ms
(0088) led_contrl_port &=~ (1<<1);
01CC 98C1 CBI 0x18,1
(0089) }
01CD C00B RJMP 0x01D9
(0090) else
(0091) {
(0092) if(mode==1)
01CE 2D8A MOV R24,R10
01CF 3081 CPI R24,1
01D0 F441 BNE 0x01D9
(0093) {
(0094) display_one(1,0);
01D1 2722 CLR R18
01D2 E001 LDI R16,1
01D3 DF86 RCALL _display_one
(0095) delay_ms(6);
01D4 E006 LDI R16,6
01D5 E010 LDI R17,0
01D6 940E00AE CALL _delay_ms
(0096) led_contrl_port &=~ (1<<1);
01D8 98C1 CBI 0x18,1
(0097) }
(0098) }
(0099) //个位
(0100) temp=data%10;
01D9 E02A LDI R18,0xA
01DA E030 LDI R19,0
01DB 018B MOVW R16,R22
01DC 940E0938 CALL mod16u
01DE 2F40 MOV R20,R16
(0101) display_one(0,temp);
01DF 2F24 MOV R18,R20
01E0 2700 CLR R16
01E1 DF78 RCALL _display_one
(0102) delay_ms(6);
01E2 E006 LDI R16,6
01E3 E010 LDI R17,0
01E4 940E00AE CALL _delay_ms
(0103) led_contrl_port &=~ (1<<0);
01E6 98C0 CBI 0x18,0
01E7 940E0957 CALL pop_gset3
01E9 9508 RET
_display_float:
temp2 --> R22
temp --> R20
data --> Y+22
01EA 940E0933 CALL push_arg4
01EC 940E095E CALL push_gset3
01EE 9760 SBIW R28,0x10
(0104) }
(0105)
(0106) /***********************
(0107) ** 显示四位浮点数 本函数占用 mega16 的空间 19%
(0108) ** 输入:要显示的四位数
(0109) ** 说明:可以小于四位数,自动补零
(0110) ************************/
(0111)
(0112) void display_float(float data)
(0113) {
(0114) uint8 temp;
(0115) uint16 temp2; //用于把浮点数变为整形
(0116) // 人为保证data的值,可以不要错误处理。
(0117) if (data>=1000)
01EF 01FE MOVW R30,R28
01F0 8826 LDD R2,Z+22
01F1 8837 LDD R3,Z+23
01F2 8C40 LDD R4,Z+24
01F3 8C51 LDD R5,Z+25
01F4 925A ST R5,-Y
01F5 924A ST R4,-Y
01F6 923A ST R3,-Y
01F7 922A ST R2,-Y
01F8 E808 LDI R16,0x88
01F9 E010 LDI R17,0
01FA 940E0982 CALL lpm32
01FC 933A ST R19,-Y
01FD 932A ST R18,-Y
01FE 931A ST R17,-Y
01FF 930A ST R16,-Y
0200 940E0ACC CALL cmp32f
0202 F00C BLT 0x0204
(0118) {
(0119) led_error();
0203 D729 RCALL _led_error
(0120) }
(0121) if (data<=0)
0204 E804 LDI R16,0x84
0205 E010 LDI R17,0
0206 940E0982 CALL lpm32
0208 933A ST R19,-Y
0209 932A ST R18,-Y
020A 931A ST R17,-Y
020B 930A ST R16,-Y
020C 01FE MOVW R30,R28
020D 8C22 LDD R2,Z+26
020E 8C33 LDD R3,Z+27
020F 8C44 LDD R4,Z+28
0210 8C55 LDD R5,Z+29
0211 925A ST R5,-Y
0212 924A ST R4,-Y
0213 923A ST R3,-Y
0214 922A ST R2,-Y
0215 940E0ACC CALL cmp32f
0217 F00C BLT 0x0219
(0122) {
(0123) led_error();
0218 D714 RCALL _led_error
(0124) }
(0125) //
(0126) if(data<1) //比如 0.123
0219 01FE MOVW R30,R28
021A 8826 LDD R2,Z+22
021B 8837 LDD R3,Z+23
021C 8C40 LDD R4,Z+24
021D 8C51 LDD R5,Z+25
021E 925A ST R5,-Y
021F 924A ST R4,-Y
0220 923A ST R3,-Y
0221 922A ST R2,-Y
0222 E800 LDI R16,0x80
0223 E010 LDI R17,0
0224 940E0982 CALL lpm32
0226 933A ST R19,-Y
0227 932A ST R18,-Y
0228 931A ST R17,-Y
0229 930A ST R16,-Y
022A 940E0ACC CALL cmp32f
022C F00C BLT 0x022E
022D C119 RJMP 0x0347
(0127) {
(0128) display_one(3,0); //显示0.
022E 2722 CLR R18
022F E003 LDI R16,3
0230 DF29 RCALL _display_one
(0129) led_port |= 0x80; //点亮对应小数点
0231 9ADF SBI 0x1B,7
(0130) delay_ms(6);
0232 E006 LDI R16,6
0233 E010 LDI R17,0
0234 940E00AE CALL _delay_ms
(0131) led_contrl_port &=~ (1<<3);
0236 98C3 CBI 0x18,3
(0132)
(0133) temp=(data*10); // 0.123*10 = 1
0237 E70C LDI R16,0x7C
0238 E010 LDI R17,0
0239 940E0982 CALL lpm32
023B 933A ST R19,-Y
023C 932A ST R18,-Y
023D 931A ST R17,-Y
023E 930A ST R16,-Y
023F 01FE MOVW R30,R28
0240 8C22 LDD R2,Z+26
0241 8C33 LDD R3,Z+27
0242 8C44 LDD R4,Z+28
0243 8C55 LDD R5,Z+29
0244 925A ST R5,-Y
0245 924A ST R4,-Y
0246 923A ST R3,-Y
0247 922A ST R2,-Y
0248 940E0B00 CALL empy32f
024A 01FE MOVW R30,R28
024B 8300 STD Z+0,R16
024C 8311 STD Z+1,R17
024D 8322 STD Z+2,R18
024E 8333 STD Z+3,R19
024F 01FE MOVW R30,R28
0250 8020 LDD R2,Z+0
0251 8031 LDD R3,Z+1
0252 8042 LDD R4,Z+2
0253 8053 LDD R5,Z+3
0254 925A ST R5,-Y
0255 924A ST R4,-Y
0256 923A ST R3,-Y
0257 922A ST R2,-Y
0258 E708 LDI R16,0x78
0259 E010 LDI R17,0
025A 940E0982 CALL lpm32
025C 933A ST R19,-Y
025D 932A ST R18,-Y
025E 931A ST R17,-Y
025F 930A ST R16,-Y
0260 940E0ACC CALL cmp32f
0262 F0CC BLT 0x027C
0263 01FE MOVW R30,R28
0264 8020 LDD R2,Z+0
0265 8031 LDD R3,Z+1
0266 8042 LDD R4,Z+2
0267 8053 LDD R5,Z+3
0268 925A ST R5,-Y
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -