一、描述你遇到的问题
之前单独编写了motor.c的程序,电机可以转动,但是现在换成在main函数集合后就没反应了
二、你具体做的所有步骤结果截图
## ###### # 先是main.c
#include "cmsis_os2.h"
#include "app_init.h"
#include "osal_debug.h"
#include "encoder.h"
/* ----- 任务参数宏定义 ----- */
#define MOTOR_TASK_STACK_SIZE 0x800
#define MOTOR_TASK_PRIO (osPriority_t)(osPriorityNormal)
#define ENCODER_TASK_STACK_SIZE 0x1000
#define ENCODER_TASK_PRIO (osPriority_t)(osPriorityAboveNormal)
// 放在 #include 之后,car_entry 之前
extern void *motor_task(const char *arg);
/* ----- 应用入口函数 ----- */
static void car_entry(void)
{
osThreadAttr_t attr;
/* 创建电机控制任务 */
attr.name = "MotorTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = MOTOR_TASK_STACK_SIZE;
attr.priority = MOTOR_TASK_PRIO;
if (osThreadNew((osThreadFunc_t)motor_task, NULL, &attr) == NULL) {
osal_printk("Failed to create MotorTask!\r\n");
}
/* 创建编码器读取任务 */
attr.name = "EncoderTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = ENCODER_TASK_STACK_SIZE;
attr.priority = ENCODER_TASK_PRIO;
if (osThreadNew((osThreadFunc_t)encoder_task, NULL, &attr) == NULL) {
osal_printk("Failed to create EncoderTask!\r\n");
}
}
/* 启动入口 */
app_run(car_entry);
### 下面是motor.c
#include "pinctrl.h"
#include "gpio.h"
#include "pwm.h"
#include "osal_debug.h"
#include "cmsis_os2.h"
#include "app_init.h"
#include "tcxo.h"
/* ----- 引脚定义 ----- */
// 电机A (左轮)
#define PWMA_PIN 0 // PWM引脚,控制速度
#define AIN1_PIN 10 // GPIO,控制方向
#define AIN2_PIN 9 // GPIO,控制方向
// 电机B (右轮)
#define PWMB_PIN 1 // PWM引脚,控制速度
#define BIN1_PIN 11 // GPIO,控制方向
#define BIN2_PIN 12 // GPIO,控制方向
// 注意:TB6612的STBY引脚需要接高电平,这里假设硬件上已接到3.3V
/* ----- PWM配置 ----- */
// 电机A PWM配置
#define PWM_CHANNEL_A 0
#define PWM_CHANNEL_B 1
#define PWM_GROUP_ID 0
pwm_config_t pwm_cfg_a = {
100, // 低电平时间
400, // 高电平时间 (占空比 80%)
0, 0, false // false表示连续输出
};
// 电机B PWM配置 (可根据需要调整速度)
pwm_config_t pwm_cfg_b = {
100, // 低电平时间
400, // 高电平时间 (占空比 80%)
0, 0, false
};
/* ----- 初始化GPIO ----- */
static void gpio_init(void)
{
// 将GPIO引脚设为普通GPIO模式 (PIN_MODE_0)
uapi_pin_set_mode(AIN1_PIN, PIN_MODE_0);
uapi_pin_set_mode(AIN2_PIN, PIN_MODE_0);
uapi_pin_set_mode(BIN1_PIN, PIN_MODE_0);
uapi_pin_set_mode(BIN2_PIN, PIN_MODE_0);
// 设置为输出方向
uapi_gpio_set_dir(AIN1_PIN, GPIO_DIRECTION_OUTPUT);
uapi_gpio_set_dir(AIN2_PIN, GPIO_DIRECTION_OUTPUT);
uapi_gpio_set_dir(BIN1_PIN, GPIO_DIRECTION_OUTPUT);
uapi_gpio_set_dir(BIN2_PIN, GPIO_DIRECTION_OUTPUT);
}
/* ----- 初始化PWM ----- */
static void pwm_init(void)
{
// 将PWM引脚设为PWM功能 (假设PIN_MODE_1对应PWM)
uapi_pin_set_mode(PWMA_PIN, PIN_MODE_1);
uapi_pin_set_mode(PWMB_PIN, PIN_MODE_1);
// 初始化PWM模块
uapi_pwm_init();
// 打开两个PWM通道
uapi_pwm_open(PWM_CHANNEL_A, &pwm_cfg_a);
uapi_pwm_open(PWM_CHANNEL_B, &pwm_cfg_b);
}
/* ----- 设置小车向前行驶 ----- */
static void car_forward(void)
{
// 电机A (左轮) - 正转
uapi_gpio_set_val(AIN1_PIN, GPIO_LEVEL_HIGH);
uapi_gpio_set_val(AIN2_PIN, GPIO_LEVEL_LOW);
// 电机B (右轮) - 正转
uapi_gpio_set_val(BIN1_PIN, GPIO_LEVEL_HIGH);
uapi_gpio_set_val(BIN2_PIN, GPIO_LEVEL_LOW);
// 启动PWM组 (同时启动两个电机)
uint8_t channels[] = {PWM_CHANNEL_A, PWM_CHANNEL_B};
uapi_pwm_set_group(PWM_GROUP_ID, channels, 2);
uapi_pwm_start_group(PWM_GROUP_ID);
osal_printk("Car moving forward!\r\n");
}
/* ----- 主任务 ----- */
void *motor_task(const char *arg)
{
UNUSED(arg);
gpio_init(); // 初始化GPIO
pwm_init(); // 初始化PWM
car_forward(); // 小车向前行驶
while (1) {
uapi_tcxo_delay_ms(1000);
}
return NULL;
}
### 这里encoder空转
#include "encoder.h"
#include "osal_debug.h"
#include "tcxo.h"
#include <stddef.h> // 提供 NULL 定义
#include "encoder.h" // 你自己的编码器头文件
void *encoder_task(void *arg)
{
// 这里可以留空或加个打印
osal_printk("[Encoder] Task started, waiting for implementation...\r\n");
while (1) {
uapi_tcxo_delay_ms(1000);
}
return NULL;
}encoder还有个头文件我就不放了。
三、当前开发板状态全景照片
用电表测过了,没问题
四、开发板串口所有日志
然后是CMAKELISTS.txt的
set(SOURCES_LIST
${CMAKE_CURRENT_SOURCE_DIR}/motor.c
${CMAKE_CURRENT_SOURCE_DIR}/encoder.c
${CMAKE_CURRENT_SOURCE_DIR}/main.c
)
set(PUBLIC_HEADER_LIST
${CMAKE_CURRENT_SOURCE_DIR}
)
set(SOURCES "${SOURCES_LIST}" PARENT_SCOPE)
set(PUBLIC_HEADER "${PUBLIC_HEADER_LIST}" PARENT_SCOPE)