中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

萬網(wǎng)個人網(wǎng)站備案查詢新聞投稿

萬網(wǎng)個人網(wǎng)站備案查詢,新聞投稿,蟲部落導(dǎo)航網(wǎng)站怎么做,客源通app下載項(xiàng)目框圖 ST-link接線 實(shí)物圖: 正面: 反面: 相關(guān)內(nèi)容 使用L9110S電機(jī)模塊 電機(jī)驅(qū)動模塊L9110S詳解 | 良許嵌入式 測速模塊 語音模塊SU-03T 網(wǎng)站:智能公元/AI產(chǎn)品零代碼平臺 一、讓小車動起來 新建文件夾智能小車項(xiàng)目 在里面…

項(xiàng)目框圖

ST-link接線

實(shí)物圖:

正面:

?反面:

相關(guān)內(nèi)容

使用L9110S電機(jī)模塊

電機(jī)驅(qū)動模塊L9110S詳解 | 良許嵌入式

測速模塊

?

語音模塊SU-03T

網(wǎng)站:智能公元/AI產(chǎn)品零代碼平臺

一、讓小車動起來

新建文件夾智能小車項(xiàng)目

在里面復(fù)制19-串口打印功能

重命名為01-讓小車動起來

新建文件夾motor,如下圖所示

打開項(xiàng)目

加載文件

先更改引腳

然后分裝函數(shù)

前進(jìn),后退,左轉(zhuǎn),右轉(zhuǎn),停止函數(shù)

PB0、PB1引腳控制的是左輪:

當(dāng)PB0引腳為高電平,PB1引腳為低電平的時候,左輪向前走

當(dāng)PB0引腳為低電平,PB1引腳為高電平的時候,左輪向后走

當(dāng)PB0引腳與PB1引腳電平相同的時候,左輪停止

PB2、PB10引腳控制的是右輪

當(dāng)PB2引腳為高電平,PB10引腳為低電平的時候,右輪向前走

當(dāng)PB2引腳為低電平,PB10引腳為高電平的時候,右輪向后走

當(dāng)PB2引腳與PB10引腳電平相同的時候,右輪停止

#include "motor.h"//初始化電機(jī)函數(shù)
void motor_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打開時鐘__HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOB時鐘//調(diào)用GPIO初始化函數(shù)gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_10;          // 兩個LED對應(yīng)的引腳gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽輸出gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速HAL_GPIO_Init(GPIOB, &gpio_initstruct);motor_stop();
}
//前進(jìn)
void motor_go_forward(void)
{//左輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);//右輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
}
//后退
void motor_go_backward(void)
{//左輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);//右輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
}
//左轉(zhuǎn)
void motor_go_left(void)
{//左輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);//想要一個輪子不動,就讓它兩個引腳都等于reset或者setHAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);//右輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
}
//右轉(zhuǎn)
void motor_go_right(void)
{//左輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);//右輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
}
//停止
void motor_stop(void)
{//左輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //右輪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
}

二、串口控制小車

注意:串口控制小車與藍(lán)牙控制小車類似

想要實(shí)現(xiàn)的效果是:

M1:前進(jìn)

M2:后退

M3:左轉(zhuǎn)

M4:右轉(zhuǎn)

其他M:停止

復(fù)制01-讓小車動起來

重命名為02-串口控制小車

將藍(lán)牙模塊的文件粘貼到改項(xiàng)目中進(jìn)行修改

打開項(xiàng)目文件

加載文件

將藍(lán)牙模塊的串口2代碼粘貼到02項(xiàng)目中

將接收到的串口2的數(shù)據(jù)打印到串口1中

編譯

調(diào)試代碼

燒錄

記得把串口2連接上,用兩個串口助手顯示結(jié)果

串口助手1->連接串口1->用于接收串口2發(fā)送過來的數(shù)據(jù)->波特率是115200

串口助手2->連接串口2->用于發(fā)送數(shù)據(jù)(M1\M2\M3\M4\其他數(shù)據(jù))->波特率是9600

注意:在燒錄完代碼之后,一切準(zhǔn)備就緒,發(fā)現(xiàn)在串口2中發(fā)送輸入,串口1接收不到,這時候不要慌,先把兩個串口助手?jǐn)嚅_,然后再次選擇串口號,連接串口,這時候在輸入數(shù)據(jù),就會有反應(yīng)了。

注意:如果你的電腦中usb接口不足,板子選擇使用面包板接電就會出現(xiàn)一個小錯誤,面包板中只有一個3V3在供電,這個時候,使用杜邦線給32板子接電,就會出現(xiàn)在串口2中輸入M1前進(jìn)之后再輸入M2后退,小車會停下來,串口助手1中會顯示hello word。如下圖所示:

再次輸入M2小車會后退,這是因?yàn)楣╇姴蛔?#xff0c;電壓不穩(wěn),所以想要達(dá)到輸入M1就是前進(jìn),輸入M2就是后退,解決辦法:需要使用USB外接電源供電。

三、藍(lán)牙控制小車

將上述的串口控制小車中的串口2所接的引腳替換成藍(lán)牙模塊

然后手機(jī)連接藍(lán)牙

輸入數(shù)據(jù),小車就會行動

要注意藍(lán)牙所設(shè)置的波特率,不然不能正確接收數(shù)據(jù)

