📄 dac.lst
字号:
__start:
__text_start:
0043 EFCF LDI R28,0xFF
0044 E0D2 LDI R29,2
0045 BFCD OUT 0x3D,R28
0046 BFDE OUT 0x3E,R29
0047 51C0 SUBI R28,0x10
0048 40D0 SBCI R29,0
0049 EA0A LDI R16,0xAA
004A 8308 STD Y+0,R16
004B 2400 CLR R0
004C E5E2 LDI R30,0x52
004D E0F1 LDI R31,1
004E E011 LDI R17,1
004F 35E9 CPI R30,0x59
0050 07F1 CPC R31,R17
0051 F011 BEQ 0x0054
0052 9201 ST R0,Z+
0053 CFFB RJMP 0x004F
0054 8300 STD Z+0,R16
0055 E3E4 LDI R30,0x34
0056 E0F0 LDI R31,0
0057 E0A0 LDI R26,0
0058 E0B1 LDI R27,1
0059 E010 LDI R17,0
005A 38E6 CPI R30,0x86
005B 07F1 CPC R31,R17
005C F021 BEQ 0x0061
005D 95C8 LPM
005E 9631 ADIW R30,1
005F 920D ST R0,X+
0060 CFF9 RJMP 0x005A
0061 D0D4 RCALL _main
_exit:
0062 CFFF RJMP _exit
FILE: C:\调试程序\mega48\DAC\adc.c
(0001) #include<iom48v.h>
(0002) unsigned int adc_rel;//AD转换结果
(0003) unsigned char adc_mux;//AD通道
(0004) extern unsigned int adc_old;
(0005) /* 微秒级延时程序 */
(0006) void delay_us(int time)
(0007) {
(0008) do
(0009) {
(0010) time--;
_delay_us:
time --> R16
0063 5001 SUBI R16,1
0064 4010 SBCI R17,0
(0011) }
(0012) while (time>1);
0065 E081 LDI R24,1
0066 E090 LDI R25,0
0067 1780 CP R24,R16
0068 0791 CPC R25,R17
0069 F3CC BLT 0x0063
006A 9508 RET
_delay_ms:
time --> R20
006B D17C RCALL push_gset1
006C 01A8 MOVW R20,R16
(0013) }
(0014) /* 毫秒级延时程序 */
(0015) void delay_ms(unsigned int time)
(0016) {
006D C005 RJMP 0x0073
(0017) while(time!=0)
(0018) {
(0019) delay_us(1000);
006E EE08 LDI R16,0xE8
006F E013 LDI R17,3
0070 DFF2 RCALL _delay_us
(0020) time--;
0071 5041 SUBI R20,1
0072 4050 SBCI R21,0
0073 3040 CPI R20,0
0074 0745 CPC R20,R21
0075 F7C1 BNE 0x006E
0076 D174 RCALL pop_gset1
0077 9508 RET
(0021) }
(0022) }
(0023) //ADC初始化
(0024) void adc_init(void)
(0025) {
(0026) DDRC=0x00;
_adc_init:
0078 2422 CLR R2
0079 B827 OUT 0x07,R2
(0027) PORTC=0x00;
007A B828 OUT 0x08,R2
(0028) ADCSRA = 0x00;
007B 9220007A STS 0x7A,R2
(0029) ADMUX =(1<<REFS0)|(adc_mux&0x0f);//选择内部AVCC为基准
007D 91800154 LDS R24,adc_mux
007F 708F ANDI R24,0xF
0080 6480 ORI R24,0x40
0081 9380007C STS 0x7C,R24
(0030) ACSR =(1<<ACD);//关闭模拟比较器
0083 E880 LDI R24,0x80
0084 BF80 OUT 0x30,R24
(0031) ADCSRB=0;
0085 9220007B STS 0x7B,R2
(0032) ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//64分频
0087 EC8E LDI R24,0xCE
0088 9380007A STS 0x7A,R24
008A 9508 RET
_adc_isr:
008B 922A ST R2,-Y
008C 923A ST R3,-Y
008D 930A ST R16,-Y
008E 931A ST R17,-Y
008F 932A ST R18,-Y
0090 933A ST R19,-Y
0091 938A ST R24,-Y
0092 939A ST R25,-Y
0093 93EA ST R30,-Y
0094 B62F IN R2,0x3F
0095 922A ST R2,-Y
(0033) }
(0034) //ADC完成中断
(0035) #pragma interrupt_handler adc_isr:22
(0036) void adc_isr(void)
(0037) {
(0038) static unsigned i;
(0039) adc_rel+=ADC&0x3ff;
0096 91800078 LDS R24,0x78
0098 91900079 LDS R25,0x79
009A 7093 ANDI R25,3
009B 90200155 LDS R2,adc_rel
009D 90300156 LDS R3,adc_rel+1
009F 0E28 ADD R2,R24
00A0 1E39 ADC R3,R25
00A1 92300156 STS adc_rel+1,R3
00A3 92200155 STS adc_rel,R2
(0040) ADMUX=(1<<REFS0)|(adc_mux&0x0f);//选择内部AVCC为基准
00A5 91800154 LDS R24,adc_mux
00A7 708F ANDI R24,0xF
00A8 6480 ORI R24,0x40
00A9 9380007C STS 0x7C,R24
(0041) ADCSRA|=(1<<ADSC);//启动AD转换
00AB 9180007A LDS R24,0x7A
00AD 6480 ORI R24,0x40
00AE 9380007A STS 0x7A,R24
(0042) if (i<63)
00B0 91800152 LDS R24,i
00B2 91900153 LDS R25,i+1
00B4 338F CPI R24,0x3F
00B5 E0E0 LDI R30,0
00B6 079E CPC R25,R30
00B7 F430 BCC 0x00BE
(0043) i++;
00B8 9601 ADIW R24,1
00B9 93900153 STS i+1,R25
00BB 93800152 STS i,R24
00BD C015 RJMP 0x00D3
(0044) else
(0045) {
(0046) adc_old=adc_rel/64;//64点平均滤波
00BE E026 LDI R18,6
00BF E030 LDI R19,0
00C0 91000155 LDS R16,adc_rel
00C2 91100156 LDS R17,adc_rel+1
00C4 D168 RCALL lsr16
00C5 93100158 STS adc_old+1,R17
00C7 93000157 STS adc_old,R16
(0047) i=0;
00C9 2422 CLR R2
00CA 2433 CLR R3
00CB 92300153 STS i+1,R3
00CD 92200152 STS i,R2
(0048) adc_rel=0;
00CF 92300156 STS adc_rel+1,R3
00D1 92200155 STS adc_rel,R2
(0049) }
00D3 9029 LD R2,Y+
00D4 BE2F OUT 0x3F,R2
00D5 91E9 LD R30,Y+
00D6 9199 LD R25,Y+
00D7 9189 LD R24,Y+
00D8 9139 LD R19,Y+
00D9 9129 LD R18,Y+
00DA 9119 LD R17,Y+
00DB 9109 LD R16,Y+
00DC 9039 LD R3,Y+
00DD 9029 LD R2,Y+
00DE 9518 RETI
FILE: C:\调试程序\mega48\DAC\dac.c
(0001) //使用内部RC振荡,PB6-G,PB7-DP短路块连接
(0002) //使用INT0/INT1按键改变DAC输出电压大小
(0003) //可以使用ADC0通道测量DAC的输出电压
(0004) //演示了使用PC机对MEGA8开发板进行控制的方法
(0005) #include <iom48v.h>
(0006) #include <macros.h>
(0007) #define osccal 0x9A//内部RC校正常数
(0008) #define Vref 500//参考电压值
(0009) #include"uart.h"
(0010) #include"adc.h"
(0011) unsigned int adc_old;
(0012) //T1初始化程序
(0013) void timer1_init(void)
(0014) {
(0015) TCCR1B = 0; //stop
_timer1_init:
00DF 2422 CLR R2
00E0 92200081 STS 0x81,R2
(0016) TCNT1H = 0;
00E2 92200085 STS 0x85,R2
(0017) OCR1A=0;
00E4 2433 CLR R3
00E5 92300089 STS 0x89,R3
00E7 92200088 STS 0x88,R2
(0018) TCCR1A =(1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
00E9 E883 LDI R24,0x83
00EA 93800080 STS 0x80,R24
(0019) TCCR1B =(1<<CS10);//(1<<WGM13)|(1<<WGM12)|(1<<CS10); //0x1A //start Timer
00EC E081 LDI R24,1
00ED 93800081 STS 0x81,R24
00EF 9508 RET
_int_isr:
i --> R20
00F0 D10E RCALL push_lset
00F1 D0F6 RCALL push_gset1
(0020) }
(0021) //两个中断向量使用同一个中断处理函数,实现对INT0/INT1按键的处理
(0022) #pragma interrupt_handler int_isr:2 int_isr:3
(0023) void int_isr(void)
(0024) {
(0025) unsigned char i;
(0026) delay_ms(10);
00F2 E00A LDI R16,0xA
00F3 E010 LDI R17,0
00F4 DF76 RCALL _delay_ms
(0027) i=PIND&0x0c;//键盘消抖动
00F5 B149 IN R20,0x09
00F6 704C ANDI R20,0xC
(0028) if(i==0x0c)
00F7 304C CPI R20,0xC
00F8 F409 BNE 0x00FA
(0029) return;
00F9 C039 RJMP 0x0133
(0030) else
(0031) {
(0032) if (i==0x08)//INT0键按下
00FA 3048 CPI R20,0x8
00FB F4C1 BNE 0x0114
(0033) {
(0034) if(OCR1A<0x3ef)
00FC 91800088 LDS R24,0x88
00FE 91900089 LDS R25,0x89
0100 3E8F CPI R24,0xEF
0101 E0E3 LDI R30,3
0102 079E CPC R25,R30
0103 F450 BCC 0x010E
(0035) OCR1A+=0x10;//递增
0104 91800088 LDS R24,0x88
0106 91900089 LDS R25,0x89
0108 9640 ADIW R24,0x10
0109 93900089 STS 0x89,R25
010B 93800088 STS 0x88,R24
010D C006 RJMP 0x0114
(0036) else
(0037) OCR1A=0x3ff;
010E EF8F LDI R24,0xFF
010F E093 LDI R25,3
0110 93900089 STS 0x89,R25
0112 93800088 STS 0x88,R24
(0038) }
(0039) if (i==0x04)//INT1键按下
0114 3044 CPI R20,4
0115 F4C9 BNE 0x012F
(0040) {
(0041) if(OCR1A>0x10)
0116 E180 LDI R24,0x10
0117 E090 LDI R25,0
0118 90200088 LDS R2,0x88
011A 90300089 LDS R3,0x89
011C 1582 CP R24,R2
011D 0593 CPC R25,R3
011E F450 BCC 0x0129
(0042) OCR1A-=0x10;//递减
011F 91800088 LDS R24,0x88
0121 91900089 LDS R25,0x89
0123 9740 SBIW R24,0x10
0124 93900089 STS 0x89,R25
0126 93800088 STS 0x88,R24
0128 C006 RJMP 0x012F
(0043) else
(0044) OCR1A=0;
0129 2422 CLR R2
012A 2433 CLR R3
012B 92300089 STS 0x89,R3
012D 92200088 STS 0x88,R2
(0045) }
(0046) while((PIND&0x0c)!=0x0c)//检查按键释放
012F B189 IN R24,0x09
0130 708C ANDI R24,0xC
0131 308C CPI R24,0xC
0132 F7E1 BNE 0x012F
(0047) ;
(0048) }
0133 D0B7 RCALL pop_gset1
0134 D0E1 RCALL pop_lset
0135 9518 RETI
(0049) }
(0050) //MAIN程序
(0051) void main(void)
(0052) {
(0053) unsigned char i;
(0054) unsigned int temp;
(0055) DDRB=(1<<PB1); //置输出比较oc1a为高电平
_main:
temp --> R22
i --> R10
0136 E082 LDI R24,2
0137 B984 OUT 0x04,R24
(0056) DDRD=0xf0;
0138 EF80 LDI R24,0xF0
0139 B98A OUT 0x0A,R24
(0057) PORTD=0xff;
013A EF8F LDI R24,0xFF
013B B98B OUT 0x0B,R24
(0058) OSCCAL=osccal;
013C E98A LDI R24,0x9A
013D 93800066 STS 0x66,R24
(0059) adc_mux=0;
013F 2422 CLR R2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -