stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)

目录

一。材料准备。

二。PCB原理图 

三。逻辑状态图

四。代码部分

五。文件下载:


stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第1张图片

接上:stm32f103 简易4路红外寻迹小车(1)----2023西南交大电赛校赛(含stm32中文资料)

小车测试视频:

stm32小车寻迹小车

一。材料准备。

材料资料图片见上:stm32f103 简易4路红外寻迹小车(1)----2023西南交大电赛校赛(含stm32中文资料)

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第2张图片

电机驱动MX1919L

VCC统一接stm32系统板的3.3v。VDD接7.4V电源。电容连接如图。左侧和右侧两轮分别接2通道。

利用pwm波改变占空比控制电机转速,逻辑输入接可以产生pwm的PA6,PA7,PB0,PB1(TIM3),复用推挽输出。

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第3张图片

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第4张图片

红外寻迹模块

接PB4,PB5,PB6,PB7。浮空输入

二。PCB原理图 

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第5张图片

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第6张图片

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第7张图片

学校发了最小系统板所有没有自己做驱动板直接把最小系统板插上去用了。

三。逻辑状态图

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第8张图片

四。代码部分

pwm.c 

启用TIM3时钟 输出pwm波使用的是TIM3的4个通道(A6 A7 B0 B1)分别连接电机驱动的Vina1 Vinb1 Vina2 Vinb2。

设置为复用推挽输出。

#include "stm32f10x.h"
#include "pwm.h"
#include "delay.h"

void pwm_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
	
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
	
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
	
}
//T(s)周期/溢出时间=(arr溢出值+1)(psc分频系数+1)/Tclk  
//Tlck为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72Mhz
//PWM时钟频率=1/T
//TIM_SetCompare3(TIM3,1500);//改变比较值TIM3->CCR2达到调节占空比的效果
void pwm(u16 arr,u16 ccr){
//2个结构体的定义
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;

	TIM_DeInit(TIM3);//TIM3设置为缺省值
	TIM_TimeBaseStructure.TIM_Period= arr-1; //自动重装载寄存器的值 因为从0开始计到arr-1 共arr个数 
	TIM_TimeBaseStructure.TIM_Prescaler= 1;//时钟预分频数
	TIM_TimeBaseStructure.TIM_ClockDivision=0x0;//采样分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1 ;        //TIM的PWM1模式         PWM1  PMW2
	TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse=ccr-1;                  //设置占空比
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//TIM输出比较极性高    High  Low
	
	TIM_OC1Init(TIM3,&TIM_OCInitStructure);              
	TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OC2Init(TIM3,&TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OC4Init(TIM3,&TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_ARRPreloadConfig(TIM3,ENABLE);//使能定时器TIM3在ARR上的预装载寄存器
    TIM_Cmd (TIM3,ENABLE);//使能定时器3
}

xunkun.c  读取红外信号

TC表示从左到右红外显示的红外寻迹信号 如1111 表示全部检测的黑线

#include "xunkun.h"
//#define LL1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)//读取 PB4
//#define LL2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)//读取 PB5
//#define RR2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)//读取 PB6
//#define RR1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)//读取 PB7
//#define TC   1000*LL1+100*LL2+10*RR2+1*RR1
void xunkun_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;                                     
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING;  
	GPIO_Init(GPIOB,&GPIO_InitStructure);                        
}

diankun.c   电机驱动调速部分,TIM_SetCompareX(TIMX,X);改变TIMX时钟的某一通道的ccr,从而改变占空比。

stm32f103 简易4路红外寻迹小车(2)----2023西南交大电赛校赛(pcb原理图,代码及分析)_第9张图片

#include "stm32f10x.h"
#include "diankun.h"
#include "delay.h"
void diankun_Z1(void){//快速直走
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,2000);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,2000);
	  delay_ms(10);}
void diankun_L1(void){//快速左转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,1750);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,2000);
	  delay_ms(10);}
void diankun_L2(void){//中速左转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,1500);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,2000);
	 delay_ms(10);}
void diankun_L3(void){//慢速左转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,1000);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,2000);
	 delay_ms(10);}
void diankun_R1(void){//快速右转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,2000);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,1750);
     delay_ms(10);}
void diankun_R2(void){//中速右转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,2000);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,1500);
	 delay_ms(10);}
