📄 09ad.lst
字号:
__start:
__text_start:
0051 EFCF LDI R28,0xFF
0052 E1D0 LDI R29,0x10
0053 BFCD OUT 0x3D,R28
0054 BFDE OUT 0x3E,R29
0055 51C0 SUBI R28,0x10
0056 40D0 SBCI R29,0
0057 EA0A LDI R16,0xAA
0058 8308 STD Y+0,R16
0059 2400 CLR R0
005A E1E5 LDI R30,0x15
005B E0F1 LDI R31,1
005C E011 LDI R17,1
005D 31E6 CPI R30,0x16
005E 07F1 CPC R31,R17
005F F011 BEQ 0x0062
0060 9201 ST R0,Z+
0061 CFFB RJMP 0x005D
0062 8300 STD Z+0,R16
0063 E8EC LDI R30,0x8C
0064 E0F0 LDI R31,0
0065 E0A0 LDI R26,0
0066 E0B1 LDI R27,1
0067 E010 LDI R17,0
0068 3AE1 CPI R30,0xA1
0069 07F1 CPC R31,R17
006A F021 BEQ 0x006F
006B 95C8 LPM
006C 9631 ADIW R30,1
006D 920D ST R0,X+
006E CFF9 RJMP 0x0068
006F 940E0138 CALL _main
_exit:
0071 CFFF RJMP _exit
FILE: E:\ICCAVR\project\AVRMEG~3\icc\009-AD-LED4\adc.c
(0001) /*
(0002) AD采样函数,标准10位精度采样函数,可以项目里直接使用。
(0003) */
(0004) #include "iom128v.h"
(0005)
(0006) /*ADC采样函数,采样第0通道信号,采样分辨率1024*/
(0007) unsigned int get_ad(void) {
(0008)
(0009) unsigned int i;
(0010)
(0011) ADMUX = (1 << REFS0); /*基准AVCC、通道0*/
_get_ad:
i --> R16
0072 E480 LDI R24,0x40
0073 B987 OUT 0x07,R24
(0012) ADCSRA = (1 << ADEN) | (1 << ADSC) /*使能、开启*/
0074 EC83 LDI R24,0xC3
0075 B986 OUT 0x06,R24
(0013) | (1 << ADPS1) | (1 << ADPS0); /*8分频*/
(0014) while(!(ADCSRA & (1 << ADIF))); /*等待采样结束*/
0076 9B34 SBIS 0x06,4
0077 CFFE RJMP 0x0076
(0015) i = ADC; /*读取AD结果*/
0078 B104 IN R16,0x04
0079 B115 IN R17,0x05
(0016) ADCSRA &= ~(1 << ADIF); /*清标志*/
007A 9834 CBI 0x06,4
(0017) ADCSRA &= ~(1 << ADEN); /*关闭转换*/
007B 9837 CBI 0x06,7
(0018)
(0019) return i; /*返回结果*/
007C 9508 RET
FILE: E:\ICCAVR\project\AVRMEG~3\icc\009-AD-LED4\led4.c
(0001) /*
(0002) 模块说明:
(0003)
(0004) LED数码管中断动态显示程序。
(0005) 1、程序通过SPI接口输出数据到HC595芯片驱动LED数据管简单显示。
(0006) 2、动态调度由片内定时器1中断产生,中断周期为5mS。
(0007) 3、内部1 M晶振,程序采用单任务方式,软件延时。
(0008) 4、此模块文件为使用文件,可直接用于项目中。
(0009) www.iccavr.com 阿发
(0010)
(0011) */
(0012) #include "iom128v.h"
(0013) #include <macros.h>
(0014)
(0015) unsigned char disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0};
(0016)
(0017) /*
(0018) 前4位为显示数值。
(0019) 最后一位为小数点显示位置。
(0020) */
(0021) unsigned char led_buf[] = {0, 0, 0, 0, 3}; /*显示信息*/
(0022)
(0023) /*------------------------------------------------------------------*-
(0024)
(0025) Disp_Init()
(0026) 显示初始化
(0027)
(0028) -*------------------------------------------------------------------*/
(0029) void disp_init(void) {
(0030)
(0031) /*初始化定时器*/
(0032) OCR1A = 625; /*计数周期为5mS,F=1M*/
_disp_init:
007D E781 LDI R24,0x71
007E E092 LDI R25,2
007F BD9B OUT 0x2B,R25
0080 BD8A OUT 0x2A,R24
(0033) TIMSK |= (1 << OCIE1A); /*比较中断A允许*/
0081 B787 IN R24,0x37
0082 6180 ORI R24,0x10
0083 BF87 OUT 0x37,R24
(0034) TCCR1A = 0x00;
0084 2422 CLR R2
0085 BC2F OUT 0x2F,R2
(0035) TCCR1B = (1 << WGM12); /*定时器工作在CTC计数器模式*/
0086 E088 LDI R24,0x8
0087 BD8E OUT 0x2E,R24
(0036) TCCR1B |= (1 << CS11); /*设置定时器的分频值为8分频*/
0088 B58E IN R24,0x2E
0089 6082 ORI R24,2
008A BD8E OUT 0x2E,R24
(0037)
(0038) /*SPI接口初始化*/
(0039)
(0040) DDRB = 0xFF; /* 设置PB口为输出*/
008B EF8F LDI R24,0xFF
008C BB87 OUT 0x17,R24
(0041) SPCR = (1<<SPE) | (1<<MSTR)
008D E583 LDI R24,0x53
008E B98D OUT 0x0D,R24
(0042) | (1<<SPR1) | (1<<SPR0); /* 使能SPI 主机模式,设置时钟速率为fck/128 */
(0043)
(0044) /*中断使能*/
(0045) SEI();
008F 9478 BSET 7
0090 9508 RET
_Int_TCCR1A:
temp --> R20
0091 922A ST R2,-Y
0092 923A ST R3,-Y
0093 930A ST R16,-Y
0094 931A ST R17,-Y
0095 938A ST R24,-Y
0096 939A ST R25,-Y
0097 93EA ST R30,-Y
0098 93FA ST R31,-Y
0099 B62F IN R2,0x3F
009A 922A ST R2,-Y
009B 940E01CA CALL push_gset1
(0046) }
(0047)
(0048) /*------------------------------------------------------------------*-
(0049)
(0050) Int_TCCR1A()
(0051) LED数码管动态显示函数
(0052)
(0053) 定时器'T1',A组比较中断产生5mS周期性中断
(0054) 在中断里刷新显示
(0055)
(0056) -*------------------------------------------------------------------*/
(0057) #pragma interrupt_handler Int_TCCR1A: 13
(0058) void Int_TCCR1A(void) {
(0059)
(0060) unsigned char temp;
(0061) static unsigned char i;
(0062)
(0063) PORTB &= ~(1 << PB0); /*准备锁存*/
009D 98C0 CBI 0x18,0
(0064) PORTB |= 0xF0; /*复位段选择口*/
009E B388 IN R24,0x18
009F 6F80 ORI R24,0xF0
00A0 BB88 OUT 0x18,R24
(0065) PORTB |= (1 << PB0); /*锁存数据*/
00A1 9AC0 SBI 0x18,0
(0066) if (i == 3) {
00A2 91800115 LDS R24,i
00A4 3083 CPI R24,3
00A5 F409 BNE 0x00A7
(0067) PORTB &= ~(1 << PB6); /*由于此处显示数值滞后一个周期所以显示位也要修改*/
00A6 98C6 CBI 0x18,6
(0068) } /*此处逻辑性很强,如不能理解可先跳过,以后熟练来再看*/
(0069) if (i == 2) {
00A7 91800115 LDS R24,i
00A9 3082 CPI R24,2
00AA F409 BNE 0x00AC
(0070) PORTB &= ~(1 << PB5);
00AB 98C5 CBI 0x18,5
(0071) }
(0072) if (i == 1) {
00AC 91800115 LDS R24,i
00AE 3081 CPI R24,1
00AF F409 BNE 0x00B1
(0073) PORTB &= ~(1 << PB4);
00B0 98C4 CBI 0x18,4
(0074) }
(0075) if (i == 0) {
00B1 90200115 LDS R2,i
00B3 2022 TST R2
00B4 F409 BNE 0x00B6
(0076) PORTB &= ~(1 << PB7);
00B5 98C7 CBI 0x18,7
(0077) }
(0078) temp = led_buf[i] % 16; /*滤除溢出的数值*/
00B6 E180 LDI R24,0x10
00B7 E091 LDI R25,1
00B8 91E00115 LDS R30,i
00BA 27FF CLR R31
00BB 0FE8 ADD R30,R24
00BC 1FF9 ADC R31,R25
00BD 8100 LDD R16,Z+0
00BE E110 LDI R17,0x10
00BF 940E0177 CALL mod8u
00C1 2F40 MOV R20,R16
(0079) temp = disp[temp]; /*取出当前显示信息*/
00C2 E080 LDI R24,0
00C3 E091 LDI R25,1
00C4 2FE4 MOV R30,R20
00C5 27FF CLR R31
00C6 0FE8 ADD R30,R24
00C7 1FF9 ADC R31,R25
00C8 8140 LDD R20,Z+0
(0080) if (led_buf[4] == i) { /*显示小数点*/
00C9 90200115 LDS R2,i
00CB 90300114 LDS R3,0x114
00CD 1432 CP R3,R2
00CE F421 BNE 0x00D3
(0081) SPDR = temp & 0x7F;
00CF 2F84 MOV R24,R20
00D0 778F ANDI R24,0x7F
00D1 B98F OUT 0x0F,R24
(0082) }
00D2 C001 RJMP 0x00D4
(0083) else {
(0084) SPDR = temp;
00D3 B94F OUT 0x0F,R20
(0085) }
(0086)
(0087) i ++;
00D4 91800115 LDS R24,i
00D6 5F8F SUBI R24,0xFF
00D7 93800115 STS i,R24
(0088) if (i > 3) { /*溢出处理*/
00D9 E083 LDI R24,3
00DA 90200115 LDS R2,i
00DC 1582 CP R24,R2
00DD F418 BCC 0x00E1
(0089) i = 0;
00DE 2422 CLR R2
00DF 92200115 STS i,R2
(0090) }
00E1 940E01CD CALL pop_gset1
00E3 9029 LD R2,Y+
00E4 BE2F OUT 0x3F,R2
00E5 91F9 LD R31,Y+
00E6 91E9 LD R30,Y+
00E7 9199 LD R25,Y+
00E8 9189 LD R24,Y+
00E9 9119 LD R17,Y+
00EA 9109 LD R16,Y+
00EB 9039 LD R3,Y+
00EC 9029 LD R2,Y+
00ED 9518 RETI
_delay_ms:
a --> R20
b --> R22
i --> R16
00EE 940E01C8 CALL push_gset2
FILE: E:\ICCAVR\project\AVRMEG~3\icc\009-AD-LED4\main.c
(0001) /*
(0002) 实验九:
(0003) AD转换实验。
(0004) 1、AD转换实验。程序进行周期AD转换,在并转换值显示在数码管上。
(0005) 2、使用内部1 M晶振。
(0006) 3、进行此实验需要插上SPI、AD0短路块。
(0007) 4、此实验采用项目化管理,主要文件有ADC、DISP、主程序。
(0008) 5、此实验包含ADC采样、数值转换、显示,是一个完整的小系统。
(0009)
(0010) AVR mega128学习板
(0011) www.iccavr.com 阿发
(0012) 2007-10-12
(0013) */
(0014)
(0015) #include "iom128v.h"
(0016) #include <macros.h>
(0017)
(0018) extern unsigned int get_ad(void); /*AD采样函数*/
(0019) extern void disp_init(void); /*显示初始化*/
(0020) extern unsigned char led_buf[]; /*显示缓存*/
(0021)
(0022) /*延时函数,频率1MHz,单位mS*/
(0023) void delay_ms(unsigned char i) {
(0024)
(0025) unsigned char a, b;
(0026) for (a = 0; a < i; a++) {
00F0 2744 CLR R20
00F1 C006 RJMP 0x00F8
(0027) for (b = 1; b; b++);
00F2 E061 LDI R22,1
00F3 C001 RJMP 0x00F5
00F4 9563 INC R22
00F5 2366 TST R22
00F6 F7E9 BNE 0x00F4
00F7 9543 INC R20
00F8 1740 CP R20,R16
00F9 F3C0 BCS 0x00F2
00FA 940E01BF CALL pop_gset2
00FC 9508 RET
(0028) }
(0029) }
(0030)
(0031) /*IO口初始化函数*/
(0032) void io_init(void) {
(0033)
(0034) DDRA = 0x00; /*方向输入*/
_io_init:
00FD 2422 CLR R2
00FE BA2A OUT 0x1A,R2
(0035) PORTA = 0xFF; /*打开上拉*/
00FF EF8F LDI R24,0xFF
0100 BB8B OUT 0x1B,R24
(0036) DDRB = 0xFF; /*方向输出*/
0101 BB87 OUT 0x17,R24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -