出电磁寻迹小车代码 主控stm32c8t6 提供原理图 pcb
一、引言
电磁寻迹小车在智能车竞赛等场景中有着广泛应用。以STM32C8T6为主控芯片来打造这样一辆小车,我们需要从硬件原理图、PCB设计以及代码实现等多个方面入手。今天就来和大家详细唠唠这其中的门道,并分享相关代码。
二、硬件部分:原理图与PCB设计
2.1 原理图
首先,我们来看原理图。STM32C8T6作为核心,它要与电磁传感器、电机驱动等模块连接。
- 电磁传感器部分:电磁传感器用于检测赛道上的电磁信号。一般会有多个传感器分布在小车前端,比如三个传感器呈线性排列。传感器将感应到的电磁信号转化为电压信号,这些模拟信号需要输入到STM32C8T6的ADC(模拟数字转换器)引脚。例如,PA0 - PA2引脚可作为ADC输入引脚连接传感器输出端。
- 电机驱动部分:常见的电机驱动芯片如L298N,它负责为直流电机提供足够的驱动电流。STM32C8T6通过GPIO(通用输入输出)引脚输出PWM(脉冲宽度调制)信号来控制电机的转速和转向。比如,PB0、PB1引脚可以分别连接到L298N的使能端,通过输出不同占空比的PWM信号来控制左右电机的转速。
2.2 PCB设计
在PCB设计时,要注意布局和布线。
- 布局:将STM32C8T6芯片放置在板子中央位置,方便与周围模块连接。电磁传感器尽量靠近小车前端,减少信号传输干扰。电机驱动芯片靠近电机放置,缩短大电流传输路径。
- 布线:对于电源布线,要加粗电源线,确保为各个模块提供稳定的电源。模拟信号布线要尽量短且远离数字信号布线,防止数字信号对模拟信号产生干扰。特别是电磁传感器的信号线,要用屏蔽线或者在PCB上包地处理。
三、代码实现
3.1 初始化部分
#include "stm32f10x.h" void ADC_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 3; ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); } void TIM3_PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 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); TIM_TimeBaseStructure.TIM_Period = 999; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); }代码分析:
ADC_Init函数用于初始化ADC。首先使能GPIOA和ADC1的时钟,然后将PA0 - PA2配置为模拟输入模式。接着对ADC1进行模式、扫描模式、转换模式等参数设置,最后使能ADC1。TIM3PWMInit函数初始化TIM3用于产生PWM信号。使能TIM3和GPIOB时钟,将PB0和PB1配置为复用推挽输出模式。设置TIM3的周期、预分频器等参数,配置OC1和OC2为PWM1模式并使能输出。
3.2 主函数部分
int main(void) { uint16_t adc_value[3]; ADC_Init(); TIM3_PWM_Init(); while (1) { for (int i = 0; i < 3; i++) { ADC_RegularChannelConfig(ADC1, ADC_Channel_0 + i, 1, ADC_SampleTime_55Cycles5); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); adc_value[i] = ADC_GetConversionValue(ADC1); } if (adc_value[0] > adc_value[1] && adc_value[0] > adc_value[2]) { TIM_SetCompare1(TIM3, 500); TIM_SetCompare2(TIM3, 300); } else if (adc_value[2] > adc_value[1] && adc_value[2] > adc_value[0]) { TIM_SetCompare1(TIM3, 300); TIM_SetCompare2(TIM3, 500); } else { TIM_SetCompare1(TIM3, 500); TIM_SetCompare2(TIM3, 500); } } }代码分析:
- 在主函数中,先定义了一个数组
adcvalue用于存储ADC转换后的值。调用ADCInit和TIM3PWMInit进行初始化。 - 在循环中,通过
ADC_RegularChannelConfig配置ADC通道,启动软件转换并等待转换完成,获取转换值存入数组。 - 根据三个传感器的值判断小车的偏向。如果左边传感器值最大,说明小车偏右,通过
TIMSetCompare1和TIMSetCompare2设置左右电机PWM占空比,使小车向左调整;同理右边传感器值最大时,小车向左偏,进行相应调整;当中间传感器值最大,说明小车在赛道中间,设置左右电机相同的PWM占空比,使小车直线行驶。
四、总结
通过上述的原理图、PCB设计以及代码实现,我们就可以打造出一辆基于STM32C8T6的电磁寻迹小车。当然,实际应用中还可以进一步优化代码和硬件设计,比如采用更复杂的算法提高寻迹精度,优化PCB布局减少干扰等。希望这篇博文能给对电磁寻迹小车感兴趣的朋友一些帮助。