其他学习
光立方
- 硬件
STM32F103C8T6
4个SG90舵机
4路继电器
一个超声波
- MX配置
- 程序编写
AllHead.h
cpp
#ifndef __ALLHEAD_H
#define __ALLHEAD_H
#include "main.h"
#include "dma.h"
#include "iwdg.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "CallBack.h"
#include "Public.h"
#include "System.h"
#include "System_Init.h"
# include <string.h>
# include <stdarg.h>
# include <stdlib.h>
# include "stdio.h"
#include "stdint.h"
#include "math.h"
#include "Steer.h"
#include "ultrasound.h"
#include "Pwm_Led.h"
#include "IW_Dog.h"
#include "Relay.h"
#include "Voice.h"
#include "BlueTooth.h"
#include "Task.h"
#endif
Task.c
cpp
/***************************************************************************
* File: Task.c
* Author: Luckys.
* Date: 2023/06/23
* description:
****************************************************************************/
#include "AllHead.h"
/*====================================static function declaration area BEGIN====================================*/
static void TasksHandle_30MS(void);
static void TasksHandle_50MS(void);
static void TasksHandle_100MS(void);
static void TasksHandle_150MS(void);
static void TasksHandle_1S(void);
static void TasksHandle_1500MS(void);
/*====================================static function declaration area END====================================*/
Task_t Task[] =
{
{FALSE, 30, 30, TasksHandle_30MS}, // task Period: 10ms
{FALSE, 50, 50, TasksHandle_50MS}, // task Period: 50ms
{FALSE, 100, 100, TasksHandle_100MS}, // task Period: 100ms
{FALSE, 150, 150, TasksHandle_150MS}, // task Period: 150ms
{FALSE, 1000, 1000, TasksHandle_1S}, // task Period: 1s
{FALSE, 1500, 1500, TasksHandle_1500MS}, // task Period: 1.5s
};
/*====================================variable definition declaration area BEGIN===================================*/
//
uint8_t ucTasks_Max = sizeof(Task) / sizeof(Task[0]);
/*====================================variable definition declaration area END===================================*/
static void TasksHandle_30MS(void)
{
// 【呼吸灯1】
if (TRUE == Voice.Pwm_Led_Flag_Buf[LED1])
{
Pwm_Led.Pwm_Led_Breathing(LED1);
}
else
{
Pwm_Led.Pwm_Led_Duty_Control(LED1, 101); // 常亮
}
// 【呼吸灯2】
if (TRUE == Voice.Pwm_Led_Flag_Buf[LED2])
{
Pwm_Led.Pwm_Led_Breathing(LED2);
}
else
{
Pwm_Led.Pwm_Led_Duty_Control(LED2, 101); // 常亮
}
// 【呼吸灯3】
if (TRUE == Voice.Pwm_Led_Flag_Buf[LED3])
{
Pwm_Led.Pwm_Led_Breathing(LED3);
}
else
{
Pwm_Led.Pwm_Led_Duty_Control(LED3, 101); // 常亮
}
// 【呼吸灯4】
if (TRUE == Voice.Pwm_Led_Flag_Buf[LED4])
{
Pwm_Led.Pwm_Led_Breathing(LED4);
}
else
{
Pwm_Led.Pwm_Led_Duty_Control(LED4, 101); // 常亮
}
}
static void TasksHandle_50MS(void)
{
HAL_GPIO_TogglePin(SYS_LED_GPIO_Port, SYS_LED_Pin); // 系统灯运行
}
static void TasksHandle_100MS(void)
{
ultrasound.ultrasound_Get_Value(); // 超声波读取值
}
static void TasksHandle_150MS(void)
{
if (TRUE == Voice.Steer_Auto_Flag) // 启动鲜花全自动
{
ultrasound.ultrasound_Handler(); // 超声波处理函数
}
}
static void TasksHandle_1S(void)
{
if (TRUE == Voice.Steer_Auto_Flag) // 启动鲜花全自动
{
Steer.Steer_Handler(); // 舵机处理函数
}
else
{
__Steer_Reset(); // 舵机复位
}
}
static void TasksHandle_1500MS(void)
{
IW_Dog.IW_Dog_Feed(); // 喂狗
}System_Init.c
cpp
/***************************************************************************
* File: System_Init.c
* Author: Luckys.
* Date: 2023/06/23
* description: 存放系统初始化
****************************************************************************/
#include "AllHead.h"
/*====================================static function declaration area BEGIN====================================*/
static void Hardware_Init(void);
/*====================================static function declaration area END====================================*/
System_Init_t System_Init =
{
Hardware_Init
};
/*
* @function: Hardware_Init
* @param: None
* @retval: None
* @brief: 硬件初始化
*/
static void Hardware_Init(void)
{
IW_Dog.IW_Dog_Init(); // 看门狗初始化
Relay.Relay_Init(); // 继电器初始化
Steer.Steer_Init(); // 舵机初始化
Pwm_Led.Pwm_Led_Init(); // PWM灯带初始化
Voice.Voice_Init(); // ASR初始化
BlueTooth.BlueTooth_Init(); // 蓝牙初始化
HAL_TIM_Base_Start_IT(&htim3); // 任务调度定时器
BlueTooth.BlueTooth_Send_Data((uint8_t*)"Init OK\r\n", strlen("Init OK\r\n"));
}
System.c
cpp
/***************************************************************************
* File: System.c
* Author: Luckys.
* Date: 2023/06/23
* description:
****************************************************************************/
#include "AllHead.h"
/*====================================static function declaration area BEGIN====================================*/
static void Run(void);
static void SysTem_Func_Fail_Handler(void);
static void System_Assert_Fail_Handler(void);
static void Task_Marks_Handler(void);
static void Task_Pro_Handler(void);
/*====================================static function declaration area END====================================*/
System_t System =
{
Run,
SysTem_Func_Fail_Handler,
System_Assert_Fail_Handler,
Task_Marks_Handler
};
/*
* @function: Run
* @param: None
* @retval: None
* @brief:
*/
static void Run(void)
{
Task_Pro_Handler(); //
}
/*
* @function: SysTem_Func_Fail_Handler
* @param: None
* @retval: None
* @brief:
*/
static void SysTem_Func_Fail_Handler(void)
{
}
/*
* @function: System_Assert_Fail_Handler
* @param: None
* @retval: None
* @brief:
*/
static void System_Assert_Fail_Handler(void)
{
}
/*
* @function: Task_Marks_Handler
* @param: None
* @retval: None
* @brief:
*/
static void Task_Marks_Handler(void)
{
uint8_t i;
for (i = 0; i < ucTasks_Max; i++)
{
if (Task[i].Task_Cnt) //
{
Task[i].Task_Cnt--; //
if (0 == Task[i].Task_Cnt) //
{
Task[i].Task_Cnt = Task[i].Task_Timer; //
Task[i].Run_Status = TRUE; //
}
}
}
}
/*
* @function: Task_Pro_Handler
* @param: None
* @retval: None
* @brief:
*/
static void Task_Pro_Handler(void)
{
uint8_t i;
for (i = 0; i < ucTasks_Max; i++)
{
if (Task[i].Run_Status) //
{
Task[i].Run_Status = FALSE;
Task[i].Task_Hook(); //
}
}
}
Public.c
cpp
/***************************************************************************
* File: Public.c
* Author: Luckys.
* Date: 2023/06/23
* description: 存放通用
-----------------------------------
上位机通信选择USART3
PB10(TX)
PB11(RX)
-----------------------------------
****************************************************************************/
#include "AllHead.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
/*====================================static function declaration area BEGIN====================================*/
static void Memory_Clear(uint8_t*, uint16_t);
static void Public_Delay_ms(uint16_t);
static void Public_Delay_us(uint16_t);
static void Memory_Copy(char*, const char*, uint16_t);
/*====================================static function declaration area END====================================*/
Public_t Public =
{
Memory_Clear,
Public_Delay_ms,
Public_Delay_us,
Memory_Copy
};
/*
* @function: Memory_Clear
* @param: pucBuffer -> 内存首地址 LEN -> 内存长度
* @retval: None
* @brief: 描述
*/
static inline void Memory_Clear(uint8_t* pucBuffer, uint16_t LEN)
{
uint16_t i;
for (i = 0; i < LEN; i++)
{
*(pucBuffer + i) = (uint8_t)0;
}
}
/*
* @function: Public_Delay_ms
* @param: ms -> 需要延时的时间(ms)
* @retval: None
* @brief: 系统ms延时
*/
static void Public_Delay_ms(uint16_t ms)
{
HAL_Delay(ms);
}
/*
* @function: Public_Delay_us
* @param: us -> 需要延时的时间(us)
* @retval: None
* @brief: 系统us延时
*/
static void Public_Delay_us(uint16_t us)
{
uint8_t i;
// 通过示波器测量进行校准
while(us--)
{
for (i = 0; i < 7; i++);
}
}
/*
* @function: Memory_Copy
* @param: dest -> 要复制到的指针地址 src -> 被复制的指针地址 count -> 大小(数组用sizeof 字符串用strlen)
* @retval: None
* @brief: 复制固定长度数组/字符串
*/
static inline void Memory_Copy(char* dest, const char* src, uint16_t count)
{
uint16_t i;
for (i = 0; i < count; i++)
{
dest[i] = src[i];
}
}
#if 0
// 重定向
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 0x0A);
return ch;
}
#endif
CallBack.c
cpp
/***************************************************************************
* File: CallBack.c
* Author: Luckys.
* Date: 2023/06/19
* description: 存放中断函数
****************************************************************************/
#include "AllHead.h"
/*
* @function: HAL_TIM_PeriodElapsedCallback
* @param: htim -> 处理定时器的结构体指针
* @retval: None
* @brief: 定时器回调函数
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim3.Instance)
{
System.Task_Marks_Handler(); // 任务标记
}
}
/*
* @function: xxx
* @param: None
* @retval: None
* @brief: 输入捕获回调函数
*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
switch(ultrasound.Run_Status)
{
case 1:
{
ultrasound.Timer_Cnt_Buf[0] = TIM2->CCR1; // 获取计数值
__HAL_TIM_SET_CAPTUREPOLARITY(Ultrasound_Timer, Ultrasound_Channel, TIM_INPUTCHANNELPOLARITY_FALLING); // 下降沿触发
ultrasound.Run_Status++;
break;
}
case 2:
{
ultrasound.Timer_Cnt_Buf[1] = TIM2->CCR1; // 获取计数值
HAL_TIM_IC_Stop_IT(Ultrasound_Timer, Ultrasound_Channel); // 停止捕获
ultrasound.Run_Status++;
break;
}
}
}
}
/*
* @function: USART2_IRQHandler
* @param: None
* @retval: None
* @brief: 串口2中断服务函数(语音)
*/
void USART2_IRQHandler(void)
{
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != 0x00)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2); // 清除标志位
Voice.Voice_Protocol(); // 协议解析
}
HAL_UART_IRQHandler(&huart2);
}
void USART3_IRQHandler(void)
{
if (__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE) != 0x00u) // 判断是否发生空闲中断
{
__HAL_UART_CLEAR_IDLEFLAG(&huart3); // 清除空闲中断标志位
HAL_UART_DMAStop(&huart3); // 停止DMA接收
BlueTooth.BlueTooth_Analyze(); // 数据解析
}
HAL_UART_IRQHandler(&huart3);
}BlueTooth.h
cpp
#ifndef __BLUETOOTH_H
#define __BLUETOOTH_H
// 接收缓存最大值
#define BlueTooth_REC_MAX_LEN 66
// 使用串口
#define BLUE_TOOTH_USE_UART huart3
typedef struct
{
uint8_t *BlueTooth_Rec_Buffer; // 串口3接收缓存数组指针
void (*BlueTooth_Init)(void); // 串口3初始化
void (*BlueTooth_Send_Data)(uint8_t *, uint16_t); // 串口3发送数据函数
void (*BlueTooth_Analyze)(void);
} BlueTooth_st;
extern BlueTooth_st BlueTooth;
#endifBlueTooth.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
蓝牙接线:
PB10(TX) --- 蓝牙RX
PB11(RX) --- 蓝牙TX
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private variables=========================================================*/
uint8_t BlueTooth_Rec_Arr[BlueTooth_REC_MAX_LEN] = {0}; // 定义一个接收数组
/* Private function prototypes===============================================*/
static void BlueTooth_Init(void);
static void BlueTooth_Analyze(void);
static void BlueTooth_Send_Data(uint8_t *str, uint16_t len);
/* Public variables==========================================================*/
BlueTooth_st BlueTooth =
{
.BlueTooth_Rec_Buffer = BlueTooth_Rec_Arr,
.BlueTooth_Init = &BlueTooth_Init,
.BlueTooth_Send_Data = &BlueTooth_Send_Data,
.BlueTooth_Analyze = &BlueTooth_Analyze
};
/*
* @function: BlueTooth_Init
* @param: None
* @retval: None
* @brief: 串口3初始化
*/
static void BlueTooth_Init(void)
{
__HAL_UART_ENABLE_IT(&BLUE_TOOTH_USE_UART, UART_IT_IDLE); // 使能串口3空闲中断
HAL_UART_Receive_DMA(&BLUE_TOOTH_USE_UART, BlueTooth.BlueTooth_Rec_Buffer, BlueTooth_REC_MAX_LEN); // 使能串口3DMA接收
}
/*
* @function: BlueTooth_Send_Data
* @param: None
* @retval: None
* @brief: 串口3发送数据函数
*/
static void BlueTooth_Send_Data(uint8_t *str, uint16_t len)
{
HAL_UART_Transmit(&BLUE_TOOTH_USE_UART, str, len, 0x0A);
}
/*
* @function: BlueTooth_Analyze
* @param: None
* @retval: None
* @brief: 数据解析
*/
static void BlueTooth_Analyze(void)
{
if (strncmp((char *)BlueTooth.BlueTooth_Rec_Buffer, "Ctrl_LED1", strlen("Ctrl_LED1")) == 0)
{
static uint8_t flag1 = RELAY_OFF;
flag1 = !flag1;
Relay.Relay_Control(RELAY_A, flag1);
}
else if (strncmp((char *)BlueTooth.BlueTooth_Rec_Buffer, "Ctrl_LED2", strlen("Ctrl_LED2")) == 0)
{
static uint8_t flag2 = RELAY_OFF;
flag2 = !flag2;
Relay.Relay_Control(RELAY_B, flag2);
}
else if (strncmp((char *)BlueTooth.BlueTooth_Rec_Buffer, "Ctrl_LED3", strlen("Ctrl_LED3")) == 0)
{
static uint8_t flag3 = RELAY_OFF;
flag3 = !flag3;
Relay.Relay_Control(RELAY_C, flag3);
}
else if (strncmp((char *)BlueTooth.BlueTooth_Rec_Buffer, "Ctrl_LED4", strlen("Ctrl_LED4")) == 0)
{
static uint8_t flag4 = RELAY_OFF;
flag4 = !flag4;
Relay.Relay_Control(RELAY_D, flag4);
}
memset(BlueTooth.BlueTooth_Rec_Buffer, 0, strlen((char*)BlueTooth.BlueTooth_Rec_Buffer)); // 数组清0
HAL_UART_Receive_DMA(&BLUE_TOOTH_USE_UART, BlueTooth.BlueTooth_Rec_Buffer, BlueTooth_REC_MAX_LEN); // 使能串口3DMA接收
}Voice.h
cpp
#ifndef __VOICE_H
#define __VOICE_H
// ASR串口
#define huart_ASR huart2
// 串口接收最大长度
#define Voice_Rec_Buffer_LENGTH (uint8_t)20
// 协议长度是4个字节
#define Protocol_Data_LEN (uint8_t)4
// 定义结构体类型
typedef struct
{
uint8_t Steer_Auto_Flag; // 鲜花复位/全自动标志位
uint8_t Steer_Switch_Closure_Flag; // 启动/取消自动闭合
uint8_t Pwm_Led_Flag_Buf[4]; // 打开/关闭呼吸灯标志位数组
uint8_t ucVoice_EndData[4]; // 语音接收有效协议数组
uint8_t* pucRec_Buffer; // 接收缓存
void (*Voice_Init)(void); // ASR初始化
void (*Voice_SendString)(uint8_t*); // 发送字符串给ASR
void (*Voice_Protocol)(void); // 接口协议
} Voice_st;
extern Voice_st Voice;
#endifVoice.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
语音模块通信:使用USART2
PA2(TX) ---> 模块RX(PA6)
PA3(RX) ---> 模块TX(PA5)
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private variables=========================================================*/
static uint8_t ucVoice_Rec_Buffer[Voice_Rec_Buffer_LENGTH] = {0x00};
/* Private function prototypes===============================================*/
static void Voice_Init(void);
static void Voice_SendString(uint8_t *str);
static void Voice_Protocol(void);
/* Public variables==========================================================*/
Voice_st Voice =
{
.Steer_Auto_Flag = FALSE,
.Steer_Switch_Closure_Flag = FALSE,
.Pwm_Led_Flag_Buf = {FALSE, FALSE, FALSE, FALSE},
.ucVoice_EndData = {0xFF, 0xFF, 0xFF, 0xFF},
.pucRec_Buffer = ucVoice_Rec_Buffer,
.Voice_Init = &Voice_Init,
.Voice_SendString = &Voice_SendString,
.Voice_Protocol = &Voice_Protocol
};
/*
* @function: Voice_Init
* @param: None
* @retval: None
* @brief: 语音初始化
*/
static void Voice_Init(void)
{
__HAL_UART_ENABLE_IT(&huart_ASR, UART_IT_IDLE); // 使能串口空闲中断
HAL_UART_Receive_DMA(&huart_ASR, Voice.pucRec_Buffer, (uint16_t)Voice_Rec_Buffer_LENGTH); // 使能DMA接收
}
/*
* @function: Voice_SendString
* @param: None
* @retval: None
* @brief: ASR发送字符串
*/
static void Voice_SendString(uint8_t *str)
{
HAL_UART_Transmit(&huart_ASR,str,strlen((const char*)str),100);
}
/*
* @function: Voice_Protocol
* @param: None
* @retval: None
* @brief: 语音协议解析
*/
static void Voice_Protocol(void)
{
uint8_t Temp_Array[4] = {0x00};
uint8_t i = 0, Index = 0;
HAL_UART_DMAStop(&huart_ASR); // 串口停止DMA接收
for (i = 0; i < Voice_Rec_Buffer_LENGTH; i++) //
{
if (0 == Index) // 检测键值起始数据0xAA
{
if (*(Voice.pucRec_Buffer + i) != 0xAA)
{
continue;
}
}
Temp_Array[Index] = *(Voice.pucRec_Buffer + i);
if (Protocol_Data_LEN == Index) // 已读取4字节
{
break;
}
Index++;
}
HAL_UART_Receive_DMA(&huart_ASR, Voice.pucRec_Buffer, (uint16_t)Voice_Rec_Buffer_LENGTH); // 使能DMA接收
// 处理数据
if (Protocol_Data_LEN == Index)
{
if ((0xAA == Temp_Array[0]) && (0xBB == Temp_Array[3])) // 判断帧头、帧尾
{
switch (Temp_Array[1]) // 判断主指令
{
case 0x01: // 【打开/关闭灯带1】
{
if (0x00 == Temp_Array[2])
{
Relay.Relay_Control(RELAY_A, RELAY_ON);
}
else if (0x01 == Temp_Array[2])
{
Relay.Relay_Control(RELAY_A, RELAY_OFF);
}
break;
}
case 0x02: // 【打开/关闭灯带2】
{
if (0x00 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_B, RELAY_ON);
}
else if (0x01 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_B, RELAY_OFF);
}
break;
}
case 0x03: // 【打开/关闭灯带3】
{
if (0x00 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_C, RELAY_ON);
}
else if (0x01 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_C, RELAY_OFF);
}
break;
}
case 0x04: // 【打开/关闭灯带4】
{
if (0x00 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_D, RELAY_ON);
}
else if (0x01 == Temp_Array[2])
{
// Relay.Relay_Control(RELAY_D, RELAY_OFF);
}
break;
}
case 0x05: // 【打开/关闭呼吸灯1】
{
if (0x00 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED1] = TRUE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED1] = FALSE;
}
break;
}
case 0x06: // 【打开/关闭呼吸灯2】
{
if (0x00 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED2] = TRUE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED2] = FALSE;
}
break;
}
case 0x07: // 【打开/关闭呼吸灯3】
{
if (0x00 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED3] = TRUE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED3] = FALSE;
}
break;
}
case 0x08: // 【打开/关闭呼吸灯4】
{
if (0x00 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED4] = TRUE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Pwm_Led_Flag_Buf[LED4] = FALSE;
}
break;
}
case 0x09: // 【启动自动闭合/取消自动闭合】
{
if (0x00 == Temp_Array[2])
{
Voice.Steer_Switch_Closure_Flag = TRUE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Steer_Switch_Closure_Flag = FALSE;
}
break;
}
case 0x0A: // 【鲜花复位/启动鲜花全自动】
{
if (0x00 == Temp_Array[2])
{
Voice.Steer_Auto_Flag = FALSE;
}
else if (0x01 == Temp_Array[2])
{
Voice.Steer_Auto_Flag = TRUE;
}
}
case 0x0B:
{
if (0x00 == Temp_Array[2]) // 打开风扇
{
Relay.Relay_Control(RELAY_B, RELAY_ON);
}
else if (0x01 == Temp_Array[2]) // 关闭风扇
{
Relay.Relay_Control(RELAY_B, RELAY_OFF);
}
break;
}
default:break;
}
}
else
{
return;
}
}
}Relay.h
cpp
#ifndef __RELAY_H
#define __RELAY_H
// 打开全部继电器
#define __Relay_All_ON() do { \
Relay.Relay_Control(RELAY_A, RELAY_ON); \
Relay.Relay_Control(RELAY_B, RELAY_ON); \
Relay.Relay_Control(RELAY_C, RELAY_ON); \
Relay.Relay_Control(RELAY_D, RELAY_ON); \
} while(0)
// 关闭全部继电器
#define __Relay_All_OFF() do { \
Relay.Relay_Control(RELAY_A, RELAY_OFF); \
Relay.Relay_Control(RELAY_B, RELAY_OFF); \
Relay.Relay_Control(RELAY_C, RELAY_OFF); \
Relay.Relay_Control(RELAY_D, RELAY_OFF); \
} while(0)
// 继电器开关状态枚举
typedef enum
{
RELAY_OFF = 0x00,
RELAY_ON = 0x01
} Relay_Switch_Status_et;
// 继电器数量
typedef enum
{
RELAY_A = 0x00,
RELAY_B = 0x01,
RELAY_C = 0x02,
RELAY_D = 0x03
} Relay_Number_et;
typedef struct
{
uint8_t ucRelay_Status_Buf[4]; // 存储继电器当前状态
void (*Relay_Init)(void); // 继电器初始化
void (*Relay_Control)(Relay_Number_et, Relay_Switch_Status_et); // 继电器控制
} Relay_st;
extern Relay_st Relay;
#endifRelay.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
继电器接线:
PA6 --- 继电器A
PA7 --- 继电器B
PB0 --- 继电器C
PB1 --- 继电器D
高电平触发, 3.3V驱动
-----------------------------------
****************************************************************************/
#include "AllHead.h"
//* Private function prototypes===============================================*/
static void Relay_Init(void);
static void Relay_Control(Relay_Number_et Relay_x, Relay_Switch_Status_et status);
/* Public variables==========================================================*/
Relay_st Relay =
{
.ucRelay_Status_Buf = {RELAY_OFF, RELAY_OFF, RELAY_OFF, RELAY_OFF},
.Relay_Init = &Relay_Init,
.Relay_Control = &Relay_Control
};
/*
* @function: Relay_Init
* @param: None
* @retval: None
* @brief: 继电器初始化
*/
static void Relay_Init(void)
{
__Relay_All_OFF(); // 关闭全部继电器
}
/*
* @function: Relay_Control
* @param: None
* @retval: None
* @brief: 继电器控制
*/
static void Relay_Control(Relay_Number_et Relay_x, Relay_Switch_Status_et status)
{
switch (Relay_x)
{
case RELAY_A:
{
if (RELAY_ON == status) // 打开继电器
{
HAL_GPIO_WritePin(Relay_A_GPIO_Port, Relay_A_Pin, GPIO_PIN_SET);
}
else // 关闭继电器
{
HAL_GPIO_WritePin(Relay_A_GPIO_Port, Relay_A_Pin, GPIO_PIN_RESET);
}
Relay.ucRelay_Status_Buf[RELAY_A] = status; // 更新继电器状态
break;
}
case RELAY_B:
{
if (RELAY_ON == status) // 打开继电器
{
HAL_GPIO_WritePin(Relay_B_GPIO_Port, Relay_B_Pin, GPIO_PIN_SET);
}
else // 关闭继电器
{
HAL_GPIO_WritePin(Relay_B_GPIO_Port, Relay_B_Pin, GPIO_PIN_RESET);
}
Relay.ucRelay_Status_Buf[RELAY_B] = status; // 更新继电器状态
break;
}
case RELAY_C:
{
if (RELAY_ON == status) // 打开继电器
{
HAL_GPIO_WritePin(Relay_C_GPIO_Port, Relay_C_Pin, GPIO_PIN_SET);
}
else // 关闭继电器
{
HAL_GPIO_WritePin(Relay_C_GPIO_Port, Relay_C_Pin, GPIO_PIN_RESET);
}
Relay.ucRelay_Status_Buf[RELAY_C] = status; // 更新继电器状态
break;
}
case RELAY_D:
{
if (RELAY_ON == status) // 打开继电器
{
HAL_GPIO_WritePin(Relay_D_GPIO_Port, Relay_D_Pin, GPIO_PIN_SET);
}
else // 关闭继电器
{
HAL_GPIO_WritePin(Relay_D_GPIO_Port, Relay_D_Pin, GPIO_PIN_RESET);
}
Relay.ucRelay_Status_Buf[RELAY_D] = status; // 更新继电器状态
break;
}
default:break;
}
}IW_Dog.h
cpp
#ifndef __IW_DOG_H
#define __IW_DOG_H
typedef struct
{
void (*IW_Dog_Init)(void);
void (*IW_Dog_Feed)(void);
} IW_Dog_st;
extern IW_Dog_st IW_Dog;
#endifIW_Dog.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
独立看门狗,定时2S --- (1/(40000/64)) * x = 2s x = 1250
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private function prototypes===============================================*/
static void IW_Dog_Init(void);
static void IW_Dog_Feed(void);
/* Public variables==========================================================*/
IW_Dog_st IW_Dog =
{
.IW_Dog_Init = &IW_Dog_Init,
.IW_Dog_Feed = &IW_Dog_Feed
};
/*
* @function: IW_Dog_Init
* @param: None
* @retval: None
* @brief: 独立看门狗初始化
*/
static void IW_Dog_Init(void)
{
IW_Dog_Feed();
}
/*
* @function: IW_Dog_Feed
* @param: None
* @retval: None
* @brief: 喂狗
*/
static void IW_Dog_Feed(void)
{
HAL_IWDG_Refresh(&hiwdg); // 喂狗
}Pwm_Led.h
cpp
#ifndef __PWM_LED_H
#define __PWM_LED_H
// LED灯带选择
typedef enum
{
LED1 = 0x00,
LED2 = 0x01,
LED3 = 0x02,
LED4 = 0x03
} Pwm_Led_Number_et;
typedef struct
{
void (*Pwm_Led_Init)(void); // PWM灯带初始化
void (*Pwm_Led_Duty_Control)(Pwm_Led_Number_et, uint8_t); // PWM灯带占空比控制
void (*Pwm_Led_Breathing)(Pwm_Led_Number_et); // 呼吸灯控制
} Pwm_Led_st;
extern Pwm_Led_st Pwm_Led;
#endifPwm_Led.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
LED灯带接线:
PA8(TIM1_CH1) --- LED1
PA9(TIM1_CH2) --- LED2
PA10(TIM1_CH3) --- LED3
PA11(TIM1_CH4) --- LED4
定时器频率设置为1ms,ARR为100,占空比则是0~100对应0%~100%
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private variables=========================================================*/
static uint8_t Led_Duty[] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 101, 90, 80, 70, 60, 50, 40, 30, 20, 10};
/* Private function prototypes===============================================*/
static void Pwm_Led_Init(void);
static void Pwm_Led_Duty_Control(Pwm_Led_Number_et LEDx, uint8_t duty);
static void Pwm_Led_Breathing(Pwm_Led_Number_et LEDx);
/* Public variables==========================================================*/
Pwm_Led_st Pwm_Led =
{
.Pwm_Led_Init = &Pwm_Led_Init,
.Pwm_Led_Duty_Control = &Pwm_Led_Duty_Control,
.Pwm_Led_Breathing = &Pwm_Led_Breathing
};
/*
* @function: Pwm_Led_Init
* @param: None
* @retval: None
* @brief: LED灯带初始化
*/
static void Pwm_Led_Init(void)
{
Pwm_Led_Duty_Control(LED1, 0);
Pwm_Led_Duty_Control(LED2, 0);
Pwm_Led_Duty_Control(LED3, 0);
Pwm_Led_Duty_Control(LED4, 0);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
}
/*
* @function: Pwm_Led_Duty_Control
* @param: None
* @retval: None
* @brief: PWM灯带占空比控制
*/
static void Pwm_Led_Duty_Control(Pwm_Led_Number_et LEDx, uint8_t duty)
{
switch (LEDx)
{
case LED1:
{
TIM1->CCR1 = duty;
break;
}
case LED2:
{
TIM1->CCR2 = duty;
break;
}
case LED3:
{
TIM1->CCR3 = duty;
break;
}
case LED4:
{
TIM1->CCR4 = duty;
break;
}
default:break;
}
}
/*
* @function: Pwm_Led_Breathing
* @param: None
* @retval: None
* @brief: 呼吸灯控制
*/
static void Pwm_Led_Breathing(Pwm_Led_Number_et LEDx)
{
static uint8_t Index1 = 0;
static uint8_t Index2 = 0;
static uint8_t Index3 = 0;
static uint8_t Index4 = 0;
uint8_t len = (sizeof(Led_Duty) / sizeof(Led_Duty[0])) - 1; // 计算数组的长度
switch (LEDx)
{
case LED1:
{
Pwm_Led_Duty_Control(LED1, Led_Duty[Index1]);
Index1 = (Index1 - 0 + 1) % (len - 0 + 1) + 0;
break;
}
case LED2:
{
Pwm_Led_Duty_Control(LED2, Led_Duty[Index2]);
Index2 = (Index2 - 0 + 1) % (len - 0 + 1) + 0;
break;
}
case LED3:
{
Pwm_Led_Duty_Control(LED3, Led_Duty[Index3]);
Index3 = (Index3 - 0 + 1) % (len - 0 + 1) + 0;
break;
}
case LED4:
{
Pwm_Led_Duty_Control(LED4, Led_Duty[Index4]);
Index4 = (Index4 - 0 + 1) % (len - 0 + 1) + 0;
break;
}
default:break;
}
}ultrasound.h
cpp
#ifndef __ULTRASOUND_H
#define __ULTRASOUND_H
// 打印调试使能
#define Ultrasound_Debug 0
/*触发引脚*/
// 置1
#define SOUND_Trig_1_Set() HAL_GPIO_WritePin(Sound_Trig_1_GPIO_Port, Sound_Trig_1_Pin, GPIO_PIN_SET)
// 置0
#define SOUND_Trig_1_RESET() HAL_GPIO_WritePin(Sound_Trig_1_GPIO_Port, Sound_Trig_1_Pin, GPIO_PIN_RESET)
// 超声波所用定时器
#define Ultrasound_Timer &htim2
// 超声波1所在通道
#define Ultrasound_Channel TIM_CHANNEL_1
typedef struct
{
uint16_t distance; // 测量距离
uint32_t Timer_Cnt_Buf[3]; // 存放定时器计数数值的数组
uint8_t Run_Status; // 运行到哪个步骤状态标志位
uint32_t Hight_Time; // 模块返回的高电平时间
void (*ultrasound_Get_Value)(void); // 超声波获取值
void (*ultrasound_Handler)(void); // 超声波处理函数
} ultrasound_st;
extern ultrasound_st ultrasound;
#endifultrasoud.c
cpp
/***************************************************************************
* File: xxx.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
接线:
PA4 --- Trig
PA0(TIM2_CH1) --- Echo
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private function prototypes===============================================*/
static void ultrasound_Get_Value(void);
static void ultrasound_Handler(void);
/* Public variables==========================================================*/
ultrasound_st ultrasound =
{
.distance = 0,
.Timer_Cnt_Buf = {0},
.Run_Status = 0,
.Hight_Time = 0,
.ultrasound_Get_Value = &ultrasound_Get_Value,
.ultrasound_Handler = &ultrasound_Handler
};
/*
* @function: ultrasound_Get_Value
* @param: None
* @retval: None
* @brief: 超声波获取值
*/
static void ultrasound_Get_Value(void)
{
switch (ultrasound.Run_Status)
{
case 0:
{
SOUND_Trig_1_Set();
Public.Public_Delay_us(30);
SOUND_Trig_1_RESET();
ultrasound.Run_Status++;
__HAL_TIM_SET_CAPTUREPOLARITY(Ultrasound_Timer, Ultrasound_Channel, TIM_INPUTCHANNELPOLARITY_RISING); // 上升沿触发
HAL_TIM_IC_Start_IT(Ultrasound_Timer, Ultrasound_Channel); // 输入捕获启动
break;
}
case 3:
{
ultrasound.Hight_Time = ultrasound.Timer_Cnt_Buf[1] - ultrasound.Timer_Cnt_Buf[0]; // 计算高电平时间
ultrasound.distance = (ultrasound.Hight_Time * 0.034) / 2; // 单位cm
#if Ultrasound_Debug
printf("Distance:%d\r\n", ultrasound.distance); // 打印距离
#endif
ultrasound.Run_Status = 0; // 状态清0
TIM2->CNT = 0; // 计数值清0
break;
}
default:break;
}
}
/*
* @function: ultrasound_Handler
* @param: None
* @retval: None
* @brief: 超声波处理函数
*/
static void ultrasound_Handler(void)
{
if (ultrasound.distance < 10) // <10cm
{
Steer.Steer_Control(STEER_3, Angle_180);
}
else
{
Steer.Steer_Control(STEER_3, Angle_0);
}
}Steer.h
cpp
#ifndef __STEER_H
#define __STEER_H
#define TIM4_ARR 200
// 0 --- 0.5ms 2.5%
#define Angle_0 (float)(0.025f * TIM4_ARR)
// 45 --- 1ms 5%
#define Angle_45 (float)(0.05f * TIM4_ARR)
// 90 --- 1.5ms 7.5%
#define Angle_90 (float)(0.075f * TIM4_ARR)
// 135 --- 2ms 10%
#define Angle_135 (float)(0.1f * TIM4_ARR)
// 180 --- 2.5ms 12.5%
#define Angle_180 (float)(0.125f * TIM4_ARR)
// 舵机复位
#define __Steer_Reset() do { \
Steer.Steer_Control(STEER_1, Angle_0); \
Steer.Steer_Control(STEER_2, Angle_0); \
Steer.Steer_Control(STEER_3, Angle_0); \
Steer.Steer_Control(STEER_4, Angle_0); \
} while(0)
typedef enum
{
STEER_1 = 0x00,
STEER_2 = 0x01,
STEER_3 = 0x02,
STEER_4 = 0x03,
} Steer_Number_et;
typedef struct
{
uint8_t Steer_Switch_Flag;
void (*Steer_Init)(void);
void (*Steer_Control)(Steer_Number_et, float);
void (*Steer_Handler)(void);
} Steer_st;
extern Steer_st Steer;
#endifSteer.c
cpp
/***************************************************************************
* File: Steer.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
舵机接线:
PB6(TIM4_CH1) --- 舵机1
PB7(TIM4_CH2) --- 舵机2
PB8(TIM4_CH3) --- 舵机3
PB9(TIM4_CH4) --- 舵机4
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private function prototypes===============================================*/
static void Steer_Init(void);
static void Steer_Control(Steer_Number_et Steer_X, float angle);
static void Steer_Handler(void);
/* Public variables==========================================================*/
Steer_st Steer =
{
.Steer_Switch_Flag = FALSE,
.Steer_Init = &Steer_Init,
.Steer_Control = &Steer_Control,
.Steer_Handler = &Steer_Handler
};
/*
* @function: Steer_Init
* @param: None
* @retval: None
* @brief: 舵机初始化
*/
static void Steer_Init(void)
{
HAL_TIM_Base_Start(&htim4);
Steer_Control(STEER_1, Angle_0);
Steer_Control(STEER_2, Angle_0);
Steer_Control(STEER_3, Angle_0);
Steer_Control(STEER_4, Angle_0);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); // 通道1
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); // 通道2
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); // 通道3
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); // 通道4
}
/*
* @function: Steer_Control
* @param: None
* @retval: None
* @brief: 舵机控制
*/
static void Steer_Control(Steer_Number_et Steer_X, float angle)
{
switch (Steer_X)
{
case STEER_1:
{
TIM4->CCR1 = angle;
break;
}
case STEER_2:
{
TIM4->CCR2 = angle;
break;
}
case STEER_3:
{
TIM4->CCR3 = angle;
break;
}
case STEER_4:
{
TIM4->CCR4 = angle;
break;
}
default:break;
}
}
/*
* @function: Steer_Handler
* @param: None
* @retval: None
* @brief: 舵机处理函数
*/
static void Steer_Handler(void)
{
if (TRUE == Voice.Steer_Switch_Closure_Flag) // 启动自动闭合
{
Steer.Steer_Switch_Flag = !Steer.Steer_Switch_Flag;
if (Steer.Steer_Switch_Flag)
{
Steer_Control(STEER_1, Angle_180);
Steer_Control(STEER_2, Angle_180);
}
else
{
Steer_Control(STEER_1, Angle_0);
Steer_Control(STEER_2, Angle_0);
}
}
else // 关闭自动闭合
{
Steer_Control(STEER_1, Angle_0);
Steer_Control(STEER_2, Angle_0);
}
}控制机械臂
- 硬件
STM32F103C8T6
MG995舵机
【舵机】
- 红色:5V
- 粽色:GND
- 橙色:PWM
【MG995舵机】
转动方向是
0°~180°,周期是20ms(50Hz),0°对应高电平时间是0.5ms,180°对应高电平时间是2.5ms它步进值只能是
10°,小于10°没反应,可以通过公式计算出角度对应的周期时间:
Steer.h
cpp
#ifndef __STEER_H
#define __STEER_H
// 舵机使用定时器
#define USE_STEER_Timer htim1
// 定时器ARR值
#define STEER_TIMER_ARR 200
// 最大周期(180°)
#define STEER_MAX_CYCLE 2.5f
// 最小周期(0°)
#define STEER_MIN_CYCLE 0.5f
// 最大可转角度
#define STEER_MAX_ANGLE 180
// 计算角度对应所需占空比值
#define STEER_CALCULATE_DUTY(angle) (uint8_t)((float)((STEER_MAX_CYCLE - STEER_MIN_CYCLE) / (float)STEER_MAX_ANGLE * angle + 0.5f) / 20 * 200)
// // 0 --- 0.5ms 2.5% 0.5/20=0.025
// #define Angle_0 (float)(0.025f * STEER_TIMER_ARR)
// // 45 --- 1ms 5%
// #define Angle_45 (float)(0.05f * STEER_TIMER_ARR)
// // 90 --- 1.5ms 7.5%
// #define Angle_90 (float)(0.075f * STEER_TIMER_ARR)
// // 135 --- 2ms 10%
// #define Angle_135 (float)(0.1f * STEER_TIMER_ARR)
// // 180 --- 2.5ms 12.5%
// #define Angle_180 (float)(0.125f * STEER_TIMER_ARR)
// 舵机复位
#define __Steer_Reset() do { \
Steer.Steer_Control(STEER_1, STEER_ANGLE_0); \
Steer.Steer_Control(STEER_2, STEER_ANGLE_0); \
Steer.Steer_Control(STEER_3, STEER_ANGLE_0); \
Steer.Steer_Control(STEER_4, STEER_ANGLE_0); \
} while(0)
/*
角度--角度所需占空比值
0.0--5
10.0--6
20.0--7
30.0--8
40.0--9
50.0--10
60.0--11
70.0--12
80.0--13
90.0--15
100.0--16
110.0--17
120.0--18
130.0--19
140.0--20
150.0--21
160.0--22
170.0--23
180.0--25
*/
// 度数对应占空比值
typedef enum
{
STEER_ANGLE_0 = (uint8_t)STEER_CALCULATE_DUTY(0),
STEER_ANGLE_10 = (uint8_t)STEER_CALCULATE_DUTY(10),
STEER_ANGLE_20 = (uint8_t)STEER_CALCULATE_DUTY(20),
STEER_ANGLE_30 = (uint8_t)STEER_CALCULATE_DUTY(30),
STEER_ANGLE_40 = (uint8_t)STEER_CALCULATE_DUTY(40),
STEER_ANGLE_50 = (uint8_t)STEER_CALCULATE_DUTY(50),
STEER_ANGLE_60 = (uint8_t)STEER_CALCULATE_DUTY(60),
STEER_ANGLE_70 = (uint8_t)STEER_CALCULATE_DUTY(70),
STEER_ANGLE_80 = (uint8_t)STEER_CALCULATE_DUTY(80),
STEER_ANGLE_90 = (uint8_t)STEER_CALCULATE_DUTY(90),
STEER_ANGLE_100 = (uint8_t)STEER_CALCULATE_DUTY(100),
STEER_ANGLE_110 = (uint8_t)STEER_CALCULATE_DUTY(110),
STEER_ANGLE_120 = (uint8_t)STEER_CALCULATE_DUTY(120),
STEER_ANGLE_130 = (uint8_t)STEER_CALCULATE_DUTY(130),
STEER_ANGLE_140 = (uint8_t)STEER_CALCULATE_DUTY(140),
STEER_ANGLE_150 = (uint8_t)STEER_CALCULATE_DUTY(150),
STEER_ANGLE_160 = (uint8_t)STEER_CALCULATE_DUTY(160),
STEER_ANGLE_170 = (uint8_t)STEER_CALCULATE_DUTY(170),
STEER_ANGLE_180 = (uint8_t)STEER_CALCULATE_DUTY(180)
} Steer_Angle_et;
typedef enum
{
STEER_1 = 0,
STEER_2 = 1,
STEER_3 = 2,
STEER_4 = 3,
MAX_STEER = STEER_4 + 1,
} Steer_Number_et;
typedef struct
{
uint8_t Now_Angle; // 存储舵机当前的角度值
uint16_t Turn_Time; // 转动完所需时间(ms)大概2s
uint8_t Turn_Over_Flag; // 转动计数完成标志位
} Steer_Parameter_st;
typedef struct
{
uint8_t Steer_All_Start_Flag; // 总启动标志位
void (*Steer_Init)(void);
uint8_t (*Steer_Control)(Steer_Number_et, Steer_Angle_et);
void (*Steer_Test)(void);
void (*Steer_Turn_Judge)(void);
} Steer_st;
extern Steer_st Steer;
extern Steer_Parameter_st Steer_Parameter[];
#endifSteer.c
cpp
/***************************************************************************
* File: Steer.c
* Author: Yang
* Date: 2023/11/21
* description:
-----------------------------------
舵机接线:
PA8(TIM1_CH1) --- 舵机1
PA9(TIM1_CH2) --- 舵机2
PA10(TIM1_CH3) --- 舵机3
PA11(TIM1_CH4) --- 舵机4
-----------------------------------
****************************************************************************/
#include "AllHead.h"
/* Private function prototypes===============================================*/
static void Steer_Init(void);
static uint8_t Steer_Control(Steer_Number_et Steer_X, Steer_Angle_et angle);
static void Steer_Test(void);
static void Steer_Turn_Judge(void);
/* Public variables==========================================================*/
Steer_Parameter_st Steer_Parameter[] =
{
{STEER_ANGLE_0, 2000, FALSE},
{STEER_ANGLE_0, 2000, FALSE},
{STEER_ANGLE_0, 2000, FALSE},
{STEER_ANGLE_0, 2000, FALSE}
};
Steer_st Steer =
{
.Steer_All_Start_Flag = FALSE,
.Steer_Init = &Steer_Init,
.Steer_Control = &Steer_Control,
.Steer_Test = &Steer_Test,
.Steer_Turn_Judge = &Steer_Turn_Judge
};
/*
* @function: Steer_Init
* @param: None
* @retval: None
* @brief: 舵机初始化
*/
static void Steer_Init(void)
{
HAL_TIM_Base_Start(&USE_STEER_Timer);
__Steer_Reset(); // 复位
HAL_TIM_PWM_Start(&USE_STEER_Timer, TIM_CHANNEL_1); // 通道1
HAL_TIM_PWM_Start(&USE_STEER_Timer, TIM_CHANNEL_2); // 通道2
HAL_TIM_PWM_Start(&USE_STEER_Timer, TIM_CHANNEL_3); // 通道3
HAL_TIM_PWM_Start(&USE_STEER_Timer, TIM_CHANNEL_4); // 通道4
}
/*
* @function: Steer_Control
* @param: None
* @retval: None
* @brief: 舵机控制
*/
static uint8_t Steer_Control(Steer_Number_et Steer_X, Steer_Angle_et angle)
{
uint8_t res = FALSE;
uint8_t i;
switch (Steer_X)
{
case STEER_1:
{
if (FALSE == Steer_Parameter[STEER_1].Turn_Over_Flag)
{
TIM1->CCR1 = angle;
Steer_Parameter[STEER_1].Now_Angle = angle;
Steer_Parameter[STEER_1].Turn_Over_Flag = TRUE;
res = TRUE;
}
break;
}
case STEER_2:
{
if (FALSE == Steer_Parameter[STEER_2].Turn_Over_Flag)
{
TIM1->CCR2 = angle;
Steer_Parameter[STEER_2].Now_Angle = angle;
Steer_Parameter[STEER_2].Turn_Over_Flag = TRUE;
res = TRUE;
}
break;
}
case STEER_3:
{
if (FALSE == Steer_Parameter[STEER_3].Turn_Over_Flag)
{
TIM1->CCR3 = angle;
Steer_Parameter[STEER_3].Now_Angle = angle;
Steer_Parameter[STEER_3].Turn_Over_Flag = TRUE;
res = TRUE;
}
break;
}
case STEER_4:
{
if (FALSE == Steer_Parameter[STEER_4].Turn_Over_Flag)
{
TIM1->CCR4 = angle;
Steer_Parameter[STEER_4].Now_Angle = angle;
Steer_Parameter[STEER_4].Turn_Over_Flag = TRUE;
res = TRUE;
}
break;
}
default:break;
}
return res;
}
/*
* @function: Steer_Test
* @param: None
* @retval: None
* @brief: 舵机测试函数
*/
static void Steer_Test(void)
{
static uint8_t step = 0;
static Steer_Angle_et steer_angle_temp = STEER_ANGLE_0;
if (!Steer.Steer_All_Start_Flag) // 强制退出
{
return;
}
switch (step)
{
case 0: // 0 -> 180
{
Steer_Parameter[STEER_1].Turn_Time = 200; // 转小的度数
if (steer_angle_temp != STEER_ANGLE_180)
{
if (TRUE == Steer.Steer_Control(STEER_1, steer_angle_temp))
{
steer_angle_temp++;
}
}
else
{
step++;
}
break;
}
case 1: // 180 -> 0
{
if (steer_angle_temp != STEER_ANGLE_0)
{
if (TRUE == Steer.Steer_Control(STEER_1, steer_angle_temp))
{
steer_angle_temp--;
}
}
else
{
step++;
}
break;
}
case 2: // 180
{
Steer_Parameter[STEER_1].Turn_Time = 2000; // 转大的度数
if (TRUE == Steer.Steer_Control(STEER_1, STEER_ANGLE_180))
{
step++;
}
break;
}
case 3: // 180
{
if (TRUE == Steer.Steer_Control(STEER_1, STEER_ANGLE_0))
{
step = 0;
}
break;
}
default:
{
step = 0;
break;
}
}
return;
}
/*
* @function: Steer_Turn_Judge
* @param: None
* @retval: None
* @brief: 转向时间计数(1ms检测一次)
*/
static void Steer_Turn_Judge(void)
{
uint8_t i;
static uint16_t Steer_Turn_Cnt[MAX_STEER] = {0};
for (i = 0; i < MAX_STEER; i++)
{
if (Steer_Parameter[i].Turn_Over_Flag) // 置1
{
Steer_Turn_Cnt[i]++;
if (Steer_Turn_Cnt[i] >= Steer_Parameter[i].Turn_Time)
{
Steer_Turn_Cnt[i] = 0;
Steer_Parameter[i].Turn_Over_Flag = FALSE;
}
}
}
}CallBack.c
cpp
/***************************************************************************
* File: CallBack.c
* Author: Luckys.
* Date: 2023/06/19
* description: store interrupt function
****************************************************************************/
#include "AllHead.h"
/* Public variables==========================================================*/
extern uint8_t ucUart1_Rec_Buff[128];
/*
* @function: HAL_TIM_PeriodElapsedCallback
* @param: None
* @retval: None
* @brief: timer callback function
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim4.Instance) // 1ms
{
System.Task_Marks_Handler();
Steer.Steer_Turn_Judge(); // 计数
}
}
void USART1_IRQHandler(void)
{
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != 0x00u)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1); // 串口停止DMA接收
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ1_0") != NULL)
{
Steer.Steer_Control(STEER_1, STEER_ANGLE_0);
printf("1\r\n");
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ1_45") != NULL)
{
Steer.Steer_Control(STEER_1, STEER_ANGLE_50);
printf("1\r\n");
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ1_90") != NULL)
{
Steer.Steer_Control(STEER_1, STEER_ANGLE_90);
printf("1\r\n");
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ1_135") != NULL)
{
Steer.Steer_Control(STEER_1, STEER_ANGLE_160);
printf("1\r\n");
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ1_180") != NULL)
{
Steer.Steer_Control(STEER_1, STEER_ANGLE_180);
printf("1\r\n");
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ_CLOSE") != NULL)
{
Steer.Steer_All_Start_Flag = FALSE;
}
if (strstr((char*)ucUart1_Rec_Buff, (char*)"DJ_OPEN") != NULL)
{
Steer.Steer_All_Start_Flag = TRUE;
}
HAL_UART_Receive_DMA(&huart1, ucUart1_Rec_Buff, 128);
}
HAL_UART_IRQHandler(&huart1);
}Task.c
cpp
static inline void TasksHandle_200MS(void)
{
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
Steer.Steer_Test(); // 测试
}






