此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉前言
在这个实验项目中,我使用STM32CubeMX配置了基础硬件,实现了PWM呼吸灯效果、DMA接收串口数据、ADC双通道测电压等功能。经过一番调试,最终成功实现了所有功能,同时也解决了一些遇到的问题。下面将详细介绍整个实验的过程和注意事项。
基础配置
开启时钟

LCD

这里不要忘了开启PB0 
开启串口1,添加DMA

TIM
因为PB5接的是LED灯,所以直接选择PB5,如果自动选不会选PB5。
ADC

配置完,生成代码
代码编写
测试
首先测试一下各个功能是否正常
将我之前写的库导入,将多余的代码删去,首先编译一下。
接下来测试串口和LED

DMA接收
uart.c
1 2 3
| volatile uint8_t rx_len = 0; volatile uint8_t recv_end_flag = 0; uint8_t rx_buffer[100]={0};
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| void MX_USART1_UART_Init(void) {
huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); }
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);
}
|
uart.h
1 2 3 4 5 6 7 8 9 10
| extern UART_HandleTypeDef huart1; extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_tx;
#define BUFFER_SIZE 100 extern volatile uint8_t rx_len ; extern volatile uint8_t recv_end_flag; extern uint8_t rx_buffer[100];
|
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
void DMA_Usart_Send(uint8_t *buf,uint8_t len) { if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) { Error_Handler(); }
}
void DMA_Usart1_Read(uint8_t *Data,uint8_t len) { HAL_UART_Receive_DMA(&huart1,Data,len); }
|
while循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| while (1) {
if(recv_end_flag == 1) { DMA_Usart_Send(rx_buffer, rx_len); rx_len = 0; recv_end_flag = 0;
memset(rx_buffer,0,rx_len); } HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); }
|
stm32f1xx_it.c中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include "usart.h"
void USART1_IRQHandler(void) { uint32_t tmp_flag = 0; uint32_t temp; tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); if((tmp_flag != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_UART_DMAStop(&huart1); temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); rx_len = BUFFER_SIZE - temp; recv_end_flag = 1; } HAL_UART_IRQHandler(&huart1);
}
|
发送数据-测试成功 
加入PWM呼吸灯代码
测试成功
加入全部代码
PWM
实现LED呼吸灯效果
while 函数中
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| HAL_Delay(20); if (dir) ledrpwmval++; else ledrpwmval--;
if (ledrpwmval > 100 - 1) dir = 0; if (ledrpwmval == 0) dir = 1;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, ledrpwmval);
user_main_printf("ledrpwmval:%d", ledrpwmval);
|
PWM控制电机转速
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| KeyNum = key_scan(1); if (KeyNum == 1) { HAL_Delay(10); key_t_speed += 20; if (key_t_speed > 100) { key_t_speed = -100; } }
LCD_ShowString(0, 150, 240, 24, 24, "Speed:"); if (key_t_speed < 0) { speed_show = 0 - key_t_speed; LCD_ShowString(90, 150, 240, 24, 24, "-"); LCD_ShowNum(100, 150, speed_show, 3, 24); } else { speed_show = key_t_speed; LCD_ShowString(90, 150, 240, 24, 24, " "); LCD_ShowNum(100, 150, speed_show, 3, 24); } Motor_SetSpeed(key_t_speed);
|
ADC双通道测电压
1 2 3 4 5 6 7 8 9 10 11
| for (i = 0, ad1 = 0, ad2 = 0; i < 100;) { ad1 += ADC_Value[i++]; ad2 += ADC_Value[i++]; } ad1 /= 50; ad2 /= 50; user_main_info("ADC测试");
ADC_1v = (int)ad1 * 3.3f / 4096; ADC_1v = ad1 * 3.3f / 4096 * 1000 - ADC_1v * 1000;
|
遇到的问题
LCD和OLED同时开启时,初始化失败
解决方案: 因为我一开始使用的I2C1,换到I2C2问题解决。