国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

STM32遙控小車下位機及硬件連接部分(Keil MDK5平臺的C++編程)

mykurisu / 2557人閱讀

摘要:同時,該模塊中包括小車的加減速以及小車的轉向功能。在串口中斷處理程序中,由于我設定的主機指令以一個字節為單位,故串口檢測到一個字節的接收時就立即判斷當前指令對應的動作,指令與小車動作的映射見上位機編寫部分。

簡介

暑假無聊,手頭又有一個閑置的單片機一直放著,就想著做個遙控小車出來,復習一下單片機嵌入式編程。該遙控小車項目參考CSDN博主你就叫我李大帥的文章:STM32智能遙控小車,超詳細-附下載直接可以用,雙電源跑賊快!。自己在原文的基礎上添加了電腦端的控制,然后做了一個安卓定制軟件來控制小車。
注:

  1. 本文所有代碼均開源,供學習使用。源碼在此:百度云盤鏈接(提取碼:uh66)
  2. 本文是遙控小車的下位機部分,關于PC上位機部分的實現可以參考這里:點擊此處

一、硬件總體介紹

最終實物圖:

硬件方面與李大帥博主的硬件組成差不多:使用兩個L298N電機驅動模塊驅動四個電機,STM32開發板用來控制這兩個電機驅動模塊,并通過JDY-31藍牙透傳模塊與手機或電腦通信。整體采用兩個獨立電源分別為單片機和L298N供電。

1. L298N電機驅動模塊

該模塊用于驅動電機,一個L298N可以驅動兩個電機,有關L298N模塊的講解可以看這個視頻:l298n電機驅動模塊 電機正反轉 電機調速。下圖為L298N與單片機的連接示意圖。

左側L298N:

右側L298N

說明:

  1. 電機驅動模塊L298N在遙控小車兩側分別放置,左邊的L298N控制左邊的兩個電機,右邊的L298N控制右邊的兩個電機。
  2. 單片機的PD12-PD15以PWM的形式輸出控制電機的轉速,PE7-PE14以兩根為一組分別控制四個電機的轉向。

2. JDY-31藍牙模塊

JDY-31這個藍牙模塊屬于透明傳輸模塊,意思就是在使用時可以不用關心藍牙協議的細節,連接好以后可以直接將其當做串口使用。該模塊的RXD與TXD連接至單片機的UART接口,連接示意圖如下圖所示:

說明:

  1. 連接藍牙模塊時,需要將JDY-31上的RX接口與單片機的TX接口相連接(我這款單片機的RX使用P9復用),同時將JDY-31上的TX接口與單片機的RX接口相連接(我這里的RX使用P10復用)。
  2. JDY-31上的STATE接口連接到單片機用于檢測藍牙的連接狀態,當JDY-31與主機有藍牙連接時,STATE會置為高電平,否則為低電平。

3. 電源組成

我使用了兩塊獨立電源,4個干電池構成6.5V電壓給單片機供電,我所購買的單片機上有DCDC降壓芯片,能將6.5V降為3.3V供單片機使用。第二塊獨立電源由一個12V鋰電池提供,為L298N供電。

6.5V電源:

12V電源:

4. 單片機

我采用的單片機型號為STM32F407VET6,這個并不是很重要的,使用其他單片機型號找到對應的固件庫也能完成這樣的功能。

二、單片機程序介紹

下面部分為程序中主要程序的介紹,詳細代碼見百度網盤:[下載地址]。

程序結構目錄如下:

1. main.c文件

代碼片段:

