stm32driver
Stm32 chassis motor drive
A, functionality,
- 1. Equipped with FreeRTOS
- 2, variable length data reception (IDLE+DMA)
- 3, I2C display (motor parameters)
- 4, incremental PI controller (DC coded motor)
Second, the overall structure
- IO layout
- FreeRTOSHeapUsage
- Functional initialization
- FreeRTOS run timing
Three, application peripherals
- SystemCore
- RCC
- SYS
- Timers
- TIM2
- TIM3
- TIM4
- Connectivity
- I2C1
- USART3
- Middleware
- FREERTOS
Four, detailed description
1, the FreeRTOS
- freertos.c
Release only the task execution function, other content please refer to the source code
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
void StartTaskMotor(void *argument)
{
/* USER CODE BEGIN StartTaskMotor */
para_init();
/* Infinite loop */
for(;;)
{
// TODO
osDelay(10);
}
/* USER CODE END StartTaskMotor */
}
void StartTaskDisplay(void *argument)
{
/* USER CODE BEGIN StartTaskDisplay */
/* Infinite loop */
for(;;)
{
// TODO
osDelay(50);
}
/* USER CODE END StartTaskDisplay */
}
void StartTaskUsart(void *argument)
{
/* USER CODE BEGIN StartTaskUsart */
/* Infinite loop */
for(;;)
{
// TODO
osDelay(1);
}
/* USER CODE END StartTaskUsart */
}
Copy the code
2, variable length of data reception
- usart.c
/* USER CODE BEGIN 0 */
#if 1
struct __FILE{
int handle;
};
FILE __stdout;
// Define _sys_exit() to avoid semi-host mode
void _sys_exit(int x){
x = x;
}
// Redefine the fputc function
int fputc(int ch, FILE *f){
while((USART3->SR&0X40) = =0); // Loop until the send is complete
USART3->DR=(uint8_t)ch;
return ch;
}
#endif
volatile uint8_t rx3_len = 0; // The length of the received data
volatile uint8_t rec3_end_flag = 0; // The data receiving completion mark
uint8_t rx3_buffer[BUFFER_SIZE] = {0}; // Receive the data cache array
/* USER CODE END 0 */
Copy the code
/* USER CODE BEGIN 1 */
void Usart3_IDLE(void) { // IDLE reception of USART
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag = __HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE); // Get the IDLE flag
if((tmp_flag ! = RESET)){/ / idle
__HAL_UART_CLEAR_IDLEFLAG(&huart3); // Clear the flag bit
HAL_UART_DMAStop(&huart3); // Stop the DMA transfer
temp = __HAL_DMA_GET_COUNTER(&hdma_usart3_rx); // Get the number of data not transferred in DMA
rx3_len = BUFFER_SIZE - temp; // The total number of received data is subtracted from the number of untransmitted data
rec3_end_flag = 1; // Accept complete flag position 1}}void DMA_Usart3_Send(uint8_t *buf,uint8_t len) { // Serial port send encapsulation
if(HAL_UART_Transmit_DMA(&huart3,buf,len) ! = HAL_OK) {// Check whether sending is normal. If there is an exception, enter the exception interrupt functionError_Handler(); }}/* USER CODE END 1 */
Copy the code
- usart.h
/* USER CODE BEGIN Prototypes */
extern volatile uint8_t rx3_len; // The length of the received data
extern volatile uint8_t rec3_end_flag; // The data receiving completion flag
extern uint8_t rx3_buffer[BUFFER_SIZE]; // Receive the data cache array
void DMA_Usart3_Send(uint8_t *buf,uint8_t len); // Serial port send encapsulation
void Usart3_IDLE(void);
/* USER CODE END Prototypes */
Copy the code
- stm32f1xx_it.c
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */
Copy the code
/* USER CODE BEGIN USART3_IRQn 0 */
Usart3_IDLE();
/* USER CODE END USART3_IRQn 0 */
Copy the code
- main.c
/* USER CODE BEGIN 2 */
// Start usart3
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart3,rx3_buffer,BUFFER_SIZE);
/* USER CODE END 2 */
Copy the code
- freertos.c
/* USER CODE BEGIN Header_StartTaskUsart */
/**
* @brief Function implementing the myTaskUsart thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskUsart */
void StartTaskUsart(void *argument)
{
/* USER CODE BEGIN StartTaskUsart */
/* Infinite loop */
for(;;)
{
if(rec3_end_flag) { // Check whether the reception is complete
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // DEBUG
Usart3_Handle();
}
osDelay(1);
}
/* USER CODE END StartTaskUsart */
}
Copy the code
void Usart3_Handle(a) { // USART handler
user_API(rx3_buffer, rx3_len); // Analyze the data
rx3_len = 0; // Clear the count
rec3_end_flag = 0; // Clear the end of receive flag
memset(rx3_buffer,0,rx3_len);
HAL_UART_Receive_DMA(&huart3,rx3_buffer,BUFFER_SIZE); // Open DMA receive again
}
Copy the code
3, I2C display
- This section has been encapsulated as
./Core/Src/User/oled*
- Basic operation logic in freertos.c
void OLED_flash_data(a){
show_info(motorInfo[0].ENC, 1+8*6.0);
show_info(motorInfo[0].ADD, 1+8*6.1);
show_info(motorInfo[0].TGT, 1+8*6.2);
show_info(motorInfo[0].PWM, 1+8*6.3);
show_info(motorInfo[1].ENC, 1+8*6.4);
show_info(motorInfo[1].ADD, 1+8*6.5);
show_info(motorInfo[1].TGT, 1+8*6.6);
show_info(motorInfo[1].PWM, 1+8*6.7);
}
Copy the code
4. Incremental PI controller
- This section has been encapsulated as
./Core/Src/User/motor*
- Basic operation logic in freertos.c
void StartTaskMotor(void *argument)
{
/* USER CODE BEGIN StartTaskMotor */
para_init();
/* Infinite loop */
for(;;)
{
check_ENC(&motorInfo[0], &motorInfo[1]);
// plus_ADD(&motorInfo[0], &motorInfo[1]);
incremental_PI_A(&motorInfo[0]);
incremental_PI_B(&motorInfo[1]);
range_PWM(&motorInfo[0], &motorInfo[1].7000);
set_PWM(&motorInfo[0], &motorInfo[1]);
osDelay(10);
}
/* USER CODE END StartTaskMotor */
}
Copy the code
Five, as the use of the next machine
115200 Serial port communication format [00+0+0]
- [0-100) = total throttle
- If ws is down, w is down +1, s is down -1, if not +0, both are down -0
- If AD is pressed down, a is pressed down +1, D is pressed down -1, if not +0, both are pressed down -0
Vi. Project address
Github.com/causehhc/st…