藍(lán)牙當(dāng)初所設(shè)置的波特率是115200,所以要在主函數(shù)中調(diào)用藍(lán)牙初始化函數(shù)時更改波特率

?

四、點(diǎn)動控制小車

????????當(dāng)摁下前進(jìn)按鍵的時候,小車就會瘋狂的向前走,那么現(xiàn)在要實(shí)現(xiàn),當(dāng)摁一下前進(jìn),小車就前進(jìn)一下,實(shí)現(xiàn)點(diǎn)動控制小車。

復(fù)制項(xiàng)目文件02,重命名為,點(diǎn)動控制小車

打開項(xiàng)目

只添加這兩行代碼即可

剩下的在軟件上完成

原理:

在主函數(shù)的while函數(shù)中,有一個停止的函數(shù),小車最開始的狀態(tài)就是停止?fàn)顟B(tài),想讓小車開始移動,就要打斷這個while循環(huán),所以就要用到中斷,所以點(diǎn)動的代碼要在中斷函數(shù)中寫,所以在中斷回調(diào)函數(shù)中,有讓其移動的代碼,將這個代碼延時一下,比如10ms。那么程序在執(zhí)行完移動代碼之后就會執(zhí)行這個延時函數(shù),然后再回到while循環(huán)中執(zhí)行停止小車的函數(shù),所以就實(shí)現(xiàn)了,10ms的點(diǎn)動,而,需要長時間的移動小車,就要在軟件中找補(bǔ)了。

在串口助手中

(把藍(lán)牙摘下去換上串口2,記得串口2的波特率已經(jīng)改為115200了)

串口助手2可以使用數(shù)據(jù)流循環(huán)發(fā)送,設(shè)置好發(fā)送的間隔,就可以實(shí)現(xiàn)長時間的移動。

設(shè)置的時間太長,沒辦法將小車動作連續(xù)起來

時間太短,小車跑的太快

其實(shí)這個整套下來,像是將片段的小車移動整合起來變成一個連續(xù)的小車移動

將小車獨(dú)立出來的接線:

現(xiàn)在小車的串口2連接藍(lán)牙模塊

ST-LINK和串口1可以在燒錄完代碼之后拔掉

32的5V電壓和GND可以連接面包板的正負(fù)極

面包板的電壓計算:四塊1.5V的電壓=1.5*4=6V

五、PWM調(diào)速控制小車

小車接收到不同的電壓值,跑的速度也是不一樣的

電壓越大,速度越快(并不是電壓越大越好,小心燒掉板子)

為了避免小車一開始速度就很快可以使用PWM調(diào)速

小車的電機(jī)與32板子連接的電壓是3.3V,所以小車全速前進(jìn)的時候電壓是3.3V,如果把電壓降低至2V小車的速度就會降下來,1.5V更慢。

復(fù)制01項(xiàng)目,重命名為04-PWM調(diào)速控制小車

復(fù)制呼吸燈實(shí)驗(yàn)中BSP文件中的pwm文件夾

粘貼到04-PWM調(diào)速控制小車的BSP文件中

打開項(xiàng)目,加載文件

記得加載HAL庫中的定時器文件tim.c,tim_er.c

編譯無錯

修改pwm文件

將這個的TIM4修改為TIM2,TIM2的兩個通道在這里用到

因?yàn)門IM4的兩個通道GPIO口可能會占用到

這里就要注意,做項(xiàng)目前要對資源進(jìn)行合理的分配,這很重要

這里需要更改電機(jī)的引腳

想要達(dá)成每個電機(jī)使用不同的通道

這里不用看PB引腳的通道,因?yàn)樽筝営靡粋€通道,右輪用一個通道,所以PB引腳的通道并不重要,不需要關(guān)注。

這里注意,通用定時器


代碼修改如下:

這里注意,原來我pwm_init函數(shù)中的參數(shù)是psc在前,arr在后,然后主函數(shù)中聲明pwm_init();時寫的參數(shù)20-1,72-1,這里傳參的順序錯了,所以在這里pwm文件中調(diào)換了psc和arr的順序。

復(fù)習(xí)CCR是什么?

主函數(shù)代碼如下:

產(chǎn)生的疑問?

????????STM33F103C8T6智能小車項(xiàng)目中使用循跡+PWM調(diào)速小車時,小車電機(jī)實(shí)際接線的引腳是PA0接A-1A、PB1接A-1B、PA1接B-1A、PB10接B-1B和PWM定義的接口引腳是PA0和PA1,但是在小車電機(jī)文件中定義的引腳是PB0接A-1A、PB1接A-1B、PB2 接B-1A、PB10接B-1B,這時候使用pwm調(diào)節(jié)CRR的值可以控制小車車速,但是為什么項(xiàng)目所定義的電機(jī)文件中的引腳和小車實(shí)際接線的引腳不一致的情況下,小車還可以動?

DeepSeek回答

關(guān)于STM32F103C8T6智能小車項(xiàng)目中,電機(jī)實(shí)際接線與代碼中定義的引腳不一致,但小車仍然可以動的原因。我需要仔細(xì)分析這個問題,并給出合理的解釋。

