#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "beep.h" #include "key.h" #include "motor_driver.h" //ALIENTEK 探索者STM32F407开发板 实验4 //串口通信实验 -库函数版本 //技术支持:www.openedv.com //淘宝店铺:http://eboard.taobao.com //广州市星翼电子科技有限公司 //作者:正点原子 @ALIENTEK void MX_TIM2_Init(void); //void PWM_SetPulseWidth(uint16_t pulseWidth); //void PWM_SetSpeed(int16_t speed); void Error_Handler(void); typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; // 定义TMC2240寄存器地址 #define REG_MICROSTEPS 0x03 #define REG_CURRENT 0x05 #define EG_STATUS 0x0F extern volatile u16 rx_len; // 接收计数 extern volatile u8 rx_flag; // 接收完成标志 #define GCONF 0x00 #define IHOLD_IRUN 0x10 #define TPOWERDOWN 0x11 #define TPWMTHRS 0x13 #define TCOOLTHRS 0x14 #define CHOPCONF 0x6C #define COOLCONF 0x6D #define DRV_CONF 0x0A #define DRV_STATUS 0x6F #define PWMCONF 0x70 #define SOFT_SPI_DR_PORT GPIOD #define SOFT_SPI_DR_PIN GPIO_Pin_3 //forward and reverse #define D3_DR_forward() GPIO_SetBits(SOFT_SPI_DR_PORT, SOFT_SPI_DR_PIN) #define D3_DR_reverse() GPIO_ResetBits(SOFT_SPI_DR_PORT, SOFT_SPI_DR_PIN) void TMC2240_Init_rotating() { // 启用电压补偿和PWM模式 TMC2240_WriteReg(GCONF, 0x000000C4); // 电流设置:IHOLD=0.5A, IRUN=1.2A TMC2240_WriteReg(IHOLD_IRUN, 0x00180C10); // 16微步(MRES=4),TOFF=3 TMC2240_WriteReg(CHOPCONF, 0x030000C3); // 设置速度阈值500Hz(低于此值切StealthChop2) TMC2240_WriteReg(TPWMTHRS, 200); // 驱动配置(根据需求调整) TMC2240_WriteReg(DRV_CONF, 0x00000001); // 停机电流延时 TMC2240_WriteReg(TPOWERDOWN, 10); } void TMC2240_Init() { // 启用StealthChop2自动调谐 + SpreadCycle动态切换 TMC2240_WriteReg(GCONF, 0x000000C4 | (1 << 7)); // bit7=1 // 电流设置:IRUN=1.2A, IHOLD=0.8A(公式计算值) //TMC2240_WriteReg(IHOLD_IRUN, 0x00190C10); TMC2240_WriteReg(IHOLD_IRUN, 0x04090101); //可能运行电流太大,发热,这里调小试试 // 降低微步分辨率(例如从256微步改为16微步) TMC2240_WriteReg(CHOPCONF, 0x070080C3 ); // MRES=4(16微步) // 设置速度阈值500Hz(低于此值切StealthChop2) TMC2240_WriteReg(TPWMTHRS, 50); // 其他配置保持不变 TMC2240_WriteReg(DRV_CONF, 0x00000001); TMC2240_WriteReg(TPOWERDOWN, 10); } // 检查驱动器状态 void CheckDriverStatus() { uint32_t status = TMC2240_ReadReg(DRV_STATUS);// if (status & (1 << 26)) { // 检查短路到地 printf("Short to ground detected\n"); } if (status & (1 << 25)) { // 检查过温 printf("Overtemperature detected\n"); } if (status & (1 << 24)) { // 检查失速 printf("Motor stall detected\n"); } } void motor_steps(uint8_t num, uint8_t dir, uint16_t steps) { GPIO_SetBits(GPIOD, GPIO_Pin_4); //TMS2240 - 2使能信号 delay_us(steps); GPIO_ResetBits(GPIOD, GPIO_Pin_4); //TMS2240 - 1使能信号 } void motor_stop(uint8_t num) { } uint8_t crc8_calculate(const uint8_t *data, uint32_t length, uint8_t poly, uint8_t init_val, uint8_t ref_out) { // 1. 初始化 CRC 寄存器 uint8_t crc = init_val; // 2. 遍历每个字节 for (uint32_t i = 0; i < length; i++) { // 3. 将当前字节与 CRC 寄存器异或(核心步骤) crc ^= data[i]; // 4. 遍历当前字节的每一位(8 位) for (uint8_t j = 0; j < 8; j++) { // 5. 判断最高位是否为 1,决定是否异或多项式 if (crc & 0x80) { // 左移 1 位,再异或多项式(等价于多项式除法) crc = (crc << 1) ^ poly; } else { // 最高位为 0,仅左移 1 位 crc <<= 1; } } } // 6. 输出反转(若需要) if (ref_out) { // 按位反转 CRC 结果(如 0x12 → 0x48) uint8_t reversed = 0; for (uint8_t i = 0; i < 8; i++) { reversed |= ((crc >> i) & 0x01) << (7 - i); } crc = reversed; } return crc; } uint8_t crc8_standard(const uint8_t *data, uint32_t length) { // 适配 CRC-8/MAXIM/ITU 标准:poly=0x07, init=0x00, ref_out=0 return crc8_calculate(data, length, 0x07, 0x00, 0); } uint32_t status ; u8 flg=0; extern int flag_microswitch_left; // 光电开关left 限位 extern int flag_microswitch_right; // 光电开关right 限位 extern uint8_t g_usart1_rx_buf[USART_REC_LEN]; extern uint16_t g_usart1_rx_sta; extern uint16_t g_usart1_rx_state; extern uint8_t g_usart2_rx_buf[USART_REC_LEN]; extern uint16_t g_usart2_rx_sta; extern uint16_t g_usart2_rx_state; extern uint8_t g_usart3_rx_buf[USART_REC_LEN]; extern uint16_t g_usart3_rx_sta; extern uint16_t g_usart3_rx_state; extern uint8_t g_rx1_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ /* 接收缓冲, 最大USART_REC_LEN个字节. */ extern uint8_t g_usart2_rx_buf[USART_REC_LEN]; extern uint16_t g_usart2_rx_sta; extern uint8_t g_rx2_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ /* 接收缓冲, 最大USART_REC_LEN个字节. */ extern uint8_t g_usart3_rx_buf[USART_REC_LEN]; extern uint16_t g_usart3_rx_sta; extern uint8_t g_rx3_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ /* 接收缓冲, 最大USART_REC_LEN个字节. */ extern uint8_t g_usart4_rx_buf[USART_REC_LEN]; extern uint16_t g_usart4_rx_sta; extern uint8_t g_rx4_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ /* 接收缓冲, 最大USART_REC_LEN个字节. */ extern uint8_t g_usart5_rx_buf[USART_REC_LEN]; extern uint16_t g_usart5_rx_sta; extern uint8_t g_rx5_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ /* 接收缓冲, 最大USART_REC_LEN个字节. */ extern uint8_t g_usart6_rx_buf[USART_REC_LEN]; extern uint16_t g_usart6_rx_sta; extern uint8_t g_rx6_buffer[RXBUFFERSIZE]; /* HAL库使用的串口接收缓冲 */ int main(void) { u8 t; u8 len; u16 times=0; uint8_t frame_updata[6] = {0x30,0x30,0x30,0x30,0x30,0x30}; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //延时初始化 uart1_init(115200); //串口1初始化波特率为115200 手指左 uart2_init(115200); //串口1初始化波特率为115200 手指中 uart3_init(115200); //串口1初始化波特率为115200 手指右 uart4_init(115200); //串口1初始化波特率为115200 用于信息打印 uart5_init(115200); uart6_init(115200); //串口6初始化波特率为115200 上传到slide gpio_Init(); //初始化gpio motor_spi1_init(); motor_spi2_init(); TIM1_PWM_Init(16, 32); //TIM2_PWM_Init(16, 32); TIM4_PWM_Init(16, 32); TIM_Cmd(TIM1, DISABLE); //TIM_Cmd(TIM2, DISABLE); TIM_Cmd(TIM4, DISABLE); //--------------------------------------------- // 初始化DRV8832电机驱动 DRV8832_Init(); // 初始化PWM定时器(如果需要调速) PWM_Timer_Init(); // 使能全局中断 __enable_irq(); //======================================================================= while(0) { // 示例1:基本控制(全速正反转) Motor_Control(MOTOR_FORWARD); // 正转 delay_ms(5000); Motor_SafeDirectionChange(MOTOR_REVERSE); // 安全切换到反转 delay_ms(5000); Motor_Control(MOTOR_BRAKE); // 刹车 delay_ms(500); Motor_Control(MOTOR_STOP); // 停止(滑行) delay_ms(1000); // 示例2:PWM调速演示 // 正转加速 // for(uint8_t speed = 0; speed <= 100; speed += 10) { // Motor_SetSpeed(speed, MOTOR_FORWARD); // delay_ms(200); // } // delay_ms(2000); // // // 正转减速 // for(uint8_t speed = 100; speed > 0; speed -= 10) { // Motor_SetSpeed(speed, MOTOR_FORWARD); // delay_ms(200); // } // Motor_SetSpeed(0, MOTOR_STOP); // delay_ms(1000); // 检查故障状态 if(Motor_GetFaultStatus()) { // 发生故障,停止电机 Motor_Control(MOTOR_STOP); // 可以添加故障处理代码,如闪烁LED或串口输出 // ... // 等待故障清除 while(Motor_GetFaultStatus()) { delay_ms(100); } } } //======================================================================= while(1) { printf("I love you lao zhang\n"); delay_ms(300); printf("I love you zhengshuo\n"); delay_ms(300); Uart5_Send_data(frame_updata,6); //------------------------------------------------- if(g_usart1_rx_state == 1) { // g_usart1_rx_buf[1] = 0x01; // g_usart1_rx_buf[3] = 0x34; // g_usart1_rx_buf[4] = crc8_standard(g_usart1_rx_buf,4); g_usart1_rx_state = 0; memcpy(frame_updata,g_usart1_rx_buf,6 ); memset(g_usart1_rx_buf, 0x0, 6); g_rx1_buffer[0] = 0x0; Uart6_Send_data(frame_updata,6); } if(g_usart2_rx_state == 1) { // g_usart1_rx_buf[1] = 0x01; // g_usart1_rx_buf[3] = 0x34; // g_usart1_rx_buf[4] = crc8_standard(g_usart1_rx_buf,4); g_usart2_rx_state = 0; memcpy(frame_updata,g_usart2_rx_buf,6 ); memset(g_usart2_rx_buf, 0x0, 6); g_rx2_buffer[0] = 0x0; Uart6_Send_data(frame_updata,6); } if(g_usart3_rx_state == 1) { // g_usart1_rx_buf[1] = 0x01; // g_usart1_rx_buf[3] = 0x34; // g_usart1_rx_buf[4] = crc8_standard(g_usart1_rx_buf,4); g_usart3_rx_state = 0; memcpy(frame_updata,g_usart3_rx_buf,6 ); memset(g_usart3_rx_buf, 0x0, 6); g_rx3_buffer[0] = 0x0; Uart6_Send_data(frame_updata,6); } //------------------------------------------------- // if(USART_RX_STA&0x8000) // { // len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 // printf("\r\n您发送的消息为:\r\n"); // for(t=0;t