int main(void){ 	//設置外部中斷優先組	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//各部分的初始化	uart_init(9600);	delay_init(168);	LED_Init();			 	Bluetooth_Init();  	SPEEDER_Init();	MTR_GPIOInit();	LED0 = 1;	//主程序	while(1)	{				if(BLUTOOTH_STATE)		{				LED0 = 0;				delay_ms(100);  					LED0 = 1;				delay_ms(100);     		}		else 		{			LED0 = 0;			MTR_CarBrakeAll();		}	}}

代碼說明:

  1. main函數主要執行各個硬件部分的初始化,然后在主程序中判斷JDY-31藍牙與主機的連接的狀態,如果與主機正常連接,則LED0以閃爍的形式不停跳動;如果未連接主機,則LED0保持常亮。

2. bluetooth.c文件

代碼片段:

#include "bluetooth.h"#include "delay.h"  void Bluetooth_Init(void){  GPIO_InitTypeDef  GPIO_InitStructure;  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE時鐘   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //STATE連接的引腳PE0  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//down pull  GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE} 

說明:

  1. 該模塊用于檢測藍牙的連接狀態,故Bluetooth_Init函數只需初始化PE0即可。
  2. 同時在bluetooth.h頭文件中定義了一個變量BLUTOOTH_STATE,用來查詢藍牙是否連接,如下所示:
    #define BLUTOOTH_STATE 	GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_0)	//PE0

3. motor.c文件

代碼片段:

#include "motor.h"//剎車void MTR_CarBrakeAll(void){	MTR1_BRAKE;	MTR2_BRAKE;	MTR3_BRAKE;	MTR4_BRAKE;}//前進void MTR_CarGo(void){	MTR1_ROTA_F;	MTR2_ROTA_F;	MTR3_ROTA_F;	MTR4_ROTA_F;}//后退void MTR_CarBack(void){	MTR1_ROTA_B;	MTR2_ROTA_B;	MTR3_ROTA_B;	MTR4_ROTA_B;}//順時針轉void MTR_CarCW(void){	MTR1_ROTA_F;	MTR2_ROTA_F;	MTR3_ROTA_B;	MTR4_ROTA_B;}//逆時針轉void MTR_CarCCW(void){	MTR1_ROTA_B;	MTR2_ROTA_B;	MTR3_ROTA_F;	MTR4_ROTA_F;}//電機驅動控制初始化void MTR_GPIOInit(void){	GPIO_InitTypeDef GPIO_InitStructure;	RCC_AHB1PeriphClockCmd(MTR1_GPIO_CLK|MTR2_GPIO_CLK|MTR3_GPIO_CLK|MTR4_GPIO_CLK,ENABLE);//時鐘	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//推挽輸出	//電機1	GPIO_InitStructure.GPIO_Pin = MTR1_GPIO_PIN;	GPIO_Init(MTR1_GPIO_PORT, &GPIO_InitStructure);	//電機2	GPIO_InitStructure.GPIO_Pin = MTR2_GPIO_PIN;	GPIO_Init(MTR2_GPIO_PORT, &GPIO_InitStructure);	//電機3	GPIO_InitStructure.GPIO_Pin = MTR3_GPIO_PIN;	GPIO_Init(MTR3_GPIO_PORT, &GPIO_InitStructure);	//電機4	GPIO_InitStructure.GPIO_Pin = MTR4_GPIO_PIN;	GPIO_Init(MTR4_GPIO_PORT, &GPIO_InitStructure);	//小車剎車	MTR_CarBrakeAll();}

說明:

  1. 該模塊主要通過控制PE7-PE14從而實現剎車前進后退以及自轉的功能,例如MTR1_ROTA_F是對第一個電機的兩個引腳分別賦值為1和0,而MTR1_BRAKE則是將這兩個引腳都賦值為0。

4. speeder.c文件

代碼片段:

#include "sys.h"#include "speeder.h"u16 SPEED_LEVEL = SPEED_LEVEL1;u8 CAR_STATE = STRAIGHT_STATE;//GPIO初始化static void SPEEDER_GPIO_Init(void){	GPIO_InitTypeDef GPIO_InitStructure;	RCC_AHB1PeriphClockCmd(SPEEDER_GPIO_CLK,ENABLE);//時鐘	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//推挽輸出	//初始化GPIO 將復用的引腳與對應的定時器綁定在一起。	GPIO_InitStructure.GPIO_Pin = SPEEDER_GPIO_PIN;	GPIO_Init(SPEEDER_GPIO_PORT, &GPIO_InitStructure);	GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource12,GPIO_AF_TIM4);	GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource13,GPIO_AF_TIM4);	GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource14,GPIO_AF_TIM4);	GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource15,GPIO_AF_TIM4);}//定時器初始化static void SPEEDER_TIM_Init(void){	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;	TIM_OCInitTypeDef  TIM_OCInitStructure;	RCC_APB1PeriphClockCmd(GENERAL_TIM_CLK,ENABLE);	/*--------------------TIME BASE 結構體初始化-------------------------*/	TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;	//自動重裝載的值	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);	/*--------------------輸出比較結構體初始化-------------------*/		TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	// 配置為PWM2模式   計數器值大于occr時輸出有效信號	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	// 輸出使能	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	// 輸出通道電平極性配置	   有效信號為高電平	TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;									//比較的值:0	TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);	// 輸出比較通道 1	TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);	TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;	TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);	// 輸出比較通道 2	TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);	TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;	TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure);	// 輸出比較通道 3	TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);	TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;	TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure);	// 輸出比較通道 4	TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);		TIM_ARRPreloadConfig(GENERAL_TIM,ENABLE);	TIM_Cmd(GENERAL_TIM, ENABLE);	// 使能定時器}//整體的使能void SPEEDER_Init(void){	SPEEDER_GPIO_Init();	SPEEDER_TIM_Init();	CAR_STATE = STRAIGHT_STATE;}//向右轉void SET_RIGHT_TURN(void){	CAR_STATE = RIGHT_STATE;	TIM_SetCompare1(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare2(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare3(GENERAL_TIM,0);	TIM_SetCompare4(GENERAL_TIM,0);}//向左轉void SET_LEFT_TURN(void){	CAR_STATE = LEFT_STATE;	TIM_SetCompare1(GENERAL_TIM,0);	TIM_SetCompare2(GENERAL_TIM,0);	TIM_SetCompare3(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare4(GENERAL_TIM,SPEED_LEVEL);}//變直道void RESET_DIRECTION(void){	CAR_STATE = STRAIGHT_STATE;	TIM_SetCompare1(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare2(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare3(GENERAL_TIM,SPEED_LEVEL);	TIM_SetCompare4(GENERAL_TIM,SPEED_LEVEL);}//根據當前的小車狀態將當前的速度等級賦值到對應的定時器中。static void RESET_SPEED_LEVEL(void){	switch(CAR_STATE){		case STRAIGHT_STATE:			RESET_DIRECTION();			break;		case LEFT_STATE:			SET_LEFT_TURN();			break;		case RIGHT_STATE:			SET_RIGHT_TURN();			break;	}}//變速:加速void SPEED_UP(void){	switch(SPEED_LEVEL){		case SPEED_LEVEL0:			SPEED_LEVEL = SPEED_LEVEL1;			break;		case SPEED_LEVEL1:			SPEED_LEVEL = SPEED_LEVEL2;			break;		case SPEED_LEVEL2:			SPEED_LEVEL = SPEED_LEVEL3;			break;		case SPEED_LEVEL3:			SPEED_LEVEL = SPEED_LEVEL3;			break;	}	RESET_SPEED_LEVEL();}//變速:減速void SPEED_DOWN(void){	switch(SPEED_LEVEL){		case SPEED_LEVEL0:			SPEED_LEVEL = SPEED_LEVEL0;			break;		case SPEED_LEVEL1:			SPEED_LEVEL = SPEED_LEVEL0;			break;		case SPEED_LEVEL2:			SPEED_LEVEL = SPEED_LEVEL1;			break;		case SPEED_LEVEL3:			SPEED_LEVEL = SPEED_LEVEL2;			break;	}	RESET_SPEED_LEVEL();}

說明:

  1. 該模塊主要對PD12-PD15實現PWM輸出,從而達到控制小車速度的功能。同時,該模塊中包括小車的加減速以及小車的轉向功能。
  2. 在加速函數(減速函數)中,先用switch語句判斷小車當前的速度狀態,之后將SPEED_LEVEL更改為對應的更大(更小)的速度檔位,然后使用RESET_SPEED_LEVEL()函數將更改后的速度檔位值賦值到對應的定時器比較值中。

5. uart.c文件

代碼部分:

void USART1_IRQHandler(void)                	//串口1中斷服務程序{	uint8_t CMD = 0;//接收的命令	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){		USART_ClearFlag(USART1,USART_FLAG_RXNE);		USART_ClearITPendingBit(USART1,USART_IT_RXNE);		CMD = USART_ReceiveData(USART1);//讀取一個字節		switch(CMD){			case 0x00:				RESET_DIRECTION();				MTR_CarGo();				printf("forward/r/n");				break;			case 0x01:				RESET_DIRECTION();				MTR_CarBack();				printf("back/r/n");				break;			case 0x02:				SET_RIGHT_TURN();				printf("right turn/r/n");				break;			case 0x03:				SET_LEFT_TURN();				printf("left turn/r/n");				break;			case 0x04:				MTR_CarCW();				printf("right CW/r/n");				break;			case 0x05:				MTR_CarCCW();				printf("left CW/r/n");				break;			case 0x06://==================加速				SPEED_UP();				printf("speed up/r/n");				break;			case 0x07://===================減速				SPEED_DOWN();				printf("speed down/r/n");				break;			case 0x0a:				RESET_DIRECTION();				printf("reset straight/r/n");				break;			case 0xff:				MTR_CarBrakeAll();				printf("stop/r/n");				break;			case 0x1f:	//================ 測試連接				printf("connect successfully");				break;		}	}} 

說明:

  1. 在該文件中主要包含uart串口模塊的初始化部分以及串口的中斷處理程序編寫部分。
  2. 在串口初始化部分中,為了方便,我使用了商家提供的ucos初始化代碼,具體可見源代碼,本人沒能將其搞清楚。
  3. 在串口中斷處理程序中,由于我設定的主機指令以一個字節為單位,故串口檢測到一個字節的接收時就立即判斷當前指令對應的動作,指令與小車動作的映射見上位機編寫部分。

三、總結

  1. 本文代碼可以移植到其他單片機上,源代碼在百度云盤中自行領取:點擊此處 (提取碼:uh66)
  2. 本文是遙控小車的下位機部分,關于PC上位機部分的實現可以參考這里:點擊此處
  3. 文中解釋如有問題可評論留言,我會不定時查看

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/119768.html

相關文章

  • 基于STM32Cube MX開發TencentOS-Tiny軟件包

    摘要:基于開發的軟件包導師汪禮超學員崔林威摘要騰訊物聯網操作系統是騰訊面向物聯網領域開發的實時操作系統,具有低功耗,低資源占用,模塊化,可裁剪等特性。圖中斷函數處理進行生成工程配置,按如下界面進行配置,最后點擊,并點擊。 ...

    shiyang6017 評論0 收藏0
  • 三年探索:一條自控、電信/科類學生技術成長路線

    摘要:所以我必須基于自己現在的情況走出一條適合自己情況的成長路線。下位機上位機的思想下位機上位機這就是我自己探索出來的技術成長路線。對和嵌入式的朋友感興趣的朋友可以試一下我這條學習路線 ...

    Miracle 評論0 收藏0
  • 48小時開發實踐:如何開發一款可實時視頻智能小車

    摘要:本文的三位作者正陽海洋阿力,是來自不同公司的工程師,將與智能小車結合,開發了一款可實時視頻遠程看房的創新性項目。用戶可以通過上位機或網頁前端控制小車前后左右移動或控制云臺調整攝像頭方向。 本文的三位作者正陽、海洋、阿力,是來自不同公司的工程師,將 Agora SDK 與智能小車結合,開發了一款可實時視頻遠程看房的創新性項目。本文將從方案設計到具體實現,詳實分享他們的開發經驗。三人也憑借...

    VPointer 評論0 收藏0
  • 48小時開發實踐:如何開發一款可實時視頻智能小車

    摘要:本文的三位作者正陽海洋阿力,是來自不同公司的工程師,將與智能小車結合,開發了一款可實時視頻遠程看房的創新性項目。用戶可以通過上位機或網頁前端控制小車前后左右移動或控制云臺調整攝像頭方向。 本文的三位作者正陽、海洋、阿力,是來自不同公司的工程師,將 Agora SDK 與智能小車結合,開發了一款可實時視頻遠程看房的創新性項目。本文將從方案設計到具體實現,詳實分享他們的開發經驗。三人也憑借...

    mumumu 評論0 收藏0

發表評論

0條評論

mykurisu

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<