首先,用戶提到實(shí)際接線是PA0接A-1A,PB1接A-1B,PA1接B-1A,PB10接B-1B。而代碼中定義的引腳是PB0接A-1A,PB1接A-1B,PB2接B-1A,PB10接B-1B。但使用PWM調(diào)節(jié)CCR(應(yīng)該是PWM的捕獲/比較寄存器)來控制車速,小車卻能動。這看起來矛盾,因?yàn)橐_定義不一致,按理說電機(jī)可能不會正常工作,或者完全不動。

我需要考慮幾個可能性:

?硬件接線錯誤,但代碼中錯誤地配置了其他引腳?:比如,雖然代碼定義的是PB0,但實(shí)際可能錯誤地配置了PA0,導(dǎo)致兩者巧合地對應(yīng)。這可能是因?yàn)榇a中的初始化部分錯誤地將PB0配置為PA0,或者存在其他配置問題。

?復(fù)用功能或引腳映射?:STM32的某些引腳可能有復(fù)用功能,或者通過重映射功能改變了實(shí)際控制的引腳。例如,定時器的通道可能被映射到不同的引腳,導(dǎo)致代碼中定義的PB0實(shí)際上輸出到了PA0。

?代碼中的引腳配置與實(shí)際不符,但部分引腳正確?:例如,雖然A-1A和B-1A的引腳定義錯誤,但A-1B和B-1B的PB1和PB10正確,這樣可能有一半的電機(jī)驅(qū)動正確,而另一半可能被其他因素(如共地或短路)導(dǎo)致電機(jī)仍能轉(zhuǎn)動,但表現(xiàn)異常。

?PWM信號通過其他方式傳遞?:可能存在飛線或電路板上的短路,導(dǎo)致PWM信號從代碼定義的引腳傳輸?shù)搅藢?shí)際接線的引腳。

接下來,我需要進(jìn)一步分析這些可能性。首先檢查代碼中的GPIO初始化部分,查看是否正確配置了引腳。例如,如果代碼中錯誤地將PB0配置為PWM輸出,但實(shí)際硬件連接到了PA0,但PA0可能被配置為其他功能(如普通GPIO輸出),這時候如果PA0被設(shè)置為高電平,可能電機(jī)一直全速運(yùn)行,而PWM調(diào)節(jié)無效。但用戶提到可以通過調(diào)節(jié)CCR控制車速,這說明PWM可能確實(shí)在起作用。

另一種可能是,雖然代碼中定義的引腳是PB0、PB2,但實(shí)際使用的定時器通道對應(yīng)的引腳是PA0和PA1。例如,定時器2的通道1和2可能默認(rèn)映射到PA0和PA1,而代碼中錯誤地配置了PB0和PB2,但由于沒有重映射,實(shí)際輸出仍然在PA0和PA1。這種情況下,即使代碼中試圖配置PB0和PB2為PWM,但由于這些引腳對應(yīng)的定時器通道不同,可能無法輸出,但用戶的情況卻可以工作,這似乎矛盾。

或者,用戶可能使用了不同的定時器,例如,PA0和PA1屬于定時器2,而PB0、PB1屬于定時器3,但代碼中錯誤地配置了定時器3到PB0,但實(shí)際硬件連接到了定時器2的PA0,這時候如果代碼中錯誤地配置了定時器3,但實(shí)際沒有啟用,而PA0可能被其他代碼(如直接GPIO控制)驅(qū)動,這可能無法解釋PWM調(diào)速的有效性。

可能需要考慮代碼中的具體配置,比如使用的定時器和通道,以及引腳重映射情況。例如,STM32的某些定時器通道可以重映射到其他引腳,如果代碼中啟用了重映射,那么實(shí)際輸出引腳會改變。例如,定時器3的通道1默認(rèn)是PA6,但部分重映射后可能是PB4,完全重映射可能是PC6。如果用戶代碼中配置了重映射,但實(shí)際硬件連接到了默認(rèn)引腳,或者相反,可能導(dǎo)致引腳不一致但信號仍然輸出。

另外,用戶提到調(diào)節(jié)CCR可以控制車速,這說明PWM信號確實(shí)在正確的引腳上輸出。因此,可能的情況是,雖然代碼中定義的引腳名稱和實(shí)際接線不一致,但實(shí)際配置的定時器通道對應(yīng)的物理引腳是正確的。例如,代碼中定義PB0,但實(shí)際配置的是定時器3通道1,而該通道的引腳可能是PB0,但硬件連接到了PA0,這似乎矛盾,除非存在硬件錯誤或飛線。

或者,用戶可能混淆了引腳的定義,例如在代碼中錯誤地命名了引腳,但實(shí)際配置的是正確的引腳。比如,代碼中將電機(jī)A的PWM引腳定義為PB0,但在初始化時實(shí)際配置的是PA0,這可能是代碼中的注釋或變量名錯誤,而實(shí)際代碼正確。

另一個可能性是,電機(jī)驅(qū)動模塊的使能端被固定啟用,例如ENA和ENB被接高電平,此時電機(jī)的方向由IN1和IN2控制,而PWM信號實(shí)際上控制的是速度,但若方向引腳配置正確,即使PWM引腳錯誤地輸出高電平,電機(jī)也會全速運(yùn)轉(zhuǎn)。但用戶提到可以調(diào)節(jié)速度,所以PWM必須有效。

