日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32智能遥控小车,超详细-附下载直接可以用,双电源跑贼快!

發布時間:2023/12/29 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32智能遥控小车,超详细-附下载直接可以用,双电源跑贼快! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

  • 小車的動力部分由4個帶減速箱的電機,和兩個L298N電機驅動模塊組成。
  • 通過STM32核心板控制電機驅動模塊,JDY-31藍牙模塊與手機通訊。
  • 總共三塊電池,一塊專門給單片機供電,另外兩塊串聯在一起同時給電機驅動模塊供電(為什么選擇分別供電后面的電源硬件部分有說)。
  • 源碼下載,提取碼:nxo3

硬件

  • 硬件的基本介紹
    • 電機的位置很重要,因為電機驅動模塊一個可以分別控制兩個電機,而且程序里面也是分別控制單個電機的動作。
    • 如果電機的和自己想要的運動方向不一樣的話,交換一下接線端的兩個線就好了。程序里面小車前進默認是電機1、2CW(順時針),電機3、4CCW(逆時針)。
  • L298N電機驅動模塊
    電機驅動模塊這里不細講,網上有很多資料,很簡單的。
    下面這個是右邊的驅動板,控制電機1、2。

    下面是左邊的驅動板,控制電機3、4。
    • 兩個驅動板是并聯的,供電時應選擇粗一點的導線給驅動板供電,最好就不要使用杜邦線,如果使用杜邦線有可能會電壓不夠。
    • 有的時候電機可能要用手轉一下才能動,那是因為電壓太小了,可以串聯幾個電池。我是用一個小米充電寶和4節干電池,電 壓應該在10V左右。
    • 注意不能串聯太多充電寶,因為充電寶上面有過電流保護,電流太大充電寶可能會斷電,甚至有可能會直接弄壞充電寶。
    • 如果是雙電源的話,單片機要和兩個驅動板共地。
    • 電機驅動模塊上面的電機使能端的跳帽要拔掉,因為程序是用PWM來控制使能引腳的通點時長來讓小車轉彎的。
  • 藍牙模塊JDY-31
    我使用的是透傳藍牙模塊,簡單來說就是手機連接后給藍牙發送什么數據,然后藍牙模塊再原封不動的通過串口發給單片機,所以只要懂串口的基本通信就好了。
    • 0V和3.3V是從單片機上取電的,驅動板取電的話有可能會有干擾。
    • PA2、PA3是單片機的串口2引腳。本來我想用串口1通訊的,但是好像串口1只能接受到單片機發出來的數據,不能用手機發送進去給單片機(有可能是因為串口1的時鐘頻率太高),而且串口1正好留出來下載程序,所以就選擇了串口2。
    • 藍牙模塊的默認波特率是9600,為了方便我也將串口的波特率也初始化成了9600。
    • 藍牙模塊的STATE引腳是藍牙的連接狀態引腳,連接成功會變成高電平。該引腳我用來給小車做緊急剎車,當藍牙沒有連接或是斷開小車會自動剎車,以免藍牙突然斷開時小車失控的運動。
  • 電源
    小車采用雙電源供電
    • 這里我選擇用兩個電源分別給單片機和驅動板供電的原因
      電機啟動會有很大的啟動電流會在一瞬間將電流全部拉走,使得單片機斷電,如果藍牙模塊也是從單片機上取點也會斷電。
      直接電機的電刷會產生火花對通訊有干擾,有些質量好的電機可能沒有(不太確定是不是這個原因,但同電源時通訊確實有干擾,藍牙會接收一些奇怪的數據)。
    • 驅動板的兩塊電源串聯連接,然后連接到驅動板的電源接線端。

    程序

    程序只要按照上面的連接都是可以直接使用,如果硬件有改動我也有定義宏可以直接做更改。
    代碼里面的注釋比較詳細,這里只是將重要的代碼放上來,稍作講解,最好是直接下載來看。
    下載地址,提取碼:qsmu

    • 目錄結構
  • main.c
  • #include "stm32f10x.h" // Device header #include "MTR_GPIO.h" #include "USART.h" #include "LED.h" #include "blueTooth.h" #include "PWM_GeneralTim.h"int main(void){USART_Config();//串口MTR_GPIOInit();//電機引腳GENERAL_TIM_Init();//定時器PWM初始化,用于小車轉向blueToothInit();//藍牙初始化LEDInit();printf("-----指令-----\n\0x01:小車后退\n\0x02:小車向左\n\0x03:小車向右\n\0x04:小車前進\n\0x05:小車剎車\n\0x06:電機停止\n\0x07:小車逆時針\n\0x08:小車轉向停止\n\0x09:小車順時針\n");while(1){//如果藍牙斷開,小車會一直在剎車狀態if(BLUE_TOOTH_STATE != Bit_SET){MTR_CarBrakeAll();}} }
    • 主要是各功能的初始化。
    • 藍牙狀態的判斷。
  • stm32f10x_it.c
  • void DEBUG_USART_IRQHandler(void){uint8_t CMD = 0;//接收的命令if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET){LED1_ON;CMD = USART_ReceiveData(DEBUG_USARTx);//讀取一個switch(CMD){case 0x06://電機停止MTR_CarBrakeAll();printf("0x06");break;case 0x08://小車轉向停止PWM_CarMaxGo();printf("0x08");break;case 0x05://小車剎車MTR_CarBrakeAll();printf("0x05");break;case 0x02://小車向左PWM_CarLeft();printf("0x02");break;case 0x03://小車向右PWM_CarRight();printf("0x03");break;case 0x04://小車前進MTR_CarGo();printf("0x04");break;case 0x01://小車后退MTR_CarBackGo();printf("0x01");break;case 0x07://小車逆時針MTR_CarCCW();printf("0x07");break;case 0x09://小車順時針MTR_CarCW();printf("0x09");break;}LED1_OFF;//讓LED閃爍來表示數據的接收}USART_ClearFlag(DEBUG_USARTx,USART_FLAG_RXNE); }
    • 串口通過接收十六進制的指令來控制驅動板。
    • 接收到特定的指令后,單片機會將小車執行的指令再發送回給藍牙。
  • MTR_GPIO.c
  • #include "MTR_GPIO.h"//剎車 void MTR_CarBrakeAll(void){MTR1_BRAKE;MTR2_BRAKE;MTR3_BRAKE;MTR4_BRAKE; }//前進 void MTR_CarGo(void){MTR1_CW;MTR2_CW;MTR3_CCW;MTR4_CCW; }//后退 void MTR_CarBackGo(void){MTR1_CCW;MTR2_CCW;MTR3_CW;MTR4_CW; }//順時針 void MTR_CarCW(void){MTR1_CCW;MTR2_CCW;MTR3_CCW;MTR4_CCW; }//逆時針 void MTR_CarCCW(void){MTR1_CW;MTR2_CW;MTR3_CW;MTR4_CW; }void MTR_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(MTR1_GPIO_CLK|MTR2_GPIO_CLK|MTR3_GPIO_CLK|MTR4_GPIO_CLK,ENABLE);//時鐘GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出//電機1GPIO_InitStructure.GPIO_Pin = MTR1_GPIO_PIN;GPIO_Init(MTR1_GPIO_PORT, &GPIO_InitStructure);//電機2GPIO_InitStructure.GPIO_Pin = MTR2_GPIO_PIN;GPIO_Init(MTR2_GPIO_PORT, &GPIO_InitStructure);//電機3GPIO_InitStructure.GPIO_Pin = MTR3_GPIO_PIN;GPIO_Init(MTR3_GPIO_PORT, &GPIO_InitStructure);//電機4GPIO_InitStructure.GPIO_Pin = MTR4_GPIO_PIN;GPIO_Init(MTR4_GPIO_PORT, &GPIO_InitStructure);//小車剎車MTR_CarBrakeAll(); }

    注意:因為單片機是控制驅動板從而間接的控制電機,為了簡單我直接把控制驅動板的引腳看成是控制電機的。

    • 電機的引腳初始化。
    • 小車前進、后退、原地旋轉和剎車的函數封裝。
  • MTR_GPIO.h
  • #ifndef __MTR_GPIO_H #define __MTR_GPIO_H#include "stm32f10x.h"/*小車四輪驅動電機1:右上電機2:右下電機3:左上電機4:左下 */ #define MTR1_GPIO_PORT GPIOB #define MTR1_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR1_GPIO_PIN GPIO_Pin_6|GPIO_Pin_7 #define MTR1_CW {GPIO_ResetBits(MTR1_GPIO_PORT,GPIO_Pin_6);GPIO_SetBits(MTR1_GPIO_PORT,GPIO_Pin_7);}//順時針 #define MTR1_CCW {GPIO_SetBits(MTR1_GPIO_PORT,GPIO_Pin_6);GPIO_ResetBits(MTR1_GPIO_PORT,GPIO_Pin_7);}//逆時針 #define MTR1_BRAKE GPIO_ResetBits(MTR1_GPIO_PORT,MTR1_GPIO_PIN);#define MTR2_GPIO_PORT GPIOB #define MTR2_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR2_GPIO_PIN GPIO_Pin_8|GPIO_Pin_9 #define MTR2_CW {GPIO_ResetBits(MTR2_GPIO_PORT,GPIO_Pin_8);GPIO_SetBits(MTR2_GPIO_PORT,GPIO_Pin_9);}//順時針 #define MTR2_CCW {GPIO_SetBits(MTR2_GPIO_PORT,GPIO_Pin_8);GPIO_ResetBits(MTR2_GPIO_PORT,GPIO_Pin_9);}//逆時針 #define MTR2_BRAKE GPIO_ResetBits(MTR2_GPIO_PORT,MTR2_GPIO_PIN);#define MTR3_GPIO_PORT GPIOB #define MTR3_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR3_GPIO_PIN GPIO_Pin_12|GPIO_Pin_13 #define MTR3_CW {GPIO_ResetBits(MTR3_GPIO_PORT,GPIO_Pin_12);GPIO_SetBits(MTR3_GPIO_PORT,GPIO_Pin_13);}//順時針 #define MTR3_CCW {GPIO_SetBits(MTR3_GPIO_PORT,GPIO_Pin_12);GPIO_ResetBits(MTR3_GPIO_PORT,GPIO_Pin_13);}//逆時針 #define MTR3_BRAKE GPIO_ResetBits(MTR3_GPIO_PORT,MTR3_GPIO_PIN);#define MTR4_GPIO_PORT GPIOB #define MTR4_GPIO_CLK RCC_APB2Periph_GPIOB #define MTR4_GPIO_PIN GPIO_Pin_14|GPIO_Pin_15 #define MTR4_CW {GPIO_ResetBits(MTR4_GPIO_PORT,GPIO_Pin_14);GPIO_SetBits(MTR4_GPIO_PORT,GPIO_Pin_15);}//順時針 #define MTR4_CCW {GPIO_SetBits(MTR4_GPIO_PORT,GPIO_Pin_14);GPIO_ResetBits(MTR4_GPIO_PORT,GPIO_Pin_15);}//逆時針 #define MTR4_BRAKE GPIO_ResetBits(MTR4_GPIO_PORT,MTR4_GPIO_PIN);void MTR_CarBrakeAll(void); //小車剎車 void MTR_CarGo(void); //小車前進 void MTR_CarBackGo(void); //小車后退 void MTR_CarCW(void); //小車順時針轉 void MTR_CarCCW(void); //小車逆時針轉 void MTR_GPIOInit(void);#endif
    • 電機引腳的頭文件
  • PWM_GeneralTim.c
  • #include "PWM_GeneralTim.h" static void GENERAL_TIM_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;// 輸出比較通道1 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);// 輸出比較通道2 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM_CH2_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH2_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure);// 輸出比較通道3 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM_CH3_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH3_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM_CH3_PORT, &GPIO_InitStructure);// 輸出比較通道4 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM_CH4_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH4_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure); }///* // * 注意:TIM_TimeBaseInitTypeDef結構體里面有5個成員,TIM6和TIM7的寄存器里面只有 // * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的時候只需初始化這兩個成員即可, // * 另外三個成員是通用定時器和高級定時器才有. // *----------------------------------------------------------------------------- // *typedef struct // *{ TIM_Prescaler 都有 // * TIM_CounterMode TIMx,x[6,7]沒有,其他都有 // * TIM_Period 都有 // * TIM_ClockDivision TIMx,x[6,7]沒有,其他都有 // * TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有 // *}TIM_TimeBaseInitTypeDef; // *----------------------------------------------------------------------------- // *//* ---------------- PWM信號 周期和占空比的計算--------------- */ // ARR :自動重裝載寄存器的值 // CLK_cnt:計數器的時鐘,等于 Fck_int / (psc+1) = 72M/(psc+1) // PWM 信號的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M // 占空比P=CCR/(ARR+1)static void GENERAL_TIM_Mode_Config(void) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;// 開啟定時器時鐘,即內部時鐘CK_INT=72MGENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE);/*--------------------時基結構體初始化-------------------------*/// 配置周期// 自動重裝載寄存器的值,累計TIM_Period+1個頻率后產生一個更新或者中斷TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period; // 驅動CNT計數器的時鐘 = Fck_int/(psc+1)TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler; // 時鐘分頻因子 ,配置死區時間時需要用到TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 計數器計數模式,設置為向上計數TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重復計數器的值,沒用到不用管TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // 初始化定時器TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);/*--------------------輸出比較結構體初始化-------------------*/ // 配置為PWM模式TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;// 輸出使能TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;// 輸出通道電平極性配置 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;// 輸出比較通道 1TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);// 輸出比較通道 2TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);// 輸出比較通道 3TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure);TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);// 輸出比較通道 4TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure);TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);// 使能計數器TIM_Cmd(GENERAL_TIM, ENABLE); }void GENERAL_TIM_Init(void) {GENERAL_TIM_GPIO_Config();GENERAL_TIM_Mode_Config(); }//小車左轉 void PWM_CarLeft(void){TIM_SetCompare1(GENERAL_TIM,0);TIM_SetCompare2(GENERAL_TIM,0);TIM_SetCompare3(GENERAL_TIM,4000);TIM_SetCompare4(GENERAL_TIM,4000); }//小車右轉 void PWM_CarRight(void){TIM_SetCompare1(GENERAL_TIM,4000);TIM_SetCompare2(GENERAL_TIM,4000);TIM_SetCompare3(GENERAL_TIM,0);TIM_SetCompare4(GENERAL_TIM,0); }//小車最大速度 void PWM_CarMaxGo(void){TIM_SetCompare1(GENERAL_TIM,0);TIM_SetCompare2(GENERAL_TIM,0);TIM_SetCompare3(GENERAL_TIM,0);TIM_SetCompare4(GENERAL_TIM,0); }/*********************************************END OF FILE**********************/
    • 小車轉向的原理是跟坦克的一樣,通過降低轉向邊的輪子速度來實現。而控制轉速就要用到PWM波來減少或增多電機的通斷時間(其實是驅動板的電機使能引腳)。
    • 轉向函數的封裝

    PS:完整的程序太多了,最好下載下來慢慢看。

    藍牙遙控器

    做到這里就剩只藍牙遙控器的配置了,軟件呢隨便哪個都行,只要能收發數據就行。
    不過我推薦用我這個,因為長得好看。
    下載地址,提取碼:kvar。此軟件為安卓,ios沒有

  • 查看指令
    單片機復位的時候會通過藍牙發送這些數據,用手機連上藍牙然后復位單片機就可以看到了。
  • printf("-----指令-----\n
    0x01:小車后退\n
    0x02:小車向左\n
    0x03:小車向右\n
    0x04:小車前進\n
    0x05:小車剎車\n
    0x06:電機停止\n
    0x07:小車逆時針\n
    0x08:小車轉向停止\n
    0x09:小車順時針\n");

    • 單片機就是通過這些十六進制的數據來控制小車的運動,只要將遙控器上的按鍵對應這些數據就行了。
  • 按鍵說明
  • 按鍵配置
    按鍵配置簡單,只要根據指令來配置就好了,我就舉幾個例子。
    • 前進
    • 左轉
    • 剎車
    • 原地順時針 接下來可以開車上路了
      祝你好運!!!

    總結

    以上是生活随笔為你收集整理的STM32智能遥控小车,超详细-附下载直接可以用,双电源跑贼快!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。