⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jidong.lst

📁 基于m16的寻迹寻光小车程序
💻 LST
📖 第 1 页 / 共 5 页
字号:
(0096) 	else if( small_tmp == d ) return 3;
     17F 810C      LDD	R16,Y+4
     180 811D      LDD	R17,Y+5
     181 812E      LDD	R18,Y+6
     182 813F      LDD	R19,Y+7
     183 01CE      MOVW	R24,R28
     184 968C      ADIW	R24,0x2C
     185 939A      ST	R25,-Y
     186 938A      ST	R24,-Y
     187 940E 0BB3 CALL	fpcmp1
     189 F411      BNE	0x018C
     18A E003      LDI	R16,3
     18B C00E      RJMP	0x019A
(0097) 	else if( small_tmp == e ) return 4;
     18C 810C      LDD	R16,Y+4
     18D 811D      LDD	R17,Y+5
     18E 812E      LDD	R18,Y+6
     18F 813F      LDD	R19,Y+7
     190 01CE      MOVW	R24,R28
     191 96C0      ADIW	R24,0x30
     192 939A      ST	R25,-Y
     193 938A      ST	R24,-Y
     194 940E 0BB3 CALL	fpcmp1
     196 F411      BNE	0x0199
     197 E004      LDI	R16,4
     198 C001      RJMP	0x019A
(0098) 	else return 1;
     199 E001      LDI	R16,1
     19A 96A4      ADIW	R28,0x24
     19B 9508      RET
_car_xunguang:
  s_flag               --> R10
     19C 940E 090A CALL	push_xgset300C
     19E 2EA0      MOV	R10,R16