void diankun_R3(void){//慢速右转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,2000);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,1000);
	 delay_ms(10);}
void diankun_LL(void){//向左旋转
	 TIM_SetCompare1(TIM3,1500);
	 TIM_SetCompare2(TIM3,1);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,1650);
	 delay_ms(8);}
void diankun_LL2(void){//向左旋转
	 TIM_SetCompare1(TIM3,1500);
	 TIM_SetCompare2(TIM3,1500);
	 TIM_SetCompare3(TIM3,1);
	 TIM_SetCompare4(TIM3,2000);
	 delay_ms(8);}
void diankun_RR(void){//向右旋转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,1650);
	 TIM_SetCompare3(TIM3,1500);
	 TIM_SetCompare4(TIM3,1);
	 delay_ms(8);}
void diankun_RR2(void){//向右旋转
	 TIM_SetCompare1(TIM3,1);
	 TIM_SetCompare2(TIM3,2000);
	 TIM_SetCompare3(TIM3,1500);
	 TIM_SetCompare4(TIM3,1500);
	 delay_ms(8);}
void diankun_X1(void){//快速制动
	 TIM_SetCompare1(TIM3,1800);
	 TIM_SetCompare2(TIM3,1800);
	 TIM_SetCompare3(TIM3,1800);
	 TIM_SetCompare4(TIM3,1800);
	 delay_ms(10);}

main.c   

SD识别赛道,用与入库出库和更圆滑的通过弧线弯道,本代码是小车开始识别不到黑线则判定为竞速赛道,这里也可以使用开关来调节小车模式

RL是记录小车最左侧和最右侧的最后一次检测信号,用于当小车冲出赛道(识别不到黑线)应该向什么方向旋转。

#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "pwm.h"
#include "diankun.h"
#include "xunkun.h"
int main(void)
{
	xunkun_init();
	pwm_init();
	pwm(2000,1);//初始pwm值
	u8 RL=0;//R=0,L=1,确定0000前最后一次转弯方向
	u8 SD=0;//识别是否为竞速赛道
	delay_ms(20);//等待设备稳定

	if(TC==0){//0000识别赛道起点
		diankun_RR();
		SD=1;//改变RR和LL为RR2和LL2
		delay_ms(450);}
 while(1){ 
	 //入库
	  if(TC==1111&&SD==1){//1111
			 diankun_Z1();
	         delay_ms(80);			 
			 if(TC==0) {
		    diankun_RR();
			delay_ms(560);	
		   while(1) diankun_X1();}}
	 //旋转
	  if(TC==0){//0000
			if(SD==0)diankun_X1();
		  while(TC==0&&SD==0){ 
			  if(RL) diankun_LL(); 
			  else   diankun_RR();}
	      while(TC==0&&SD==1){ 
			  if(RL) diankun_LL2(); 
			  else   diankun_RR2();} }
	  //直走
	  if(TC==1001||TC==110|TC==1111){//1001,0110,1111
		  diankun_Z1();}
	  //右转
	  if(TC==1011||TC==111){//1011,0111  
		  RL=0;
		  diankun_R1();}
	  if(TC==11||TC==1010){//0011,1010
		  RL=0;
		  diankun_R2();}
	  if(TC==1){//0001
		  RL=0;
		  diankun_R3();}
	  if(TC==10){//0010
		  diankun_R1();}
	  //左转
	  if(TC==1101||TC==1110){//1101,1110 
		  RL=1;
		  diankun_L1();} 
	  if(TC==1100||TC==101){//1100,0101 
		  RL=1;
		  diankun_L2();}
	  if(TC==1000){//1000
		  RL=1;
		  diankun_L3();}
	  if(TC==100){//0100
		  diankun_L1();}
      }}

五。文件下载:(代码+pcb原理图)

https://pan.baidu.com/s/1YfZJb8128TMIqJpYZ9hwDA   提取码:0435

第一次参加单片机比赛 第一次学习stm32 虽然最后小车还是拿了校一 但是学习较浅 代码不足之处还请见谅。

后面省赛国赛我还会继续分享自己的历程,多多支持我这个初学者哦。

你可能感兴趣的:(稀烂胶带胶兵在行动,stm32的学习,stm32,单片机,嵌入式硬件)