綜合來看,最可能的解釋是代碼中實(shí)際配置的引腳與變量名或注釋中的定義不一致,但初始化部分正確配置了實(shí)際接線的PA0和PA1。例如,雖然在代碼的注釋或變量名中寫的是PB0和PB2,但初始化函數(shù)中正確地設(shè)置了PA0和PA1作為PWM輸出。這可能是一個代碼書寫錯誤,但實(shí)際配置正確,導(dǎo)致電機(jī)正常運(yùn)行。

或者,可能存在引腳復(fù)用的情況,例如PA0和PB0都被配置為同一個定時器的不同通道,但這種情況在STM32中不太可能,除非使用了不同的定時器。

需要進(jìn)一步考慮STM32F103的定時器通道和引腳映射。例如,查看PA0和PB0分別屬于哪個定時器的哪個通道。PA0對應(yīng)定時器2的通道1,而PB0可能屬于定時器3的通道3,或者其他定時器。如果代碼中配置了定時器2的通道1,那么無論變量名如何,實(shí)際輸出會在PA0,而如果變量名錯誤地寫成了PB0,但初始化代碼正確,那么電機(jī)就能正常工作。

因此,問題可能出在代碼中的引腳定義變量名與實(shí)際初始化時使用的引腳不一致,但初始化部分正確配置了實(shí)際引腳。例如:

在代碼中可能有:
#define MOTOR_A_PWM_PIN PB0
#define MOTOR_B_PWM_PIN PB2

但在初始化時,錯誤地配置了PA0和PA1:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 實(shí)際是PA0
或者使用了正確的定時器配置,例如Timer2的通道1和2,對應(yīng)的PA0和PA1,而變量名錯誤地寫成了PB0和PB2。

因此,盡管代碼中的定義和實(shí)際接線不一致,但由于初始化部分正確配置了PA0和PA1,所以PWM信號正確輸出,電機(jī)能夠運(yùn)行,并且通過調(diào)節(jié)CCR(即定時器的捕獲/比較寄存器)改變占空比,從而控制速度。

總結(jié)起來,可能的原因是代碼中引腳定義的變量名或注釋錯誤,但實(shí)際的硬件初始化和定時器配置正確,導(dǎo)致雖然文檔或變量名不一致,但實(shí)際信號輸出正確,因此小車可以正常運(yùn)行。

📅 ?時效性分析?:用戶問題不依賴時效性數(shù)據(jù),但為確保準(zhǔn)確性,當(dāng)前分析基于 ?2025年02月25日? 的技術(shù)背景。

🚗 ?問題核心?

在引腳定義與實(shí)際接線不一致的情況下,小車仍能運(yùn)行的根本原因在于 ?代碼與硬件實(shí)際信號流的匹配性?。以下是關(guān)鍵分析:

🔧 ?原因解析?
1?? ?PWM信號實(shí)際生效的引腳與代碼定義不同?
?可能場景?:
代碼中雖然名義上定義引腳為 PB0 和 PB2,但底層驅(qū)動(如定時器配置)可能錯誤/隱式地指向了 PA0 和 PA1。
?示例?:
c
Copy Code
// 代碼中名義定義引腳為 PB0(錯誤)
#define MOTOR_A_PWM_PIN PB0
// 實(shí)際初始化時誤配置為 PA0(正確)
TIM_OC1Init(TIM2, &pwm_config);? // TIM2_CH1 默認(rèn)映射到 PA0

?結(jié)果?:PWM信號通過 PA0/PA1 輸出,與硬件接線一致,因此可調(diào)速。
2?? ?部分引腳功能重合或短路?
?可能場景?:
若 PB0 與 PA0 在硬件上被短接(如PCB設(shè)計錯誤或飛線),代碼對 PB0 的操作會實(shí)際影響 PA0。
部分電機(jī)驅(qū)動模塊(如L298N)的使能端(ENA/ENB)直接接高電平,此時方向引腳(如A-1A/A-1B)的PWM占空比仍可調(diào)速。
3?? ?代碼未嚴(yán)格綁定引腳定義?
?可能場景?:
電機(jī)驅(qū)動代碼通過 ?定時器通道?(如 TIM2_CH1)控制PWM,而非直接依賴引腳名。
?示例?:
c
Copy Code
// 實(shí)際控制PA0的是TIM2_CH1,無論引腳名如何定義
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);? // PA0輸出PWM

📊 ?驗(yàn)證方法?
?示波器/邏輯分析儀檢測?:
檢查 PA0 和 PB0 的PWM波形,確認(rèn)實(shí)際生效的引腳。
?代碼調(diào)試?:
跟蹤PWM初始化代碼,驗(yàn)證定時器通道與引腳的映射關(guān)系(參考《STM32F103參考手冊》的定時器復(fù)用功能表)。
?硬件排查?:
檢查是否存在 PB0 與 PA0、PB2 與 PA1 的意外短路。
🛠? ?解決方案建議?
?統(tǒng)一代碼與硬件定義?:
修改代碼中的引腳定義,使其與實(shí)際接線一致(如將 PB0 改為 PA0)。
?明確定時器通道映射?:
在代碼中顯式配置引腳重映射(如需),避免隱式依賴默認(rèn)映射。
?示例?:
c
Copy Code
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);? // 顯式重映射TIM2通道

?添加注釋與文檔?:
在代碼和硬件手冊中明確記錄引腳對應(yīng)關(guān)系,減少后續(xù)維護(hù)成本。
? ?總結(jié)?

