📄 coder.lst
字号:
__text_start:
__start:
001E E5CF LDI R28,0x5F
001F E0D4 LDI R29,4
0020 BFCD OUT 0x3D,R28
0021 BFDE OUT 0x3E,R29
0022 51C4 SUBI R28,0x14
0023 40D0 SBCI R29,0
0024 EA0A LDI R16,0xAA
0025 8308 STD Y+0,R16
0026 2400 CLR R0
0027 E7E6 LDI R30,0x76
0028 E0F0 LDI R31,0
0029 E010 LDI R17,0
002A 38E8 CPI R30,0x88
002B 07F1 CPC R31,R17
002C F011 BEQ 0x002F
002D 9201 ST R0,Z+
002E CFFB RJMP 0x002A
002F 8300 STD Z+0,R16
0030 E2E6 LDI R30,0x26
0031 E0F0 LDI R31,0
0032 E6A0 LDI R26,0x60
0033 E0B0 LDI R27,0
0034 E010 LDI R17,0
0035 33EC CPI R30,0x3C
0036 07F1 CPC R31,R17
0037 F021 BEQ 0x003C
0038 95C8 LPM
0039 9631 ADIW R30,1
003A 920D ST R0,X+
003B CFF9 RJMP 0x0035
003C D132 RCALL _main
_exit:
003D CFFF RJMP _exit
FILE: D:\AVR程序\简易编码系统\coder.c
(0001) //中断方式发送PWM脉冲,负脉冲,变化范围为1MS~2MS。INT0为教练接口输入负脉冲,INT1为教练接口2,输入正脉冲后自动翻转,
(0002) //外部中断接口打开上拉。隔离脉冲为500US
(0003) //有一个教练允许开关,打开后进入死循环,并允许外部中断,前提条件是有信号,用定时器0进行信号有无判断
(0004) //定时器1采用比较匹配方式触发中断进行信号发送
(0005)
(0006)
(0007) #include <iom8v.h>
(0008) #include <macros.h>
(0009)
(0010) #define Uchar unsigned char
(0011) #define Uint unsigned int
(0012)
(0013)
(0014) #define nop() asm("nop")
(0015) #define _nop_() asm("nop")
(0016)
(0017)
(0018)
(0019) #define PB PORTB
(0020) #define PC PORTC
(0021) #define PD PORTD
(0022)
(0023) #define IN0 PIND&0x04
(0024) #define IN1 PIND&0x08
(0025)
(0026) #define LEDH PB|=0x01
(0027) #define LEDL PB&=~0x01
(0028)
(0029) #define BUTTON1 PINB&0x02
(0030) #define BUTTON2 PINB&0x04
(0031) #define BUTTON3 PINB&0x08
(0032) #define BUTTON4 PINB&0x10
(0033) #define BUTTON5 PINB&0x20
(0034)
(0035) #define OUTH PD|=0x80
(0036) #define OUTL PD&=~0x80
(0037)
(0038) #define LOW_TIME 400
(0039) #define SWH_time 900
(0040) #define SWL_time 100
(0041)
(0042) Uint ch_time[9]={1000,1000,1000,1000,1000,1000,1000,1000,1000};//输出用
(0043) Uint time[9];//输出缓存
(0044) Uchar ch_counter=0;//通道计数,用来与数据采集同步
(0045) Uchar input=0;//信号输入有无标志
(0046) Uchar train=0;//训练开始表示,防止切换时发生抖舵
(0047)
(0048) void port_init(void)
(0049) {
(0050) PORTB = 0x3E;
_port_init:
003E E38E LDI R24,0x3E
003F BB88 OUT 0x18,R24
(0051) DDRB = 0x01;
0040 E081 LDI R24,1
0041 BB87 OUT 0x17,R24
(0052) PORTC = 0x00; //m103 output only
0042 2422 CLR R2
0043 BA25 OUT 0x15,R2
(0053) DDRC = 0x00;
0044 BA24 OUT 0x14,R2
(0054) PORTD = 0x0C;
0045 E08C LDI R24,0xC
0046 BB82 OUT 0x12,R24
(0055) DDRD = 0x80;
0047 E880 LDI R24,0x80
0048 BB81 OUT 0x11,R24
0049 9508 RET
(0056) }
(0057)
(0058) //c输入
(0059)
(0060) //TIMER0 initialize - prescale:1024
(0061) // desired value: 1Hz
(0062) // actual value: Out of range
(0063) void timer0_init(void)
(0064) {
(0065) TCCR0 = 0x00; //stop
_timer0_init:
004A 2422 CLR R2
004B BE23 OUT 0x33,R2
(0066) TCNT0 = 0x00 /*INVALID SETTING*/; //set count
004C BE22 OUT 0x32,R2
004D 9508 RET
_timer0_ovf_isr:
004E 922A ST R2,-Y
004F B62F IN R2,0x3F
0050 922A ST R2,-Y
(0067) //TCCR0 = 0x05; //start timer
(0068) }
(0069)
(0070) #pragma interrupt_handler timer0_ovf_isr:10
(0071) void timer0_ovf_isr(void)
(0072) {
(0073) input=0;
0051 2422 CLR R2
0052 92200073 STS input,R2
(0074) train=0;
0054 92200074 STS train,R2
0056 9029 LD R2,Y+
0057 BE2F OUT 0x3F,R2
0058 9029 LD R2,Y+
0059 9518 RETI
(0075) }
(0076)
(0077) //TIMER1 initialize - prescale:8
(0078) // WGM: 0) Normal, TOP=0xFFFF
(0079) // desired value: 1Hz
(0080) // actual value: Out of range
(0081) void timer1_init(void)
(0082) {
(0083) TCCR1B = 0x00; //stop
_timer1_init:
005A 2422 CLR R2
005B BC2E OUT 0x2E,R2
(0084) TCNT1H = 0x00 /*INVALID SETTING*/; //setup
005C BC2D OUT 0x2D,R2
(0085) TCNT1L = 0x00 /*INVALID SETTING*/;
005D BC2C OUT 0x2C,R2
(0086) OCR1AH = 0x00 /*INVALID SETTING*/;
005E BC2B OUT 0x2B,R2
(0087) OCR1AL = 0x00 /*INVALID SETTING*/;
005F BC2A OUT 0x2A,R2
(0088) OCR1BH = 0x00 /*INVALID SETTING*/;
0060 BC29 OUT 0x29,R2
(0089) OCR1BL = 0x00 /*INVALID SETTING*/;
0061 BC28 OUT 0x28,R2
(0090) ICR1H = 0x00 /*INVALID SETTING*/;
0062 BC27 OUT 0x27,R2
(0091) ICR1L = 0x00 /*INVALID SETTING*/;
0063 BC26 OUT 0x26,R2
(0092) TCCR1A = 0x00;
0064 BC2F OUT 0x2F,R2
(0093) TCCR1B = 0x02; //start Timer
0065 E082 LDI R24,2
0066 BD8E OUT 0x2E,R24
0067 9508 RET
_timer1_compa_isr:
counter --> R16
0068 920A ST R0,-Y
0069 921A ST R1,-Y
006A 922A ST R2,-Y
006B 923A ST R3,-Y
006C 930A ST R16,-Y
006D 931A ST R17,-Y
006E 938A ST R24,-Y
006F 939A ST R25,-Y
0070 93AA ST R26,-Y
0071 93BA ST R27,-Y
0072 93EA ST R30,-Y
0073 93FA ST R31,-Y
0074 B60F IN R0,0x3F
0075 920A ST R0,-Y
(0094) }
(0095)
(0096) #pragma interrupt_handler timer1_compa_isr:7
(0097) void timer1_compa_isr(void)
(0098) {
(0099) //compare occured TCNT1=OCR1A//本函数来自4Vf改装系统,有部分改变
(0100) static Uchar output_static=1;//输出状态,0代表即将输出一个低电平,1代表即将输出一个高电平
(0101) //第一次发信号先发一个低电平
(0102)
(0103) Uchar counter;//普通计数器用来拷贝数据
(0104)
(0105)
(0106) output_static=!output_static;
0076 90200075 LDS R2,output_static
0078 2022 TST R2
0079 F419 BNE 0x007D
007A E001 LDI R16,1
007B E010 LDI R17,0
007C C002 RJMP 0x007F
007D 2700 CLR R16
007E 2711 CLR R17
007F 93000075 STS output_static,R16
(0107)
(0108) switch(output_static)
0081 2711 CLR R17
0082 3000 CPI R16,0
0083 0701 CPC R16,R17
0084 F029 BEQ 0x008A
0085 3001 CPI R16,1
0086 E0E0 LDI R30,0
0087 071E CPC R17,R30
0088 F091 BEQ 0x009B
0089 C044 RJMP 0x00CE
(0109) {
(0110) case 0:OUTH;
008A 9A97 SBI 0x12,7
(0111) TCNT1=0;//定时器清零
008B 2422 CLR R2
008C 2433 CLR R3
008D BC3D OUT 0x2D,R3
008E BC2C OUT 0x2C,R2
(0112) OCR1A=LOW_TIME;
008F E980 LDI R24,0x90
0090 E091 LDI R25,1
0091 BD9B OUT 0x2B,R25
0092 BD8A OUT 0x2A,R24
(0113) if(ch_counter==9)ch_counter=0;//计数清零同步放行
0093 91800072 LDS R24,ch_counter
0095 3089 CPI R24,0x9
0096 F009 BEQ 0x0098
0097 C036 RJMP 0x00CE
0098 92200072 STS ch_counter,R2
(0114) break;
009A C033 RJMP 0x00CE
(0115)
(0116) case 1:OUTL;
009B 9897 CBI 0x12,7
(0117) TCNT1=0;//定时器清零
009C 2422 CLR R2
009D 2433 CLR R3
009E BC3D OUT 0x2D,R3
009F BC2C OUT 0x2C,R2
(0118) OCR1A=ch_time[ch_counter];
00A0 90200072 LDS R2,ch_counter
00A2 E082 LDI R24,2
00A3 9D82 MUL R24,R2
00A4 01F0 MOVW R30,R0
00A5 E680 LDI R24,0x60
00A6 E090 LDI R25,0
00A7 0FE8 ADD R30,R24
00A8 1FF9 ADC R31,R25
00A9 8020 LDD R2,Z+0
00AA 8031 LDD R3,Z+1
00AB BC3B OUT 0x2B,R3
00AC BC2A OUT 0x2A,R2
(0119) if(ch_counter==8)//最后一个高电平是同步电平
00AD 91800072 LDS R24,ch_counter
00AF 3088 CPI R24,0x8
00B0 F4C1 BNE 0x00C9
(0120) {
(0121) for(counter=0;counter<=8;counter++)
00B1 2700 CLR R16
00B2 C013 RJMP 0x00C6
(0122) {
(0123) ch_time[counter]=time[counter]+600;
00B3 E082 LDI R24,2
00B4 9F80 MUL R24,R16
00B5 E786 LDI R24,0x76
00B6 E090 LDI R25,0
00B7 01F0 MOVW R30,R0
00B8 0FE8 ADD R30,R24
00B9 1FF9 ADC R31,R25
00BA 8180 LDD R24,Z+0
00BB 8191 LDD R25,Z+1
00BC 5A88 SUBI R24,0xA8
00BD 4F9D SBCI R25,0xFD
00BE E6E0 LDI R30,0x60
00BF E0F0 LDI R31,0
00C0 01D0 MOVW R26,R0
00C1 0FAE ADD R26,R30
00C2 1FBF ADC R27,R31
00C3 938D ST R24,X+
00C4 939C ST R25,0(X)
00C5 9503 INC R16
00C6 E088 LDI R24,0x8
00C7 1780 CP R24,R16
00C8 F750 BCC 0x00B3
(0124)
(0125) }
(0126) }
(0127) ch_counter++;
00C9 91800072 LDS R24,ch_counter
00CB 5F8F SUBI R24,0xFF
00CC 93800072 STS ch_counter,R24
(0128) }// switch(output_static)
00CE 9009 LD R0,Y+
00CF BE0F OUT 0x3F,R0
00D0 91F9 LD R31,Y+
00D1 91E9 LD R30,Y+
00D2 91B9 LD R27,Y+
00D3 91A9 LD R26,Y+
00D4 9199 LD R25,Y+
00D5 9189 LD R24,Y+
00D6 9119 LD R17,Y+
00D7 9109 LD R16,Y+
00D8 9039 LD R3,Y+
00D9 9029 LD R2,Y+
00DA 9019 LD R1,Y+
00DB 9009 LD R0,Y+
00DC 9518 RETI
(0129)
(0130) }//void timer1_compa_isr(void)
(0131)
(0132)
(0133)
(0134) //ADC initialize
(0135) // Conversion time: 104uS
(0136) void adc_init(void)
(0137) {
(0138) ADCSR = 0x00; //disable adc
_adc_init:
00DD 2422 CLR R2
00DE B826 OUT 0x06,R2
(0139) ADMUX = 0x00; //select adc input 0
00DF B827 OUT 0x07,R2
(0140) ACSR = 0x80;
00E0 E880 LDI R24,0x80
00E1 B988 OUT 0x08,R24
(0141) ADCSR = 0x86;
00E2 E886 LDI R24,0x86
00E3 B986 OUT 0x06,R24
00E4 9508 RET
(0142) }
(0143)
(0144) //Watchdog initialize
(0145) // prescale: 32K
(0146) void watchdog_init(void)
(0147) {
(0148) WDR(); //this prevents a timout on enabling
_watchdog_init:
00E5 95A8 WDR
(0149) WDTCR = 0x18;
00E6 E188 LDI R24,0x18
00E7 BD81 OUT 0x21,R24
(0150) WDTCR = 0x09; //WATCHDOG ENABLED - dont forget to issue WDRs
00E8 E089 LDI R24,0x9
00E9 BD81 OUT 0x21,R24
00EA 9508 RET
(0151)
(0152) }
(0153)
(0154)
(0155)
(0156) //call this routine to initialize all peripherals
(0157) void init_devices(void)
(0158) {
(0159) //stop errant interrupts until set up
(0160) CLI(); //disable all interrupts
_init_devices:
00EB 94F8 BCLR 7
(0161)
(0162) port_init();
00EC DF51 RCALL _port_init
(0163) timer0_init();
00ED DF5C RCALL _timer0_init
(0164) timer1_init();
00EE DF6B RCALL _timer1_init
(0165) adc_init();
00EF DFED RCALL _adc_init
(0166) OSCCAL=0xb3;
00F0 EB83 LDI R24,0xB3
00F1 BF81 OUT 0x31,R24
(0167) watchdog_init();
00F2 DFF2 RCALL _watchdog_init
(0168) MCUCR = 0x05;
00F3 E085 LDI R24,5
00F4 BF85 OUT 0x35,R24
(0169) //GICR//中断开关应在MAIN中用开关和信号有无控制
(0170) GICR = 0x00;
00F5 2422 CLR R2
00F6 BE2B OUT 0x3B,R2
(0171) TIMSK = 0x11; //timer interrupt sources
00F7 E181 LDI R24,0x11
00F8 BF89 OUT 0x39,R24
(0172) SEI(); //re-enable interrupts
00F9 9478 BSET 7
00FA 9508 RET
_int0_isr:
00FB 922A ST R2,-Y
00FC 930A ST R16,-Y
00FD 931A ST R17,-Y
00FE 938A ST R24,-Y
00FF 93EA ST R30,-Y
0100 B62F IN R2,0x3F
0101 922A ST R2,-Y
(0173) //all peripherals are now initialized
(0174) }
(0175)
(0176)
(0177)
(0178) #pragma interrupt_handler int0_isr:2
(0179) void int0_isr(void)
(0180) {
(0181) //external interupt on INT0 负输入
(0182) TCNT0 = 0x00 ;//有信号
0102 2422 CLR R2
0103 BE22 OUT 0x32,R2
(0183) input=1;
0104 E081 LDI R24,1
0105 93800073 STS input,R24
(0184) if(train)//先不忙发送
0107 90200074 LDS R2,train
0109 2022 TST R2
010A F099 BEQ 0x011E
(0185) switch(IN0)
010B B300 IN R16,0x10
010C 2711 CLR R17
010D 7004 ANDI R16,4
010E 7010 ANDI R17,0
010F 3000 CPI R16,0
0110 0701 CPC R16,R17
0111 F049 BEQ 0x011B
0112 3000 CPI R16,0
0113 E0E0 LDI R30,0
0114 071E CPC R17,R30
0115 F044 BLT 0x011E
0116 3004 CPI R16,4
0117 E0E0 LDI R30,0
0118 071E CPC R17,R30
0119 F019 BEQ 0x011D
011A C003 RJMP 0x011E
(0186) {
(0187) case 0:
(0188) OUTL;
011B 9897 CBI 0x12,7
(0189) break;
011C C001 RJMP 0x011E
(0190) case 0x04:
(0191) OUTH;
011D 9A97 SBI 0x12,7
(0192) }
011E 9029 LD R2,Y+
011F BE2F OUT 0x3F,R2
0120 91E9 LD R30,Y+
0121 9189 LD R24,Y+
0122 9119 LD R17,Y+
0123 9109 LD R16,Y+
0124 9029 LD R2,Y+
0125 9518 RETI
_int1_isr:
0126 922A ST R2,-Y
0127 930A ST R16,-Y
0128 931A ST R17,-Y
0129 938A ST R24,-Y
012A 93EA ST R30,-Y
012B B62F IN R2,0x3F
012C 922A ST R2,-Y
(0193) }
(0194)
(0195) #pragma interrupt_handler int1_isr:3
(0196) void int1_isr(void)
(0197) {
(0198) //external interupt on INT1 正输入自动反向
(0199) TCNT0 = 0x00 ;//有信号
012D 2422 CLR R2
012E BE22 OUT 0x32,R2
(0200) input=1;
012F E081 LDI R24,1
0130 93800073 STS input,R24
(0201) if(train)//先不忙发送
0132 90200074 LDS R2,train
0134 2022 TST R2
0135 F099 BEQ 0x0149
(0202) switch(IN1)
0136 B300 IN R16,0x10
0137 2711 CLR R17
0138 7008 ANDI R16,0x8
0139 7010 ANDI R17,0
013A 3000 CPI R16,0
013B 0701 CPC R16,R17
013C F049 BEQ 0x0146
013D 3000 CPI R16,0
013E E0E0 LDI R30,0
013F 071E CPC R17,R30
0140 F044 BLT 0x0149
0141 3008 CPI R16,0x8
0142 E0E0 LDI R30,0
0143 071E CPC R17,R30
0144 F019 BEQ 0x0148
0145 C003 RJMP 0x0149
(0203) {
(0204) case 0:
(0205) OUTH;
0146 9A97 SBI 0x12,7
(0206) break;
0147 C001 RJMP 0x0149
(0207) case 0x08:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -