【单片机项目】制作一辆基于STM32的智能小车——三路循迹模块
2020-04-22 02:52
585 查看
1.引脚定义:
GND接地,VCC供电,X1、X2、X3各自对应一对红外探头
2.实验原理:
红外传感器巡线的基本原理是利用物体的反射性质,当红外线发射到黑色上时会被黑线吸收掉,当红外线发射到不同的颜色的材料上会有不同反射到红外的接手管上,已产生不同大小的光电流,从而影响三路引脚输入电平高低。
3.注意:
- 红外探头发出的红外光是人眼无法看到的。
- 为了避免太阳光对红外传感器产生影响,所以我们需要在室内使用该模块。
- 工作电压: 3.3v~5v
remote.h
#ifndef __REMOTE_H #define __REMOTE_H #define left GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) #define mid GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) #define right GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) void remote_init(void); void run_left(void); void run_right(void); void run_forth(void); void run_back(void); void run_stop(void); #endif
remote.c
#include "remote.h" #include "sys.h" void remote_init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启IO口对应的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3; //PA2 PA3 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //PB0 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB,&GPIO_InitStructure); } void run_forth() { TIM_SetCompare1(TIM4,780); TIM_SetCompare2(TIM4,899); TIM_SetCompare3(TIM4,782); TIM_SetCompare4(TIM4,899); } void run_left() { TIM_SetCompare1(TIM4,860); TIM_SetCompare2(TIM4,899); TIM_SetCompare3(TIM4,760); TIM_SetCompare4(TIM4,899); } void run_right() { TIM_SetCompare1(TIM4,760); TIM_SetCompare2(TIM4,899); TIM_SetCompare3(TIM4,860); TIM_SetCompare4(TIM4,899); } void run_back() { TIM_SetCompare1(TIM4,899); TIM_SetCompare2(TIM4,800); TIM_SetCompare3(TIM4,899); TIM_SetCompare4(TIM4,800); } void run_stop() { TIM_SetCompare1(TIM4,899); TIM_SetCompare2(TIM4,899); TIM_SetCompare3(TIM4,899); TIM_SetCompare4(TIM4,899); }
main.c
#include "sys.h" #include "delay.h" //#include "usart.h" #include "led.h" #include "oled.h" #include "motor.h" #include "timer.h" #include "remote.h" //#include "tick_ulsonic.h" //#include "ultrasonic.h" /*********************************************************************************************** 本来是一个三路巡线模块,但因为模块质量问题,中间识别能力较差,故只使用左右两路,逻辑上也可以实现。 ****************************************************************************************************************/ void pointleft(void); //OLED方向指示 void pointright(void); void pointforth(void); void pointback(void); int main(void) { u8 i=0; u8 val1; u8 val2; SystemInit(); delay_init(); //延时函数初始化 nms<=1864 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 或使用JTAG_Set(0X01); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); LED_Init(); // uart_init(115200); LED_Init(); //初始化与LED连接的硬件接口 OLED_Init(); pwm_init(899,0); // Tim3_Config(); // ulsonic0_config(); // ECHO PA2 TRIG PA3 // ulsonic1_config(); // ECHO PA13 TRIG PA14 remote_init(); delay_ms(1800); delay_ms(1800); delay_ms(1800); run_forth(); while(1) //基于实际操作环境,在纸张内返回引脚口读取0,纸张外读取1。 { val1=left; val2=right; switch(val1+val2) { case 2 : run_back();pointback(); //两边跑离纸面 break; case 1 : if(val1==1) //一边跑离纸面 {run_right();pointright(); } else{ run_left();pointleft(); } break; case 0 : run_forth();pointforth(); //在纸面内 break; default: break; } OLED_ShowNumber(20,20,val1,1,14); OLED_ShowNumber(60,20,val2,1,14); OLED_Refresh_Gram(); i++; if(i==10) { LED=!LED; i=0; } delay_ms(50); } } void pointright() { OLED_Clear(); OLED_ShowString(40,10,"O"); OLED_ShowString(60,20,"O"); OLED_ShowString(80,30,"O"); OLED_ShowString(60,40,"O"); OLED_ShowString(40,50,"O"); OLED_Refresh_Gram(); } void pointleft() { OLED_Clear(); OLED_ShowString(80,10,"O"); OLED_ShowString(60,20,"O"); OLED_ShowString(40,30,"O"); OLED_ShowString(60,40,"O"); OLED_ShowString(80,50,"O"); OLED_Refresh_Gram(); } void pointforth() { OLED_Clear(); OLED_ShowString(60,10,"OO"); OLED_ShowString(50,20,"O O"); OLED_ShowString(40,30,"O O"); OLED_Refresh_Gram(); } void pointback() { OLED_Clear(); OLED_ShowString(60,50,"OO"); OLED_ShowString(50,40,"O O"); OLED_ShowString(40,30,"O O"); OLED_Refresh_Gram(); }
我用屎黄色的草稿纸铺的“跑道"
该次功能实现中,三路引脚都能正常运行,但逻辑判断中只用到了左右两路,因为个人试验没有高精度要求,小车在该环境下已经能非常流畅准确的判断、运行。若使用三路引脚判断,可以实现急转弯等更高级的功能,这里不详细说明。
注:在调试中一直遇到读IO口Byte是,1和0显示不准确和不灵敏等问题,在经历了很长一段时间的不断尝试和思考后,最后从最简单的IO配置开始修改,把下拉输入改成了浮空输入模式,整个问题迎刃而解。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 【单片机项目】制作一辆基于STM32的智能小车——收官总结
- 基于AT89S52单片机的循迹小车开发(一)硬件模块的框架搭建
- 基于STC89C52RC单片机制作的红外循迹小车(4个传感器)
- 基于STM32wifi小车制作(四)
- 基于STM32平台智能养蜂项目简介
- 关于camera:基于S12单片机的循迹小车视觉系统设计与优化
- 基于stm32循迹小车运动实例
- 基于STM32的智能学习空调项目的定时器捕获驱动
- STM32智能小车之 循迹
- 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)
- 基于STM32单片机的智能GSM短信上报GPS定位设计
- 基于STM32wifi小车制作(三)
- 基于STM32wifi小车制作(二)-电源设计
- 基于stm32的手机蓝牙智能小车的设计
- [硬件项目] 1、汽车倒车雷达设计——基于API8108A芯片简易智能语音模块的设计与实现
- 基于Qt的wifi智能小车的制作(一)
- STM32 智能小车 ESP8266 Wi-Fi模块学习记录
- 基于STM32单片机开发光学指纹识别模块(FPM10A)全教程
- 基于STC89c52rc单片机的红外循迹小车
- 基于Arduinuo单片机的循迹小车