引腳定義不一致但小車能運(yùn)行,本質(zhì)是 ?信號流在硬件或代碼層被隱式修正?。需通過硬件檢測和代碼審計定位具體原因,最終確保定義與實(shí)物的嚴(yán)格一致。

六、循跡小車

循跡模塊詳解 | 良許嵌入式

注意這里的接線改回去了,要是不改回去會出錯,小車會不要電的一直跑

復(fù)制01重命名05-循跡小車

循跡模塊和紅外傳感器模塊很像,所以復(fù)制智能臺燈的ia_sensor

粘貼到05文件的BSP文件中,并且重命名為track

打開文件

加載文件

七、循跡+PWM調(diào)速

??????? 上面循跡小車中,可能會出現(xiàn)由于地圖太小,小車太大,太沉,電機(jī)電壓夠足導(dǎo)致小車速度太快從而小車在拐彎的時候,沖出地圖跑道。

????????為了避免這這種情況的發(fā)生,可以選擇換一張大地圖、把小車重量減輕、體積減輕、讓小車變得更靈活,或者把小車電機(jī)電壓減少,小車速度放慢。

這里使用PWM調(diào)速小車

使用PWM的接線

復(fù)制04pwm文件重命名為06-循跡+pwm調(diào)速控制小車

將05中的track文件粘貼到06中

打開工程,加載文件

這里注意改變arr和psc的值

因?yàn)樵瓉淼?0-1,72-1,步子太大了

上述中小車可以設(shè)置的pwm波為0-20,如果設(shè)置9太快了,如果設(shè)置8太慢了,所以讓它步子小一點(diǎn),這樣可以設(shè)置的值就更精確了

具體的數(shù)值,需要結(jié)合實(shí)際情況自己設(shè)定,這里95的速度只符合我這里

八、跟隨小車

跟隨小車要達(dá)到的效果是:

當(dāng)兩邊的跟隨模塊都檢測到東西的時候,就向前走,當(dāng)右邊檢測到東西的時候,就向右走,否則向左走,當(dāng)都未檢測到東西的時候,就停止。

復(fù)制01,重命名為07-跟隨小車

將循跡模塊的track重命名為followu

打開項(xiàng)目,加載文件,將所有的track重命名為follow

更改引腳

代碼如下:

九、避障小車

復(fù)制項(xiàng)目文件01,重命名為08-避障小車

復(fù)制超聲波實(shí)驗(yàn)和舵機(jī)實(shí)驗(yàn)的文件,粘貼至如下圖所示

接線如圖所示:

打開項(xiàng)目

加載文件

要加入定時器文件

舵機(jī)代碼可以分裝成左轉(zhuǎn),右轉(zhuǎn),中間,方便看

超聲波的代碼就是按照上面的接線,改一下引腳,就可以直接用了

主函數(shù)代碼如下:

#include "sys.h"
#include "delay.h"
#include "uart1.h"
#include "motor.h"
#include "sg90.h"
#include "hcsr04.h"int main(void)
{HAL_Init();                         /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */uart1_init(115200);motor_init();sg90_init();hcsr04_init();printf("hello word!\r\n");double dis_left = 0, dis_middle = 0, dis_right = 0;sg90_turn_middle();while(1) { dis_middle = hcsr04_get_lenght();//接收超聲波所測的距離if(dis_middle > 35)//判斷距離是否大于35?是向前走motor_go_forward();else if(dis_middle < 15)//否則判斷距離是否小于15?是后退motor_go_backward();else //否則就是距離>15并且<35{motor_stop();  //先停下來//向左看并測量左側(cè)距離sg90_turn_left();delay_ms(500);  //給個時間進(jìn)行測量dis_left = hcsr04_get_lenght();   //存儲下左側(cè)的長度//居中sg90_turn_middle();   //超聲波傳感器回到中間的位置delay_ms(500);//向右看并測量右側(cè)距離sg90_turn_right();delay_ms(500);dis_right = hcsr04_get_lenght();//根據(jù)距離判斷左轉(zhuǎn)還是右轉(zhuǎn)if(dis_left < dis_right)motor_go_right();elsemotor_go_left();delay_ms(500);  //給個時間反應(yīng)一下motor_stop();  //電機(jī)停一下sg90_turn_middle();  //舵機(jī)回到中間的位置}delay_ms(100);  //給個時間反應(yīng)一下}
}

十、測速模塊

接線如下圖所示:

復(fù)制02-串口控制小車

重命名為09-測速小車

新建speed文件

打開項(xiàng)目,加載文件

別忘了把定時器的驅(qū)動文件加載進(jìn)來

寫頭文件

注意:測速模塊要用到中斷,每次感受到一個下降沿就中斷一次,目的為了更好的測速

然后使用定時器,每一秒定時一次

代碼如下:

#include "speed.h"
#include "delay.h"
#include "stdio.h"uint16_t speed_cnt = 0;
TIM_HandleTypeDef timer_handle = {0};//定義結(jié)構(gòu)體//gpio口初始化
void speed_gpio_init(void)
{//使能GPIO時鐘GPIO_InitTypeDef gpio_initstruct;//定義一個結(jié)構(gòu)體gpio_initstruct//打開時鐘-使能GPIO時鐘__HAL_RCC_GPIOB_CLK_ENABLE();//設(shè)置GPIO輸入模式//設(shè)置AFIO(開啟時鐘,IO口映射)//設(shè)置EXTI(屏蔽,上/下沿)//調(diào)用GPIO初始化函數(shù)gpio_initstruct.Mode = GPIO_MODE_IT_FALLING;//下降沿輸出//結(jié)構(gòu)體函數(shù)的四種類型,引腳模式、引腳、引腳上拉下拉、引腳速度gpio_initstruct.Pin = GPIO_PIN_12;//LED1對應(yīng)的引腳gpio_initstruct.Pull = GPIO_NOPULL;//上拉HAL_GPIO_Init(GPIOB,&gpio_initstruct);//設(shè)置NVIC(優(yōu)先級分組,設(shè)置優(yōu)先級,使能中斷)HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
//定時器中的初始化
void speed_timer_init(uint16_t arr,uint16_t psc)
{timer_handle.Instance = TIM2; //選擇使用的定時器timer_handle.Init.Prescaler = psc; //PSCtimer_handle.Init.Period = arr; //ARRtimer_handle.Init.CounterMode = TIM_COUNTERMODE_UP;//配置成向上的,默認(rèn)向上的timer_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;  //自動重裝載,禁用自動重裝載HAL_TIM_Base_Init(&timer_handle);HAL_TIM_Base_Start_IT(&timer_handle);//設(shè)置使能更新中斷,和啟動計數(shù)器
}
//初始化speed函數(shù)
void speed_init(void)
{speed_gpio_init();speed_timer_init(10000-1,7200-1);//一秒中斷一次的定時器
}//設(shè)置中斷服務(wù)函數(shù)
void EXTI15_10_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
}
//回調(diào)函數(shù)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(20);if(GPIO_Pin == GPIO_PIN_12){if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_RESET){speed_cnt++;printf("speed = %d\r\n",speed_cnt);  //測量出格子的個數(shù)}}
}
//定時器msp函數(shù)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){__HAL_RCC_TIM2_CLK_ENABLE();HAL_NVIC_SetPriority(TIM2_IRQn,2,2);//設(shè)置優(yōu)先級HAL_NVIC_EnableIRQ(TIM2_IRQn);//設(shè)置使能中斷}
}//定時器中斷服務(wù)函數(shù) 
void TIM2_IRQHandler(void)
{//一般還會調(diào)用一個公共處理的服務(wù)函數(shù)HAL_TIM_IRQHandler(&timer_handle); }
//定時器中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){//測量到每一秒轉(zhuǎn)了多少個格子printf("speed = %d\r\n",speed_cnt);speed_cnt = 0;}
}

