STM32F103に基づく赤外線追跡および障害物回避車の設計
赤外線追跡と赤外線障害物回避の実現は比較的簡単で、51シングルチップであろうとSTM32シングルチップであろうと、そのルーチンはどこにでも見られます。しかし、STM32マイクロプロセッサに基づくシミュレーションは言うまでもなく、実行できるオープンソースのProteusシミュレーションは多くありません。
STM32F103に基づく赤外線追跡および障害物回避車のプロテウスシミュレーションについてお話ししましょう。
まず、ProteusソフトウェアがSTM32をシミュレートできるかどうかを確認しましょう。
Proteus8.6バージョンを使用しています。次のSTM32チップを確認できます。
ProteusがSTM32でシミュレーション実験を実行できることを証明するために、照明シミュレーションにSTM32F103R6チップを選択しました。
走行後、LEDライトが点灯していることがわかります。
プログラムのこの部分(つまり、STM32がLEDを点灯させる)は次のとおりです。
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"
static void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
int main ( void )
{
LED_Init ();
Key_GPIO_Config();
macLED1_OFF ();
macLED2_OFF ();
macLED3_OFF ();
while ( 1 )
{
if( Key_Scan(macKEY1_GPIO_PORT,macKEY1_GPIO_PIN) == KEY_ON )
{
macLED1_TOGGLE() ;
macLED2_TOGGLE() ;
macLED3_TOGGLE() ;
}
}
}
次に、赤外線追跡と障害物回避のProteusシミュレーションを開始します。
赤外線追跡モジュール、このモデルを選択してください。使いやすく、安価です。
その動作原理については詳しく説明しません。その概略図は次のとおりです。
赤外線障害物回避モジュールを比較したところ、この赤外線モジュールが最高の赤外線障害物回避効果を持っていることがわかりました。
モータードライブモジュール、L298モータードライブを選択します。このドライブはより一般的に使用され、使いやすいです。
概略図は次のとおりです。
STM32 MCUはSTM32F103C8T6を選択し、この小さなコアボードを購入するだけで経済的です。
シングルチップマイクロコンピュータの最小システムの概略図:
電源の概略図は次のとおりです。
Proteus赤外線モジュールのシミュレーションは、ボタンでのみシミュレートできます。つまり、マイクロコントローラーのピンが0信号と1信号を検出します。
完全なプロテウスシミュレーション図は次のとおりです。
クリックして実行
ご覧のとおり、プログラムは実行できません。実行中であることを示していますが、プログラムは正常にループできません。
実践により、プロテウスシミュレーションSTM32は単純なシミュレーションしか実行できず、複雑なシミュレーションは実行できないことが証明されています。ただし、51個のシングルチップマイクロメータのシミュレーションはまったく問題ありません。
したがって、私の提案は、物理オブジェクトを直接実行することです。最終的に、物理オブジェクトは問題なく正常にデバッグされます。
実際の写真に来てください
参考までに、手順の一部は次のとおりです。
メインプログラム
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include "bsp_led.h"
#include <string.h>
#include <stdlib.h>
#include "bsp_pwm_output.h"
#include "infrared.h"
#include "delay.h"
unsigned int Task_Delay[NumOfTask];
int main(void)
{
SysTick_Init();
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
TIMx_PWM_Init();
infrared_Initial();
while(1)
{
if((infrared_Scan(infrared_5_GPIO_PORT,infrared_5_GPIO_PIN)==INFRARED_ON)&&\
(infrared_Scan(infrared_6_GPIO_PORT,infrared_6_GPIO_PIN)==INFRARED_ON))
{
DelayS(3);
if((infrared_Scan(infrared_5_GPIO_PORT,infrared_5_GPIO_PIN)==INFRARED_ON)&&\
(infrared_Scan(infrared_6_GPIO_PORT,infrared_6_GPIO_PIN)==INFRARED_ON))
{
TIMx_Mode_Config(500,0,0,500);
DelayMs(500);
}
else
{
TIMx_Mode_Config(500,0,0,500);
DelayMs(500);
}
}
else
{
if((infrared_Scan(infrared_3_GPIO_PORT,infrared_3_GPIO_PIN)==INFRARED_ON))
TIMx_Mode_Config(0,0,600,0);
else if((infrared_Scan(infrared_2_GPIO_PORT,infrared_2_GPIO_PIN)==INFRARED_ON))
TIMx_Mode_Config(600,0,0,0);
else if((infrared_Scan(infrared_4_GPIO_PORT,infrared_4_GPIO_PIN)==INFRARED_ON))
TIMx_Mode_Config(0,0,900,0);
else if((infrared_Scan(infrared_1_GPIO_PORT,infrared_1_GPIO_PIN)==INFRARED_ON))
TIMx_Mode_Config(900,0,0,0);
else
TIMx_Mode_Config(500,0,500,0);
}
}
}
PWM波プログラム
#include "bsp_pwm_output.h"
static void TIMx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
macTIM_APBxClock_FUN (macTIM_CLK, ENABLE);
macTIM_GPIO_APBxClock_FUN (macTIM_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = macTIM_CH1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(macTIM_CH1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = macTIM_CH2_PIN;
GPIO_Init(macTIM_CH2_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = macTIM_CH3_PIN;
GPIO_Init(macTIM_CH3_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = macTIM_CH4_PIN;
GPIO_Init(macTIM_CH4_PORT, &GPIO_InitStructure);
}
void TIMx_Mode_Config(u16 CCR1_Val,u16 CCR2_Val,u16 CCR3_Val, u16 CCR4_Val)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(macTIMx, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(macTIMx, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(macTIMx, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(macTIMx, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(macTIMx, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(macTIMx, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(macTIMx, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(macTIMx, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(macTIMx, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(macTIMx, ENABLE);
TIM_Cmd(macTIMx, ENABLE);
}
void TIMx_PWM_Init(void)
{
TIMx_GPIO_Config();
TIMx_Mode_Config(0,0,0,0);
}
遅延プログラム
#include "stm32f10x.h"
#include "delay.h"
static u8 fac_us=0;
static u16 fac_ms=0;
void DelayInit()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SystemCoreClock/8000000;
fac_ms=(u16)fac_us*1000;
}
void DelayUs(unsigned long nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
void DelayMs(unsigned int nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
void DelayS(unsigned int ns)
{
unsigned char i;
for(i=0;i<ns;i++)
{
DelayMs(1000);
}
}
STM32の設計に関しては、Proteusソフトウェアは一時的に完全なシミュレーションを実行できません。シミュレーションではなく、物理オブジェクトを直接設計し、物理オブジェクトをデバッグすることをお勧めします。
決定の高さを共有し、ギャップを開くことを学ぶ
学習者として、完成したこの作品を皆さんと共有したいと思いますので、皆様のお役に立てれば幸いです。もちろん、上記に問題がございましたら、訂正してください。
メッセージを残し、批判し、訂正するために皆を歓迎します!