基于GD32的电磁组智能车循迹代码
时间: 2023-07-27 19:06:16 浏览: 257
以下是一个基于 GD32 微控制器的电磁组智能车循迹代码的示例,代码中使用了 PID 控制算法。请注意,这只是一个示例,具体实现可能因车辆硬件配置和算法调试等因素而有所不同。
```c
#include "gd32f10x.h"
/* 定义 PWM 输出引脚 */
#define PWM_PIN TIM_CHANNEL_1
/* 定义电磁组引脚 */
#define EM1_PIN GPIO_PIN_0
#define EM1_PORT GPIOB
#define EM2_PIN GPIO_PIN_1
#define EM2_PORT GPIOB
#define EM3_PIN GPIO_PIN_2
#define EM3_PORT GPIOB
#define EM4_PIN GPIO_PIN_3
#define EM4_PORT GPIOB
/* 定义 PID 控制参数 */
#define KP 0.8f
#define KI 0.05f
#define KD 0.1f
/* 定义电磁组采样值 */
uint16_t em1_val, em2_val, em3_val, em4_val;
/* 定义 PID 控制器变量 */
float error, last_error, integral, derivative, output;
/* 定义 PWM 输出值 */
uint16_t pwm_val = 0;
/* 初始化 PWM 输出 */
void pwm_init(void)
{
/* 定义 GPIO 初始化结构体 */
gpio_init_struct gpio_init;
/* 定义定时器初始化结构体 */
timer_oc_parameter_struct timer_ocinitpara;
/* 使能 PWM 时钟 */
rcu_periph_clock_enable(RCU_TIMER0);
rcu_periph_clock_enable(RCU_AF);
/* 配置 PWM 引脚 */
gpio_init.GPIO_Pin = GPIO_PIN_6;
gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_UP;
gpio_init_struct(GPIOA, &gpio_init);
/* 配置定时器 */
timer_deinit(TIMER0);
timer_oc_struct_para_init(&timer_ocinitpara);
timer_ocinitpara.timer_oc_mode = TIMER_OC_MODE_PWM0;
timer_ocinitpara.timer_output_state = TIMER_CCX_ENABLE;
timer_ocinitpara.timer_output_nstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.timer_oc_polarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.timer_oc_npolarity = TIMER_OCNP_POLARITY_HIGH;
timer_ocinitpara.timer_oc_idle_state = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.timer_oc_nidle_state = TIMER_OCN_IDLE_STATE_HIGH;
timer_channel_output_config(TIMER0, PWM_PIN, &timer_ocinitpara);
/* 配置 PWM 周期 */
timer_auto_reload_value_config(TIMER0, 999);
/* 配置 PWM 初始占空比 */
timer_channel_output_pulse_value_config(TIMER0, PWM_PIN, pwm_val);
/* 使能定时器 */
timer_enable(TIMER0);
}
/* 初始化电磁组采样引脚 */
void em_init(void)
{
/* 定义 GPIO 初始化结构体 */
gpio_init_struct gpio_init;
/* 使能 GPIO 时钟 */
rcu_periph_clock_enable(RCU_GPIOB);
/* 配置电磁组引脚为输入 */
gpio_init.GPIO_Pin = EM1_PIN | EM2_PIN | EM3_PIN | EM4_PIN;
gpio_init.GPIO_Mode = GPIO_Mode_IPU;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_PuPd = GPIO_PuPd_UP;
gpio_init_struct(EM1_PORT, &gpio_init);
gpio_init_struct(EM2_PORT, &gpio_init);
gpio_init_struct(EM3_PORT, &gpio_init);
gpio_init_struct(EM4_PORT, &gpio_init);
}
/* 读取电磁组采样值 */
void read_em_value(void)
{
em1_val = gpio_input_bit_get(EM1_PORT, EM1_PIN);
em2_val = gpio_input_bit_get(EM2_PORT, EM2_PIN);
em3_val = gpio_input_bit_get(EM3_PORT, EM3_PIN);
em4_val = gpio_input_bit_get(EM4_PORT, EM4_PIN);
}
/* PID 控制器 */
void pid_control(void)
{
/* 计算误差 */
error = (em1_val + em2_val - em3_val - em4_val) / 2.0f;
/* 计算积分项 */
integral += error;
/* 计算微分项 */
derivative = error - last_error;
/* 计算 PID 输出 */
output = KP * error + KI * integral + KD * derivative;
/* 更新 PWM 输出值 */
pwm_val += output;
/* 限制 PWM 输出值在 0 到 999 之间 */
if (pwm_val > 999) {
pwm_val = 999;
} else if (pwm_val < 0) {
pwm_val = 0;
}
/* 更新上一次误差值 */
last_error = error;
}
int main(void)
{
/* 初始化 PWM 输出 */
pwm_init();
/* 初始化电磁组采样引脚 */
em_init();
while (1) {
/* 读取电磁组采样值 */
read_em_value();
/* PID 控制 */
pid_control();
/* 更新 PWM 输出占空比 */
timer_channel_output_pulse_value_config(TIMER0, PWM_PIN, pwm_val);
}
}
```
以上代码中,`pwm_init()` 函数用于初始化 PWM 输出,`em_init()` 函数用于初始化电磁组采样引脚,`read_em_value()` 函数用于读取电磁组采样值,`pid_control()` 函数用于实现 PID 控制器。在主函数中,循环读取电磁组采样值,并使用 PID 控制器计算 PWM 输出占空比,最后更新 PWM 输出占空比。
阅读全文