主函數(shù)如下:

#include "sys.h"
#include "delay.h"
#include "uart1.h"
#include "motor.h"
#include "bluetooth.h"
#include "speed.h"int main(void)
{HAL_Init();                         /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */uart1_init(115200);motor_init();speed_init();bt_init(9600);printf("hello word!\r\n");motor_go_forward(); //讓小車前進(jìn)while(1) { }
}

十一、測速小車oled顯示并上傳藍(lán)牙

復(fù)制09,重命名為10-測速小車oled顯示并上傳藍(lán)牙

粘貼oled文件

打開項(xiàng)目

加載文件

想把獲取到的速度,打印到oled上

我們得到的值是數(shù)字,要將這個數(shù)字轉(zhuǎn)換成字符串打印到oled屏幕上

數(shù)字轉(zhuǎn)字符串我們使用sprintf

定義一個字符數(shù)組

使用memset()先把這個字符數(shù)組清空,免得之后每次中斷之后傳進(jìn)來的數(shù)據(jù)對其進(jìn)行干擾

修改oled引腳

編譯,無錯

將藍(lán)牙模塊的這個函數(shù)的這個位置修改成這樣

?因?yàn)樵瓉硎褂玫膕izeof打印子啊手機(jī)上間距太大,不正常,如下所示

所以,換成strlen,就變成了如下所示:

?十二、wifi控制小車速度

將藍(lán)牙模塊換成esp8266模塊

讓電腦可以看見小車的速度買也可以使用電腦控制小車前進(jìn)后退

將esp8266接到串口2 的tx和rx中

復(fù)制10,重命名11-WiFi控制小車并顯示速度

打開項(xiàng)目,加載文件

將藍(lán)牙的相關(guān)文件刪除

編譯不出錯

使用網(wǎng)絡(luò)調(diào)試助手架構(gòu)一個服務(wù)器

連接esp8266

?

#include "sys.h"
#include "delay.h"
#include "uart1.h"
#include "motor.h"
#include "speed.h"
#include "oled.h"
#include "esp8266.h"
#include "string.h"int main(void)
{HAL_Init();                         /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */uart1_init(115200);motor_init();speed_init();oled_init();esp8266_init(115200); printf("hello word!\r\n");motor_go_forward(); //讓小車前進(jìn)char recv_data[ESP8266_RX_BUF_SIZE];while(1) { //esp8266發(fā)送數(shù)據(jù)esp8266_receive_data(recv_data);if(strstr(recv_data, "M1") != NULL)motor_go_forward();else if(strstr(recv_data, "M2") != NULL)motor_go_backward();else if(strstr(recv_data, "M3") != NULL)motor_go_left();else if(strstr(recv_data, "M4") != NULL)motor_go_right();elsemotor_stop();}
}

?

這里沒有用到空閑中斷,不把它注釋掉反而會出錯

十三、4G控制小車