(0099) }
(0100) 
(0101) //完成相应动作
(0102) void car_xunguang( uchar s_flag )
(0103) {
(0104)  	 switch( s_flag )
     19F 2D4A      MOV	R20,R10
     1A0 2755      CLR	R21
     1A1 3040      CPI	R20,0
     1A2 0745      CPC	R20,R21
     1A3 F089      BEQ	0x01B5
     1A4 3041      CPI	R20,1
     1A5 E0E0      LDI	R30,0
     1A6 075E      CPC	R21,R30
     1A7 F079      BEQ	0x01B7
     1A8 3042      CPI	R20,2
     1A9 E0E0      LDI	R30,0
     1AA 075E      CPC	R21,R30
     1AB F069      BEQ	0x01B9
     1AC 3043      CPI	R20,3
     1AD E0E0      LDI	R30,0
     1AE 075E      CPC	R21,R30
     1AF F059      BEQ	0x01BB
     1B0 3044      CPI	R20,4
     1B1 E0E0      LDI	R30,0
     1B2 075E      CPC	R21,R30
     1B3 F049      BEQ	0x01BD
     1B4 C009      RJMP	0x01BE
(0105) 	 {
(0106) 	 case 0: turn_l();   break;
     1B5 DEC5      RCALL	_turn_l
     1B6 C007      RJMP	0x01BE
(0107) 	 case 1: go_ahead(); break;
     1B7 DEB5      RCALL	_go_ahead
     1B8 C005      RJMP	0x01BE
(0108) 	 case 2: turn_r();   break;
     1B9 DEC8      RCALL	_turn_r
     1BA C003      RJMP	0x01BE
(0109) 	 case 3: turn_l();   break;
     1BB DEBF      RCALL	_turn_l
     1BC C001      RJMP	0x01BE
(0110) 	 case 4: turn_r();   break;	                 
     1BD DEC4      RCALL	_turn_r
     1BE 940C 090F JMP	pop_xgset300C
(0111) 	 }
(0112) }	  	
(0113) 
(0114) //使用ADC
(0115) void ADC_start( void )
(0116) {
(0117)     ADCSRA |= ( 1 << ADEN ) | ( 1 << ADIE ) | ( 1 << ADSC ) ;  //ADC使能位, 中断位置位
_ADC_start:
     1C0 B186      IN	R24,0x06
     1C1 6C88      ORI	R24,0xC8
     1C2 B986      OUT	0x06,R24
     1C3 9508      RET
(0118) }
(0119) 
(0120) //禁用ADC
(0121) void ADC_stop( void )
(0122) {
(0123)     ADCSRA &=~ ( 1 << ADEN ) | ( 1 << ADIE ) | ( 1 << ADSC ) ; //ADC使能位, 中断位清零
_ADC_stop:
     1C4 9837      CBI	0x06,7
     1C5 9508      RET
(0124) }
(0125) 
(0126) //ADC采样端口初始化
(0127) void ADC_port_init( void )
(0128) {
(0129)     ADC0_in;     //定义PAD0为输入,高阻态
_ADC_port_init:
     1C6 B38A      IN	R24,0x1A
     1C7 7F8E      ANDI	R24,0xFE
     1C8 BB8A      OUT	0x1A,R24
     1C9 9AD8      SBI	0x1B,0
(0130) 	ADC1_in;
     1CA B38A      IN	R24,0x1A
     1CB 7F8D      ANDI	R24,0xFD
     1CC BB8A      OUT	0x1A,R24
     1CD 9AD9      SBI	0x1B,1
(0131) 	ADC2_in;
     1CE B38A      IN	R24,0x1A
     1CF 7F8B      ANDI	R24,0xFB
     1D0 BB8A      OUT	0x1A,R24
     1D1 9ADA      SBI	0x1B,2
(0132) 	ADC3_in;
     1D2 B38A      IN	R24,0x1A
     1D3 7F87      ANDI	R24,0xF7
     1D4 BB8A      OUT	0x1A,R24
     1D5 9ADB      SBI	0x1B,3
(0133) 	ADC4_in;
     1D6 B38A      IN	R24,0x1A
     1D7 7E8F      ANDI	R24,0xEF
     1D8 BB8A      OUT	0x1A,R24
     1D9 9ADC      SBI	0x1B,4
     1DA 9508      RET
(0134) }
(0135) 
(0136) //ADC寄存器初始化
(0137) void ADC_REG_init( void )
(0138) {
(0139)     ADCSRA = 0X00;         //ADC控制器清零,不启动ADC转换
_ADC_REG_init:
     1DB 2422      CLR	R2
     1DC B826      OUT	0x06,R2
(0140) 	AD_mux( ad_m );        //选择内部电压,初始时使用ADC0通道做为单通道输入
     1DD 9180 0068 LDS	R24,ad_m
     1DF 6C80      ORI	R24,0xC0
     1E0 B987      OUT	0x07,R24
(0141)     SFIOR = 0X00;          //定义为连续自由转换
     1E1 BE20      OUT	0x30,R2
(0142)     ADCSRA = 0B11101101;   //启动ADC转换1110 1101, 开启ADC中断允许, 32分频(比较合适)
     1E2 EE8D      LDI	R24,0xED
     1E3 B986      OUT	0x06,R24
     1E4 9508      RET
(0143) }
(0144) 
(0145) //ADC采样, 不利用中断完成的采样
(0146) float ADC_convert( void )
(0147) {
(0148)     while( !ADIF );        					 //等待ADC转换完成 ,ADC转换完成后,ADIF = 1
(0149)     adcl = ( uint )ADCL;   					 //定义的为右对齐, 取ADCL的值
_ADC_convert:
     1E5 B024      IN	R2,0x04
     1E6 2433      CLR	R3
     1E7 9230 0063 STS	adcl+1,R3
     1E9 9220 0062 STS	adcl,R2
(0150)     adch = ( uint )ADCH;   					 //取ADCH的值
     1EB B025      IN	R2,0x05
     1EC 2433      CLR	R3
     1ED 9230 0065 STS	adch+1,R3
     1EF 9220 0064 STS	adch,R2
(0151)     adcvalue = adcl + ( adch << 8 );         //取10位ADC的值
     1F1 2C32      MOV	R3,R2
     1F2 2422      CLR	R2
     1F3 9040 0062 LDS	R4,adcl
     1F5 9050 0063 LDS	R5,adcl+1
     1F7 0C42      ADD	R4,R2
     1F8 1C53      ADC	R5,R3
     1F9 9250 0067 STS	adcvalue+1,R5
     1FB 9240 0066 STS	adcvalue,R4
(0152)     return adcvalue * Vref / 1024;           //将ADC的值比较Vref转化为浮点数
     1FD E508      LDI	R16,0x58
     1FE E010      LDI	R17,0
     1FF 940E 094B CALL	lpm32
     201 0118      MOVW	R2,R16
     202 0129      MOVW	R4,R18
     203 9100 0066 LDS	R16,adcvalue
     205 9110 0067 LDS	R17,adcvalue+1
     207 940E 09F3 CALL	uint2fp
     209 933A      ST	R19,-Y
     20A 932A      ST	R18,-Y
     20B 931A      ST	R17,-Y
     20C 930A      ST	R16,-Y
     20D 0181      MOVW	R16,R2
     20E 0192      MOVW	R18,R4
     20F 940E 0B9B CALL	fpmule2
     211 0118      MOVW	R2,R16
     212 0129      MOVW	R4,R18
     213 E504      LDI	R16,0x54
     214 E010      LDI	R17,0
     215 940E 094B CALL	lpm32
     217 933A      ST	R19,-Y
     218 932A      ST	R18,-Y
     219 931A      ST	R17,-Y
     21A 930A      ST	R16,-Y
     21B 0181      MOVW	R16,R2
     21C 0192      MOVW	R18,R4
     21D 940E 0A1C CALL	fpdiv2
     21F 9508      RET
_adc_isr:
     220 920A      ST	R0,-Y
     221 921A      ST	R1,-Y
     222 922A      ST	R2,-Y
     223 923A      ST	R3,-Y
     224 924A      ST	R4,-Y
     225 925A      ST	R5,-Y
     226 926A      ST	R6,-Y
     227 927A      ST	R7,-Y
     228 928A      ST	R8,-Y
     229 929A      ST	R9,-Y
     22A 930A      ST	R16,-Y
     22B 931A      ST	R17,-Y
     22C 932A      ST	R18,-Y
     22D 933A      ST	R19,-Y
     22E 938A      ST	R24,-Y
     22F 939A      ST	R25,-Y
     230 93AA      ST	R26,-Y
     231 93BA      ST	R27,-Y
     232 93EA      ST	R30,-Y
     233 93FA      ST	R31,-Y
     234 B60F      IN	R0,0x3F
     235 920A      ST	R0,-Y
     236 940E 090A CALL	push_xgset300C
     238 9760      SBIW	R28,0x10
(0153) }
(0154) 
(0155) //ADC值转换完成初始化
(0156) #pragma interrupt_handler adc_isr:iv_ADC
(0157) void adc_isr(void)
(0158) {
(0159)  //conversion complete, read value (int) using...
(0160)  // value=ADCL;            //Read 8 low bits first (important)
(0161)  // value|=(int)ADCH << 8; //read 2 high bits and shift into top byte
(0162)  	 ADCSRA &=~ ( 1 << ADIE ) | ( 1 << ADIF );       //禁止转换中断
     239 9833      CBI	0x06,3
(0163) 	 
(0164) 	 switch( ad_m )
     23A 9140 0068 LDS	R20,ad_m
     23C 2755      CLR	R21
     23D 3040      CPI	R20,0
     23E 0745      CPC	R20,R21
     23F F089      BEQ	0x0251
     240 3041      CPI	R20,1
     241 E0E0      LDI	R30,0
     242 075E      CPC	R21,R30
     243 F0D1      BEQ	0x025E
     244 3042      CPI	R20,2
     245 E0E0      LDI	R30,0
     246 075E      CPC	R21,R30
     247 F119      BEQ	0x026B
     248 3043      CPI	R20,3
     249 E0E0      LDI	R30,0
     24A 075E      CPC	R21,R30
     24B F161      BEQ	0x0278
     24C 3044      CPI	R20,4
     24D E0E0      LDI	R30,0
     24E 075E      CPC	R21,R30
     24F F1A9      BEQ	0x0285
     250 C07A      RJMP	0x02CB
(0165)  	 {
(0166)   	  	  case 0:
(0167) 	      {
(0168) 			   ad0_tmp = ADC_convert();
     251 DF93      RCALL	_ADC_convert
     252 9310 006A STS	ad0_tmp+1,R17
     254 9300 0069 STS	ad0_tmp,R16
     256 9330 006C STS	ad0_tmp+3,R19
     258 9320 006B STS	ad0_tmp+2,R18
(0169) 			   ad_m = 1;		//转换通道	
     25A E081      LDI	R24,1
     25B 9380 0068 STS	ad_m,R24
(0170) 		  }break;
     25D C06D      RJMP	0x02CB
(0171) 
(0172) 		  case 1:
(0173) 	 	  {
(0174) 			  ad1_tmp = ADC_convert();
     25E DF86      RCALL	_ADC_convert
     25F 9310 006E STS	ad1_tmp+1,R17
     261 9300 006D STS	ad1_tmp,R16
     263 9330 0070 STS	ad1_tmp+3,R19
     265 9320 006F STS	ad1_tmp+2,R18
(0175) 			  ad_m = 2;         //转换通道
     267 E082      LDI	R24,2
     268 9380 0068 STS	ad_m,R24
(0176) 		  }break;
     26A C060      RJMP	0x02CB
(0177) 		
(0178) 		  case 2:
(0179) 	 	  {
(0180) 			  ad2_tmp = ADC_convert();
     26B DF79      RCALL	_ADC_convert
     26C 9310 0072 STS	ad2_tmp+1,R17
     26E 9300 0071 STS	ad2_tmp,R16
     270 9330 0074 STS	ad2_tmp+3,R19
     272 9320 0073 STS	ad2_tmp+2,R18
(0181) 			  ad_m = 3;         //转换通道			  			
     274 E083      LDI	R24,3
     275 9380 0068 STS	ad_m,R24
(0182) 		  }break;
     277 C053      RJMP	0x02CB
(0183) 		  
(0184) 		  case 3:
(0185) 	      {
(0186) 			   ad3_tmp = ADC_convert();
     278 DF6C      RCALL	_ADC_convert
     279 9310 0076 STS	ad3_tmp+1,R17
     27B 9300 0075 STS	ad3_tmp,R16
     27D 9330 0078 STS	ad3_tmp+3,R19
     27F 9320 0077 STS	ad3_tmp+2,R18
(0187) 			   ad_m = 4;		//转换通道	
     281 E084      LDI	R24,4
     282 9380 0068 STS	ad_m,R24
(0188) 		  }break;
     284 C046      RJMP	0x02CB
(0189) 
(0190) 		  case 4:
(0191) 	 	  {
(0192) 			  ad4_tmp = ADC_convert();
     285 DF5F      RCALL	_ADC_convert
     286 9310 007A STS	ad4_tmp+1,R17
     288 9300 0079 STS	ad4_tmp,R16
     28A 9330 007C STS	ad4_tmp+3,R19
     28C 9320 007B STS	ad4_tmp+2,R18
(0193) 			  ad_m = 0;         //转换通道
     28E 2422      CLR	R2
     28F 9220 0068 STS	ad_m,R2
(0194) 			  
(0195) 			  			
(0196) 	          //显示三个AD光度采样的值		
(0197) 			  //LCD_write_datafloat( 2, 1, ad0_tmp, 100, 2);
(0198) 			  //LCD_write_datafloat( 2, 6, ad1_tmp, 100, 2);
(0199) 			  //LCD_write_datafloat( 2, 11, ad2_tmp, 100, 2);
(0200) 			 small_flag = get_5small( ad0_tmp, ad1_tmp, ad2_tmp, ad3_tmp, ad4_tmp );   //获取三点中最亮的一点
     291 0118      MOVW	R2,R16
     292 0129      MOVW	R4,R18
     293 862C      STD	Y+12,R2
     294 863D      STD	Y+13,R3
     295 864E      STD	Y+14,R4
     296 865F      STD	Y+15,R5
     297 9040 0077 LDS	R4,ad3_tmp+2
     299 9050 0078 LDS	R5,ad3_tmp+3
     29B 9020 0075 LDS	R2,ad3_tmp
     29D 9030 0076 LDS	R3,ad3_tmp+1
     29F 8628      STD	Y+8,R2
     2A0 8639      STD	Y+9,R3
     2A1 864A      STD	Y+10,R4
     2A2 865B      STD	Y+11,R5
     2A3 9040 0073 LDS	R4,ad2_tmp+2
     2A5 9050 0074 LDS	R5,ad2_tmp+3
     2A7 9020 0071 LDS	R2,ad2_tmp
     2A9 9030 0072 LDS	R3,ad2_tmp+1
     2AB 822C      STD	Y+4,R2
     2AC 823D      STD	Y+5,R3
     2AD 824E      STD	Y+6,R4
     2AE 825F      STD	Y+7,R5
     2AF 9040 006F LDS	R4,ad1_tmp+2
     2B1 9050 0070 LDS	R5,ad1_tmp+3
     2B3 9020 006D LDS	R2,ad1_tmp
     2B5 9030 006E LDS	R3,ad1_tmp+1
     2B7 8228      STD	Y+0,R2
     2B8 8239      STD	Y+1,R3
     2B9 824A      STD	Y+2,R4
     2BA 825B      STD	Y+3,R5
     2BB 9120 006B LDS	R18,ad0_tmp+2
     2BD 9130 006C LDS	R19,ad0_tmp+3
     2BF 9100 0069 LDS	R16,ad0_tmp
     2C1 9110 006A LDS	R17,ad0_tmp+1
     2C3 DDC9      RCALL	_get_5small
     2C4 2E20      MOV	R2,R16
     2C5 2433      CLR	R3
     2C6 9230 0061 STS	small_flag+1,R3
     2C8 9220 0060 STS	small_flag,R2
(0201)          	 car_xunguang( small_flag );
     2CA DED1      RCALL	_car_xunguang
(0202) 			 	
(0203) 		  }break;
(0204) 		
(0205)      }
(0206) 
(0207) 	 AD_mux( ad_m );                          //重新启动ADC, 重新选择基准电压和输入通道.此算法适用于多通道.
     2CB 9180 0068 LDS	R24,ad_m
     2CD 6C80      ORI	R24,0xC0
     2CE B987      OUT	0x07,R24
(0208) 	 ADCSRA |= ( 1 << ADSC ) | ( 1 << ADIE ); //开中断, 重新启动
     2CF B186      IN	R24,0x06
     2D0 6488      ORI	R24,0x48
     2D1 B986      OUT	0x06,R24
(0209) 	 delay_nms( 1 );                          //一定要这个延时, 否则转换通道会出错
     2D2 E001      LDI	R16,1
     2D3 E010      LDI	R17,0
     2D4 940E 05C4 CALL	_delay_nms
(0210) 	 
(0211) 	 if( ad_m == 0 ) ADC_stop();
     2D6 9020 0068 LDS	R2,ad_m
     2D8 2022      TST	R2
     2D9 F409      BNE	0x02DB
     2DA DEE9      RCALL	_ADC_stop
(0212) 	 delay_nms( 2 );
     2DB E002      LDI	R16,2
     2DC E010      LDI	R17,0
     2DD 940E 05C4 CALL	_delay_nms
     2DF 9660      ADIW	R28,0x10
     2E0 940E 090F CALL	pop_xgset300C
     2E2 9009      LD	R0,Y+
     2E3 BE0F      OUT	0x3F,R0
     2E4 91F9      LD	R31,Y+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -