单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:18817|回复:10

DIY一辆智能电磁循迹小车(提供原理图和PCB STM32程序)

 [复制链接]
ID:163153发表于 2019-12-1 21:08|显示全部楼层
近期为了迎接校赛,折腾了很久搞了一辆电磁循迹小车,现在决定将小车的资料开源。楼主目前还是小白,大佬勿喷,欢迎大家参考和下载。
59BDE612A05D376C54131C66CF55B42C.jpg


小车采用三轮车结构,前驱,驱动部分为2个步进电机,驱动模块是A4988,电源采用2节3000mAH的松下18650锂电池,续航开源达到2-3小时。A4988模块供电电压为12V,所以板载集成了一个XL6009升压电路,电压升至12V,电源部分还有2个低压LDO,提供5V和3.3V电源,分别共给电磁循迹模块和单片机等等。XL6009升压电路有点小毛病,建议大家修改一下。
862CC9F20BEFE594FD0B27B0A0BC6771.jpg




57C200C46D3C745CFFF759A56C4D63CC.jpg




IMG_20191105_165128.jpg


底盘是咸鱼收的二手平衡小车之家底盘,然后自己找了2个42步进电机。
3.jpg


原理图和PCB大家可以参考参考,板载有集成2片TP4056X充电芯片,这样可以方便充电,不至于每次都要取出来用专门的充电器充电。至于为什么要用2片TP4056X并联,是因为电池容量较大,单片TP4056X充电电流只有1A,充满需要6小时,实在是太久了。
D26C1PT575EF(}15{6((DTT.png




%C@A_TX[M2RHG~JGZ{JHKRO.png


前期时间比较赶,而且是抱着划水的态度,程序比较Low,仅供参考。

单片机源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "oled.h"
  6. #include "pwm.h"
  7. #include "key.h"
  8. #include "adc.h"
  9. #include "timer.h"
  10. #include "flash.h"

  11.       

  12. #define FLASH_START_ADDR  0x0801f000       //写入的起始地址

  13. u8 t=0,flag=0,valu;
  14. u16 pwm=15000,adc_1,adc_2,adc_3,adc_4,adc_5,adc_6;
  15. void ADC_display();       //ADC采集界面
  16. void PWM_speed();               //PWM参数
  17. void ADC_collection();           //ADC采集
  18. void MOTOR_different();       //步进电机差速      
  19. void way();             //寻迹
  20. int main(void)
  21. {      

  22.        delay_init();         //延时初始化
  23.        uart_init(9600);             //串口初始化为9600
  24.        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  25.        LED_Init();                       //初始化与LED连接的硬件接口
  26.        KEY_Init();
  27.        Adc_Init();                       //ADC初始化
  28.        OLED_Init();                 //初始化OLED      
  29. //       pwm = FLASH_R(FLASH_START_ADDR);//从指定页的地址读FLASH
  30.       
  31.    TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms  
  32.       
  33. //       TIM4_PWM_Init(pwm,0);//不分频。PWM频率=72000/(899+1)=80Khz
  34. //       TIM_SetCompare3(TIM4,pwm/2);        
  35. //      
  36. //       TIM5_PWM_Init(pwm,0);//不分频。PWM频率=72000/(899+1)=80Khz
  37. //       TIM_SetCompare2(TIM5,pwm/2);      
  38.       
  39.        DIR1=0;
  40.        ENA1=0;         //左轮
  41.        ENA2=0;
  42.        DIR2=1;   //右轮
  43.       
  44.       
  45.       
  46.       
  47.        OLED_Show_Font_16x16(0,00,8);
  48.        OLED_Show_Font_16x16(0+16,00,9);
  49.        OLED_Show_Font_16x16(0,16,10);
  50.        OLED_Show_Font_16x16(0+16,16,11);
  51.        OLED_Show_Font_16x16(0+32,16,12);  
  52.        OLED_Show_Font_16x16(0+48,16,13);      
  53.        OLED_ShowString(0+64,16,"......",16);  //系统初始化界面
  54.        OLED_Refresh_Gram();     //更新显示到OLED
  55.        delay_ms(500);
  56.        for(valu=0;valu<128;valu++)                       //加载系统读条
  57.        {
  58.            valu++;
  59.            OLED_Fill(0,48,valu,64,1);  
  60.            delay_ms(10);
  61.        }
  62.       

  63.            while(1)
  64.            {
  65.                  way();           //寻迹
  66.                 
  67.            }

  68. }

  69. void ADC_display()
  70. {
  71.       
  72.        if(flag==0)
  73.        {
  74.            OLED_Clear();     //清屏
  75.            OLED_ShowString(5,0," ADC",24);  
  76.            OLED_Show_Font_24x24(0+58,00,7);  
  77.            OLED_Show_Font_24x24(0+80,00,8);           //显示ADC采集 字样
  78.            OLED_ShowString(0,24,"CH1:     CH2:",12);  
  79.            OLED_ShowString(0,38,"CH3:     CH4:",12);  
  80.            OLED_ShowString(0,52,"CH5:     CH6:",12);  
  81.            OLED_Refresh_Gram();     //更新显示到OLED      
  82.            flag=1;     //标志位置1
  83.        }
  84.       
  85.       
  86. //       while(1)
  87. //       {
  88.           
  89.            OLED_ShowNum(28,24, adc_1,4,12);   //ADC值
  90.            OLED_ShowNum(100,24,adc_2,4,12);   //ADC值
  91.            OLED_ShowNum(28,38, adc_3,4,12);   //ADC值
  92.            OLED_ShowNum(100,38,adc_4,4,12);   //ADC值
  93.            OLED_ShowNum(28,52, adc_5,4,12);   //ADC值
  94.            OLED_ShowNum(100,52,adc_6,4,12);   //ADC值
  95.          OLED_Refresh_Gram();     //更新显示到OLED
  96.            LED0=!LED0;
  97.           
  98.            t=KEY_Scan(0);
  99. //         if(t==KEY2_PRES)
  100. //           PWM_speed();
  101. //       }
  102.       
  103. }

  104. void PWM_speed()
  105. {
  106.        u16 a,r,p;
  107.       
  108.        OLED_Clear();       //清屏
  109.        OLED_ShowString(5,0," PWM",24);      
  110.        OLED_Show_Font_24x24(0+56,00,9);                
  111.        OLED_Show_Font_24x24(0+80,00,10);                 //显示PWM参数 字样
  112.        OLED_ShowString(0,24, "PWM CCRx:",16);  
  113.        OLED_ShowString(0,40,"Pulse:     Hz",12);  
  114.        OLED_ShowString(0,52,"Speed:     r/min",12);  
  115.       
  116.        OLED_ShowNum(70,24,pwm,5,16);  //pwm CCRx值   恢复上一次退出前的值
  117.        OLED_ShowNum(40,40,p,5,12);   //脉冲速度
  118.        OLED_ShowNum(45,52,r,3,12);   //电机转速
  119.        OLED_Refresh_Gram();     //更新显示到OLED            
  120.   

  121. //       while(1)
  122. //       {      

  123.   
  124.        t=KEY_Scan(0);           //得到键值
  125.            switch(t)
  126.            {                      
  127.                  case KEY0_PRES:
  128.                        pwm=pwm-500;   //6000-50000
  129.                            if(pwm<=6000)
  130.                                  pwm=6000;
  131.                            p=(72000000/pwm);
  132.                            r=((p*60)/3200);
  133.                        TIM4_PWM_Init(pwm,0);
  134.                    TIM_SetCompare3(TIM4,pwm/2);
  135.                        TIM5_PWM_Init(pwm,0);
  136.                    TIM_SetCompare2(TIM5,pwm/2);
  137.                        OLED_ShowNum(70,24,pwm,5,16);  //pwm CCRx值
  138.                    OLED_ShowNum(40,40,p,5,12);   //脉冲速度
  139.                    OLED_ShowNum(45,52,r,3,12);   //电机转速
  140.                    OLED_Refresh_Gram();  //更新显示到OLED
  141.                  //       FLASH_W(FLASH_START_ADDR,pwm); //从指定页的地址写入FLASH
  142.                        break;
  143.                  case KEY1_PRES:
  144.                        pwm=pwm+500;
  145.                            if(pwm>=50000)
  146.                                  pwm=50000;
  147.                            p=(72000000/pwm);
  148.                            r=((p*60)/3200);
  149.                        TIM4_PWM_Init(pwm,0);
  150.                    TIM_SetCompare3(TIM4,pwm/2);
  151.                        TIM5_PWM_Init(pwm,0);
  152.                    TIM_SetCompare2(TIM5,pwm/2);
  153.                        OLED_ShowNum(70,24,pwm,5,16);
  154.                    OLED_ShowNum(40,40,p,5,12);
  155.                    OLED_ShowNum(45,52,r,3,12);
  156.                        OLED_Refresh_Gram();//更新显示到OLED
  157.                  //       FLASH_W(FLASH_START_ADDR,pwm); //从指定页的地址写入FLASH
  158.                        break;
  159.                  case KEY2_PRES:                      
  160.                        ADC_display();
  161.                        break;
  162.                  default:
  163.                        delay_ms(10);      
  164. //           }
  165. //           OLED_ShowChar(36,52,t,12,1);//显示ASCII字符      
  166. //           OLED_ShowNum(94,52,t,3,12);       //显示ASCII字符的码值  
  167. //           OLED_ShowNum(36,52,t,3,12);       //显示ASCII字符的码值  
  168. //           OLED_Refresh_Gram();//更新显示到OLED

  169.        }      
  170. }

  171. void ADC_collection()
  172. {
  173.        adc_1=Get_Adc_Average(ADC_Channel_7,10);  //得到ADC采集值  CH7
  174.        adc_2=Get_Adc_Average(ADC_Channel_6,10);  //得到ADC采集值  CH6
  175.        adc_3=Get_Adc_Average(ADC_Channel_5,10);  //得到ADC采集值  CH5
  176.        adc_4=Get_Adc_Average(ADC_Channel_4,10);  //得到ADC采集值  CH4
  177.        adc_5=Get_Adc_Average(ADC_Channel_3,10);  //得到ADC采集值  CH3
  178.        adc_6=Get_Adc_Average(ADC_Channel_2,10);  //得到ADC采集值  CH2
  179. }

  180. void MOTOR_different()
  181. {
  182.        OLED_Show_Font_16x16(16,00,0);
  183.        OLED_Show_Font_16x16(16+16,00,1);
  184.        OLED_Show_Font_16x16(16+32,00,2);
  185.        OLED_Show_Font_16x16(16+48,00,3);
  186.        OLED_Show_Font_16x16(16+64,00,6);
  187.        OLED_Show_Font_16x16(16+80,00,7);
  188.            while(1)
  189.            {
  190.                 
  191.            }
  192. }

  193. void way()
  194. {      
  195.        PWM_speed();
  196.        while(1)
  197.        {
  198.            ADC_collection();     //ADC信号采集
  199.            ADC_display();
  200.           
  201.           
  202.            if(1500<adc_3&& adc_3<3000&& 1500<adc_4&& adc_4<3000)       //直行
  203.            {
  204.                  if(ENA1==1)
  205.                  {
  206.                        ENA1=0;         //左轮使能开启
  207.                        ENA2=0;         //右轮使能开启
  208.                  }
  209.                        TIM4_PWM_Init(pwm,0);
  210.                        TIM_SetCompare3(TIM4,pwm/2);
  211.                        TIM5_PWM_Init(pwm,0);
  212.                        TIM_SetCompare2(TIM5,pwm/2);
  213.                       
  214.                        OLED_ShowString(116,0," ",24);
  215.                        OLED_ShowString(116,0,"M",24);
  216.                        OLED_Refresh_Gram();//更新显示到OLED
  217.           
  218.            }
  219.           
  220.            if(2500<=adc_4&& adc_3<=2000)     //左转弯
  221.            {
  222.                  if(ENA1==1)
  223.                  {
  224.                        ENA1=0;         //左轮使能开启
  225.                        ENA2=0;         //右轮使能开启
  226.                  }
  227.                        TIM4_PWM_Init(pwm,0);
  228.                        TIM_SetCompare3(TIM4,pwm/2);
  229.                        TIM5_PWM_Init(pwm/2,0);
  230.                        TIM_SetCompare2(TIM5,pwm/4);
  231.                       
  232.                        OLED_ShowString(116,0," ",24);
  233.                        OLED_ShowString(116,0,"L",24);
  234.                        OLED_Refresh_Gram();//更新显示到OLED
  235.           
  236.            }
  237.           
  238.            if(adc_4<2000&& 2500<adc_3)     //右转弯
  239.            {
  240.                  if(ENA1==1)
  241.                  {
  242.                        ENA1=0;         //左轮使能开启
  243.                        ENA2=0;         //右轮使能开启
  244.                  }          
  245.                        TIM4_PWM_Init(pwm/2,0);
  246.                        TIM_SetCompare3(TIM4,pwm/4);
  247.                        TIM5_PWM_Init(pwm,0);
  248.                        TIM_SetCompare2(TIM5,pwm/2);
  249.                       
  250.                        OLED_ShowString(116,0," ",24);
  251.                        OLED_ShowString(116,0,"R",24);
  252.                        OLED_Refresh_Gram();//更新显示到OLED
  253.           
  254.            }
  255.           
  256.            if(adc_3<300&& adc_4<300)         //停止
  257.            {
  258.                  if(ENA1==0)
  259.                  {
  260.           
  261.                        ENA1=1;         //左轮使能关闭
  262.                        ENA2=1;         //右轮使能关闭
  263.                       
  264.                  }
  265.                 
  266.                  OLED_ShowString(116,0," ",24);
  267.                  OLED_ShowString(116,0,"S",24);
  268.                  OLED_Refresh_Gram();//更新显示到OLED
  269.                 
  270.                 
  271.            }
  272.           
  273. //           delay_ms(10);
  274.        }
  275.       
  276. }
复制代码

51hei.png

全部资料51hei下载地址:
原理图PCB.rar(18.35 MB, 下载次数: 259)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

ID:526170发表于 2020-5-3 00:14|显示全部楼层
谢谢楼主分享
ID:590242发表于 2020-6-9 21:22|显示全部楼层
请问有电磁循迹模块的bom表吗
ID:780742发表于 2021-3-31 10:09|显示全部楼层
同问,请问有电磁的bom表嘛
ID:880210发表于 2021-4-19 00:28|显示全部楼层
有传感器的原理图吗
ID:582255发表于 2022-10-12 16:05|显示全部楼层
请问那个AD采样是干什么用的
ID:65066发表于 2023-8-22 10:48|显示全部楼层

谢谢楼主分享,下载学习了
ID:1097415发表于 2023-10-28 12:35|显示全部楼层
用的什么仿真软件啊
ID:1084042发表于 2024-4-29 14:57|显示全部楼层
zzhh190807 发表于 2021-4-19 00:28
有传感器的原理图吗

亲亲 有原理图了吗
ID:1084042发表于 2024-4-29 14:58|显示全部楼层
帅同学 发表于 2021-3-31 10:09
同问,请问有电磁的bom表嘛

亲亲 有了吗
ID:1119398发表于 2024-5-6 09:44|显示全部楼层
想知道底盘大小还有电路板的尺寸大小

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网