4G模塊引腳接線,tx、rx接串口2,vcc接串口1中的5v,gnd隨便找個地方接一下就可以

使用4G模塊要使用花生殼進(jìn)行內(nèi)網(wǎng)穿透,獲取外網(wǎng)地址

設(shè)置鏈路

對于4G模塊的代碼可以直接復(fù)用10-測速小車oled顯示并上傳藍(lán)牙

其中只需要注意4G模塊的波特率就好,你的4G模塊是什么波特率就改什么波特率

連接上4G模塊之后,

這段代碼就不是透傳到藍(lán)牙模塊上了,而是透傳到4G模塊

所以就可以在網(wǎng)絡(luò)調(diào)試助手上看見了

十四、語音控制小車

接線如下圖所示:

配置SU-03T,點(diǎn)開網(wǎng)站:智能公元/AI產(chǎn)品零代碼平臺

語言選擇中文,下一步

設(shè)置三次

?等待SDK燒錄完成之后,就可以下載固件了

將語音模塊接線之后

進(jìn)行燒錄

然后再燒錄的exe工具中,選擇如下文件

記住:這個文件不要放到中文路徑下,路徑也不要太長

?

?至此,語音文件就燒錄完成了

下面是代碼部分的編寫:

復(fù)制01,重命名12-語音控制小車

?打開項(xiàng)目,加載文件

記得加入定時器文件

編譯,無錯之后進(jìn)行下一步

在主函數(shù)中寫入頭文件和初始化函數(shù),編譯,無錯,進(jìn)行下一步

記得每次往主函數(shù)中融合其他模塊的時候,要編譯測試一下,減少錯誤率

主函數(shù)代碼如下:

#include "sys.h"
#include "delay.h"
#include "uart1.h"
#include "motor.h"
#include "follow.h"
#include "hcsr04.h"
#include "sg90.h"
#include "track.h"double dis_left = 0, dis_middle = 0, dis_right = 0;//循跡模式
void track_mode(void)
{if(track_left_flag() == TRUE && track_right_flag() == TRUE)motor_go_forward(); //前進(jìn)else if(track_left_flag() == FALSE && track_right_flag() == TRUE)  //左邊壓線motor_go_left(); //左轉(zhuǎn)else if(track_left_flag() == TRUE && track_right_flag() == FALSE)  //右邊壓線motor_go_right(); //右轉(zhuǎn)else if(track_left_flag() == FALSE && track_right_flag() == FALSE) // 全部為黑色motor_stop(); //停止
}
//跟隨模式
void follow_mode(void)
{if(follow_left_flag() == TRUE && follow_right_flag() == TRUE)motor_go_forward();else if(follow_left_flag() == FALSE && follow_right_flag() == TRUE)//右邊有目標(biāo)motor_go_right();else if(follow_left_flag() == TRUE && follow_right_flag() == FALSE)//左邊有目標(biāo)motor_go_left();else if(follow_left_flag() == FALSE && follow_right_flag() == FALSE)motor_stop();
}
//避障模式
void avoid_mode(void)
{dis_middle = hcsr04_get_lenght();//接收超聲波所測的距離if(dis_middle > 35)//判斷距離是否大于35?是向前走motor_go_forward();else if(dis_middle < 15)//否則判斷距離是否小于15?是后退motor_go_backward();else //否則就是距離>15并且<35{motor_stop();  //先停下來//向左看并測量左側(cè)距離sg90_turn_left();delay_ms(500);  //給個時間進(jìn)行測量dis_left = hcsr04_get_lenght();   //存儲下左側(cè)的長度//居中sg90_turn_middle();   //超聲波傳感器回到中間的位置delay_ms(500);//向右看并測量右側(cè)距離sg90_turn_right();delay_ms(500);dis_right = hcsr04_get_lenght();//根據(jù)距離判斷左轉(zhuǎn)還是右轉(zhuǎn)if(dis_left < dis_right)motor_go_right();elsemotor_go_left();delay_ms(500);  //給個時間反應(yīng)一下motor_stop();  //電機(jī)停一下sg90_turn_middle();  //舵機(jī)回到中間的位置}delay_ms(100);  //給個時間反應(yīng)一下
}int main(void)
{HAL_Init();                         /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */uart1_init(115200);motor_init();follow_init();hcsr04_init();sg90_init();track_init();printf("hello word!\r\n");sg90_turn_middle();while(1) { }
}

新建一個voice文件,加載文件

voice.c代碼如下:

voice.h文件

主函數(shù)代碼如下:

#include "sys.h"
#include "delay.h"
#include "uart1.h"
#include "motor.h"
#include "follow.h"
#include "hcsr04.h"
#include "sg90.h"
#include "track.h"
#include "voice.h"double dis_left = 0, dis_middle = 0, dis_right = 0;//循跡模式
void track_mode(void)
{if(track_left_flag() == TRUE && track_right_flag() == TRUE)motor_go_forward(); //前進(jìn)else if(track_left_flag() == FALSE && track_right_flag() == TRUE)  //左邊壓線motor_go_left(); //左轉(zhuǎn)else if(track_left_flag() == TRUE && track_right_flag() == FALSE)  //右邊壓線motor_go_right(); //右轉(zhuǎn)else if(track_left_flag() == FALSE && track_right_flag() == FALSE) // 全部為黑色motor_stop(); //停止
}
//跟隨模式
void follow_mode(void)
{if(follow_left_flag() == TRUE && follow_right_flag() == TRUE)motor_go_forward();else if(follow_left_flag() == FALSE && follow_right_flag() == TRUE)//右邊有目標(biāo)motor_go_right();else if(follow_left_flag() == TRUE && follow_right_flag() == FALSE)//左邊有目標(biāo)motor_go_left();else if(follow_left_flag() == FALSE && follow_right_flag() == FALSE)motor_stop();
}
//避障模式
void avoid_mode(void)
{dis_middle = hcsr04_get_lenght();//接收超聲波所測的距離if(dis_middle > 35)//判斷距離是否大于35?是向前走motor_go_forward();else if(dis_middle < 15)//否則判斷距離是否小于15?是后退motor_go_backward();else //否則就是距離>15并且<35{motor_stop();  //先停下來//向左看并測量左側(cè)距離sg90_turn_left();delay_ms(500);  //給個時間進(jìn)行測量dis_left = hcsr04_get_lenght();   //存儲下左側(cè)的長度//居中sg90_turn_middle();   //超聲波傳感器回到中間的位置delay_ms(500);//向右看并測量右側(cè)距離sg90_turn_right();delay_ms(500);dis_right = hcsr04_get_lenght();//根據(jù)距離判斷左轉(zhuǎn)還是右轉(zhuǎn)if(dis_left < dis_right)motor_go_right();elsemotor_go_left();delay_ms(500);  //給個時間反應(yīng)一下motor_stop();  //電機(jī)停一下sg90_turn_middle();  //舵機(jī)回到中間的位置}delay_ms(100);  //給個時間反應(yīng)一下
}int main(void)
{HAL_Init();                         /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */uart1_init(115200);motor_init();follow_init();hcsr04_init();sg90_init();track_init();voice_init();printf("hello word!\r\n");sg90_turn_middle();while(1) { if(TRACK_PIN == GPIO_PIN_RESET && FOLLOW_PIN == GPIO_PIN_SET && AVOID_PIN == GPIO_PIN_SET)track_mode();//循跡模式else if(TRACK_PIN == GPIO_PIN_SET && FOLLOW_PIN == GPIO_PIN_RESET && AVOID_PIN == GPIO_PIN_SET)follow_mode();//跟隨模式else if(TRACK_PIN == GPIO_PIN_SET && FOLLOW_PIN == GPIO_PIN_SET && AVOID_PIN == GPIO_PIN_RESET)avoid_mode();//避障模式}
}

編譯無錯

http://www.risenshineclean.com/news/45178.html

相關(guān)文章:

  • wordpress 南非政府網(wǎng)絡(luò)seo招聘
  • 高端手機(jī)網(wǎng)站 制作公司鄭州百度推廣開戶
  • 建設(shè)網(wǎng)站模板免費(fèi)百度掃一掃識別圖片在線
  • wordpress登錄漏洞杭州網(wǎng)站排名seo
  • p2p網(wǎng)站建設(shè)源碼seo全國最好的公司
  • 長沙網(wǎng)站seo技巧今日足球賽事數(shù)據(jù)
  • 信息類網(wǎng)站制作bt鸚鵡磁力
  • 競價網(wǎng)站做seosem推廣軟件哪家好
  • 北京營銷型網(wǎng)站建設(shè)價格什么是sem
  • 高新網(wǎng)站建設(shè)多少錢國際國內(nèi)新聞最新消息今天
  • 如何制作企業(yè)的網(wǎng)站瀏覽器里面信息是真是假
  • 給學(xué)校做網(wǎng)站合肥百度競價推廣代理公司
  • 廈門百度網(wǎng)站建設(shè)優(yōu)化大師下載安裝app
  • wordpress實(shí)現(xiàn)pdf瀏覽seo網(wǎng)絡(luò)推廣機(jī)構(gòu)
  • 寶安中心做網(wǎng)站網(wǎng)站公司網(wǎng)站建設(shè)
  • 《原始傳奇》官方網(wǎng)站seo推廣工具
  • 鐵嶺做網(wǎng)站信息網(wǎng)店推廣的渠道有哪些
  • 長治市人民政府門戶網(wǎng)站簡單的網(wǎng)站制作
  • 網(wǎng)站源碼推薦谷歌sem
  • 汽車網(wǎng)站更新怎么做口碑營銷的例子
  • 鄭州展廳設(shè)計制作公司seo綜合查詢什么意思
  • 旅游類網(wǎng)站如何做推廣百度推廣后臺
  • 目錄網(wǎng)站模板php搭建一個簡單的網(wǎng)站
  • iis7建立網(wǎng)站可以看封禁網(wǎng)站的瀏覽器
  • 做網(wǎng)站公司排名電話國際新聞快報
  • 外貿(mào)網(wǎng)站建設(shè)模板百度云客服人工電話
  • 企業(yè)網(wǎng)站注冊官網(wǎng)百度搜索結(jié)果優(yōu)化
  • 網(wǎng)站如何做微信支付寶支付寶支付社交網(wǎng)絡(luò)的推廣方法
  • 深圳云網(wǎng)站建站公司搜索引擎的設(shè)計與實(shí)現(xiàn)
  • 搜狐一開始把網(wǎng)站當(dāng)做什么來做站長之家官網(wǎng)