STM32与ESP8266的使用

embedded/2024/9/19 11:16:47/ 标签: stm32, 单片机, 嵌入式硬件

串口透传

  • “透传”通常指的是数据的透明传输,意思是在不对数据进行任何处理或修改的情况下,将数据从一个接口转发到另一个接口。
  • 值得注意的是要避免串口之间无限制的透明,可以采用互斥锁的方式进行限制
  • 使用方法
  1. 对USART1和USART3(用他俩举例)的模式都是设置为Asynchronous,并开启对应的中断。
  2. RCC的High SPeed CLock模式设置为Crystal/Ceramic
  3. 配置对应的时钟为64Mhz
  4. 在main函数中启动串口1和串口3的空闲中断模式,接收数据 HAL_UARTEx_ReceiveToIdle_IT(&huart1, rxbuf1, sizeof(rxbuf1));
    HAL_UARTEx_ReceiveToIdle_IT(&huart3, rxbuf3, sizeof(rxbuf3));
  5. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)写对应的透传即可
  • 代码示例
#include "main.h"
#include <string.h>UART_HandleTypeDef huart1; // 定义串口1的句柄
UART_HandleTypeDef huart3; // 定义串口3的句柄char rxbuf1[128] = {0}; // 用于接收串口1数据的缓冲区
char rxbuf3[128] = {0}; // 用于接收串口3数据的缓冲区
uint8_t uart1_to_uart3_enable = 1;  // 控制串口1是否允许发送数据到串口3的标志位
uint8_t uart3_to_uart1_enable = 1;  // 控制串口3是否允许发送数据到串口1的标志位/*** @brief 串口接收中断回调函数* 该函数在接收到数据后触发,并根据当前接收的是串口1还是串口3的数据,进行对应的处理。* @param huart 串口句柄* @param Size 接收到的数据大小*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
{printf("HAL_UARTEx_RxEventCallback triggered\n");// 判断当前接收的数据是否来自串口1,并且标志位允许发送给串口3if (huart == &huart1 && uart1_to_uart3_enable){uart3_to_uart1_enable = 0; // 禁止串口3将数据回传给串口1,防止死循环HAL_UART_Transmit(&huart3, (uint8_t*)rxbuf1, Size, HAL_MAX_DELAY); // 将串口1接收的数据发送给串口3memset(rxbuf1, 0, sizeof(rxbuf1)); // 清空串口1接收缓冲区HAL_UARTEx_ReceiveToIdle_IT(&huart1, rxbuf1, sizeof(rxbuf1)); // 重新启动串口1接收中断uart3_to_uart1_enable = 1; // 允许串口3传输数据到串口1printf("port1 sent to port 3\n");}// 判断当前接收的数据是否来自串口3,并且标志位允许发送给串口1else if (huart == &huart3 && uart3_to_uart1_enable){uart1_to_uart3_enable = 0; // 禁止串口1将数据回传给串口3,防止死循环HAL_UART_Transmit(&huart1, (uint8_t*)rxbuf3, Size, HAL_MAX_DELAY); // 将串口3接收的数据发送给串口1memset(rxbuf3, 0, sizeof(rxbuf3)); // 清空串口3接收缓冲区HAL_UARTEx_ReceiveToIdle_IT(&huart3, rxbuf3, sizeof(rxbuf3)); // 重新启动串口3接收中断uart1_to_uart3_enable = 1; // 允许串口1传输数据到串口3printf("port3 sent to port 1\n");}return;
}/*** @brief 重定向printf函数,将其输出重定向到串口1* @param ch 需要输出的字符* @return 返回输出的字符*/
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart1, (unsigned char*)&ch, 1, HAL_MAX_DELAY); // 将字符通过串口1发送return ch; // 返回字符
}/*** @brief 主函数*/
int main(void)
{HAL_Init(); // 初始化HAL库SystemClock_Config(); // 配置系统时钟MX_GPIO_Init(); // 初始化GPIOMX_USART1_UART_Init(); // 初始化串口1MX_USART3_UART_Init(); // 初始化串口3// 启动串口1和串口3的空闲中断模式,接收数据HAL_UARTEx_ReceiveToIdle_IT(&huart1, rxbuf1, sizeof(rxbuf1));HAL_UARTEx_ReceiveToIdle_IT(&huart3, rxbuf3, sizeof(rxbuf3));while (1){// 主循环中可以进行其他任务处理}
}/*** @brief 配置系统时钟* 设置MCU的时钟源、倍频系数等,保证系统运行在正确的时钟频率*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0}; // 配置RCC振荡器参数RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 配置RCC时钟源及分频系数RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 使用外部高速振荡器(HSE)RCC_OscInitStruct.HSEState = RCC_HSE_ON; // 开启HSERCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; // HSE预分频值为1RCC_OscInitStruct.HSIState = RCC_HSI_ON; // 开启内部高速振荡器(HSI)RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; // 开启PLLRCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // PLL时钟源为HSERCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; // PLL倍频系数为8if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler(); // 时钟配置失败,进入错误处理函数}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; // 配置不同的时钟类型RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟源设置为PLLRCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB时钟不分频RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1时钟分频系数为2RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2时钟不分频if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler(); // 时钟配置失败,进入错误处理函数}
}/*** @brief 初始化串口1* 配置波特率、数据位、停止位等串口参数*/
static void MX_USART1_UART_Init(void)
{huart1.Instance = USART1; // 设置串口1的实例huart1.Init.BaudRate = 115200; // 波特率设置为115200huart1.Init.WordLength = UART_WORDLENGTH_8B; // 数据位长度为8位huart1.Init.StopBits = UART_STOPBITS_1; // 停止位为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; // 过采样设置为16倍if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler(); // 初始化失败,进入错误处理函数}
}/*** @brief 初始化串口3* 配置波特率、数据位、停止位等串口参数*/
static void MX_USART3_UART_Init(void)
{huart3.Instance = USART3; // 设置串口3的实例huart3.Init.BaudRate = 115200; // 波特率设置为115200huart3.Init.WordLength = UART_WORDLENGTH_8B; // 数据位长度为8位huart3.Init.StopBits = UART_STOPBITS_1; // 停止位为1位huart3.Init.Parity = UART_PARITY_NONE; // 无校验位huart3.Init.Mode = UART_MODE_TX_RX; // 使能接收和发送模式huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 不使用硬件流控huart3.Init.OverSampling = UART_OVERSAMPLING_16; // 过采样设置为16倍if (HAL_UART_Init(&huart3) != HAL_OK){Error_Handler(); // 初始化失败,进入错误处理函数}
}/*** @brief GPIO初始化* 配置GPIO端口,用于其他硬件外设,如LED、按键等*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};// 启用GPIO时钟__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();// 配置PC6、PC7、PC8引脚为推挽输出模式,初始化为低电平,用于驱动LED或其他外设HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8, GPIO_PIN_RESET);GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8; // 设置要配置的引脚GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 配置为推挽输出模式GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上拉或下拉电阻GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 设置为低速HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); // 初始化GPIO端口PC6、PC7、PC8
}/*** @brief 错误处理函数* 当系统发生错误时调用该函数。可以在此函数中添加错误处理逻辑,如重启系统或记录日志。*/
void Error_Handler(void)
{__disable_irq(); // 禁用全局中断,防止进一步的干扰while (1) {// 无限循环,防止系统继续运行。可以在此添加LED闪烁等故障指示}
}#ifdef USE_FULL_ASSERT
/*** @brief 断言失败时调用此函数* 当遇到断言参数错误时,报告源文件和行号,帮助调试* @param file 指向发生错误的源文件名的指针* @param line 发生错误的代码行号*/
void assert_failed(uint8_t *file, uint32_t line)
{// 可以在此添加打印或记录错误的实现,例如:// printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}
#endif /* USE_FULL_ASSERT */

ESP8266与STM32

  • ESP8266 是一款集成了Wi-Fi通信功能的低功耗微控制器,广泛应用于物联网(IoT)设备中。
  • Station 模式:可以像普通的 Wi-Fi 设备一样连接到现有的无线网络。
  • AP 模式:可以创建自己的 Wi-Fi 热点,让其他设备连接到 ESP8266。
  • Station + Access Point 混合模式(STA + AP 模式):ESP8266 同时充当客户端和热点,既可以连接到现有的 Wi-Fi 网络(作为 STA),又可以作为热点允许其他设备连接到它(作为 AP)。
AT+CWMODE=1:设置为 Station 模式。
AT+CWMODE=2:设置为 AP 模式。
AT+CWMODE=3:设置为 STA + AP 混合模式。
  • 服务器
www.daxia.com//下载SSCOM即可
STATION模式
  • 配置uart1- printf,uart3-esp上网(因为WiFi芯片在串口3)
    在这里插入图片描述
使用方法
  • 新建stm32工程中添加WiFi-ops.c和WiFi-ops.h
  • 开启时钟频率为64Mhz和RCC的Crystal
  • 开启UART1和UART3串口为异步通信,且开启中断。
  • 并配置LED灯管脚留作测试
  • 代码示例
#include "main.h"
#include "stdio.h"
#include "string.h"
#include "wifi-ops.h"// UART句柄
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART3_UART_Init(void);
// 日志状态标志
int log_success_flags = 0;  // 0 - 未初始化,1 - 日志成功,2 - 日志失败/*** @brief  ESP8266 Station模式回调函数* @param  data: 接收到的数据* @param  len: 数据长度* @retval 返回值说明*/
int esp_station_callback(char *data, int len)
{printf("recv from serv: %s\r\n", data);// 更新日志状态标志if (strstr(data, "log success")) {log_success_flags = 1;} else if (strstr(data, "log failed")) {log_success_flags = 2;}return 0;
}/*** @brief  UART接收事件回调函数* @param  huart: UART句柄* @param  Size: 接收的数据大小* @retval None*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{// 处理接收事件,没有传给另一个串口wifi_uart_prepare_idle(huart);  // 接收完成后,准备UART进行下一次接收
}/*** @brief  重定向putchar到UART1* @param  ch: 要发送的字符* @retval 返回发送的字符*/
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 1);return ch;
}/*** @brief  主函数入口* @retval 程序返回值*/
int main(void)
{HAL_Init(); // 初始化HAL库SystemClock_Config(); // 配置系统时钟// 初始化所有配置的外设MX_GPIO_Init();MX_USART1_UART_Init();MX_USART3_UART_Init();int ret;char sendbuf[128] = {0}; // 用于发送数据的缓冲区// 准备UART3进行ESP8266通信,使用串口3wifi_uart_prepare_idle(&huart3);// 初始化ESP8266 Station模式,使用串口3ret = wifi_station_init(&huart3, esp_station_callback);if (ret < 0) {printf("%s-%d wifi_station_init err\r\n", __func__, __LINE__);return -35;}// 连接到指定的APret = wifi_station_join_ap(&huart3, "xiaomimobile", "12345600");if (ret < 0) {printf("%s-%d wifi_station_join_ap err\r\n", __func__, __LINE__);return -35;}// 连接到指定的TCP服务器ret = wifi_station_tcp_connect(&huart3, "107.148.201.156", 10005);if (ret < 0) {printf("%s-%d wifi_station_tcp_connect err\r\n", __func__, __LINE__);return -35;}// 发送日志请求数据。特定格式snprintf(sendbuf, sizeof(sendbuf), "toServ:action=log,usrname=%s,passwd=%s,devname=sml001;", "xiaowang", "123456");ret = wifi_station_tcp_send_data(&huart3, sendbuf, strlen(sendbuf));if (ret < 0) {printf("%s-%d wifi_station_tcp_send_data err\r\n", __func__, __LINE__);}// 等待日志发送结果for (int i = 0; i < 50; i++) {if (log_success_flags == 2) {printf("%s-%d log failed \r\n", __func__, __LINE__);return -23;} else if (log_success_flags == 1) {printf("%s-%d log success \r\n", __func__, __LINE__);break;}HAL_Delay(10);}// 循环发送获取时间请求,这个是该服务器的特定格式strcpy(sendbuf, "toServ:action=gettime;");while (1){ret = wifi_station_tcp_send_data(&huart3, sendbuf, strlen(sendbuf));if (ret < 0) {printf("%s-%d wifi_station_tcp_send_data err\r\n", __func__, __LINE__);}HAL_Delay(500); // 等待500毫秒}
}/*** @brief  配置系统时钟* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};// 初始化RCC振荡器RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {Error_Handler();}// 初始化CPU、AHB和APB总线时钟RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {Error_Handler();}
}/*** @brief  初始化USART1* @retval None*/
static 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();}
}/*** @brief  初始化USART3* @retval None*/
static void MX_USART3_UART_Init(void)
{huart3.Instance = USART3;huart3.Init.BaudRate = 115200;huart3.Init.WordLength = UART_WORDLENGTH_8B;huart3.Init.StopBits = UART_STOPBITS_1;huart3.Init.Parity = UART_PARITY_NONE;huart3.Init.Mode = UART_MODE_TX_RX;huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart3.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart3) != HAL_OK) {Error_Handler();}
}/*** @brief  初始化GPIO* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};// 启用GPIO端口时钟__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();// 配置GPIO输出级别HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8, GPIO_PIN_RESET);// 配置GPIO引脚GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}/*** @brief  错误处理函数* @retval None*/
void Error_Handler(void)
{__disable_irq();while (1) {}
}/*** @brief  报告断言失败的文件名和行号* @param  file: 源文件名* @param  line: 错误行号* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{// 用户可以添加自己的实现来报告文件名和行号
}
混合模式
  • 默认情况下,ESP8266 的 IP 地址在 AP 模式下是 192.168.4.1,以便其他设备连接到该 AP 时可以进行通信。
  • 代码

#include "main.h"#include "stdio.h"
#include "string.h"
#include "wifi-ops.h"UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART3_UART_Init(void);#ifdef ESP_STATION/*当stm32收到 esp/服务器发来消息, 会自动执行该函数* 	data,len 表示收到的具体数据和长度*** 该函数是在 中断执行,不好执行耗时/睡眠工作* */int log_success_flags = 0;		//0-uninit  1-log  2-failedint esp_station_callback (char *data,int len)
{printf("recv from serv: %s\r\n",data);//登陆成功失败标志位if( strstr(data,"log success") ){log_success_flags = 1;}else if(strstr(  data, "log failed")){log_success_flags = 2;}}
#endif/* 希望手机发来消息,该函数 被调用,  data len分别是对方发来的消息和长度*/
int esp_ap_callback(char *data,int len)
{printf("recv from phone: %s\r\n",data);		//cmd:wifiname=hyx,wifipasswd=8888888,usrname=xiaowang,passwd=123456;
}void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{//other thing to dowifi_uart_prepare_idle(huart);	//after recv success, wo must prepare uart for next time
}int __io_putchar(int ch)
{HAL_UART_Transmit(&huart1, (unsigned char *)&ch,  1,     1);return ch;
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();MX_USART3_UART_Init();/* USER CODE BEGIN 2 */int ret;int linkid;	//每个手机都可以连接ap,都会安排一个idchar sendbuf[128]={0};#ifdef ESP_STATION//预处理uart3 for esp ...wifi_uart_prepare_idle(&huart3);ret = wifi_station_init(&huart3,  esp_station_callback );if(ret < 0 ){	printf("%s-%d wifi_station_init err\r\n",__func__,__LINE__);		return -35;}ret = wifi_station_join_ap(&huart3,"WANGQINGFA","1234567890");if(ret < 0 ){	printf("%s-%d wifi_station_join_ap err\r\n",__func__,__LINE__);		return -35;}ret = wifi_station_tcp_connect(&huart3,"107.148.201.156",10001);if(ret < 0 ){	printf("%s-%d wifi_station_tcp_connect err\r\n",__func__,__LINE__);	return -35;}/*登陆服务器		toServ:action=log,usrname=xiaowang,passwd=123456,devname=sml001;		*/snprintf(sendbuf,sizeof(sendbuf), "toServ:action=log,usrname=%s,passwd=%s,devname=sml001;","xiaowang","123456" );ret = wifi_station_tcp_send_data(&huart3,sendbuf,strlen(sendbuf));if(ret < 0 ){	printf("%s-%d wifi_station_tcp_connect err\r\n",__func__,__LINE__);	   }for(int i=0;i<50;i++){if(log_success_flags == 2){printf("%s-%d log failed \r\n",__func__,__LINE__);return -23;}else if(log_success_flags == 1){printf("%s-%d log success \r\n",__func__,__LINE__);break;}HAL_Delay(10);}
#endifwifi_uart_prepare_idle(&huart3);ret = wifi_ap_init(&huart3,  esp_ap_callback);if(ret < 0 ){	printf("%s-%d wifi_ap_init err\r\n",__func__,__LINE__);		return -35;}ret = wifi_ap_set_args(&huart3, "zhangsan","12345678");if(ret < 0 ){	printf("%s-%d wifi_ap_set_args err\r\n",__func__,__LINE__);		return -35;}linkid = wifi_ap_tcp_listen_and_wait_connect_timeout(&huart3,10001,     5*60*1000);if(linkid < 0 ){	printf("%s-%d wifi_ap_tcp_listen_and_wait_connect_timeout err\r\n",__func__,__LINE__);		return -35;}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */strcpy(sendbuf,"cmd:hello phone,I have got you messgae,please reset it;");while (1){wifi_ap_tcp_send_data(&huart3, linkid , sendbuf,strlen(sendbuf)    );#ifdef ESP_STATIONret = wifi_station_tcp_send_data(&huart3,sendbuf,strlen(sendbuf));if(ret < 0 ){	printf("%s-%d wifi_station_tcp_connect err\r\n",__func__,__LINE__);	   }
#endifHAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/*** @brief USART1 Initialization Function* @param None* @retval None*/
static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */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();}}static void MX_USART3_UART_Init(void)
{huart3.Instance = USART3;huart3.Init.BaudRate = 115200;huart3.Init.WordLength = UART_WORDLENGTH_8B;huart3.Init.StopBits = UART_STOPBITS_1;huart3.Init.Parity = UART_PARITY_NONE;huart3.Init.Mode = UART_MODE_TX_RX;huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart3.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart3) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART3_Init 2 *//* USER CODE END USART3_Init 2 */}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8, GPIO_PIN_RESET);/*Configure GPIO pins : PC6 PC7 PC8 */GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
  • 如图所示,用的TCP/IP调试软件
    在这里插入图片描述

http://www.ppmy.cn/embedded/113343.html

相关文章

Python--常见的数据格式转换

下面是几个常见的数据格式转换的示例&#xff0c;涵盖了一些常用的格式&#xff0c;如 CSV、XML、YAML 等。每个示例都会介绍如何从一种格式转换到另一种格式。 1. CSV 转 JSON CSV 文件通常以逗号分隔&#xff0c;行代表记录&#xff0c;列代表字段。我们可以使用 csv 和 js…

【图像匹配】基于SURF算法的图像匹配,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于基于SURF算法的图像匹配&#xff0c;用matlab实现。 一、案例背景和算法介绍 前…

SHT30温湿度传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理 三、程序设计 main.c文件 sht30.h文件 sht30.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 SHT30是一种常见的温湿度传感器&#xff0c;是一款完全校准的线性化的温湿度数字传感器&#xff0…

echarts 自定义标注样式自定义tooltip弹窗样式

文章目录 1. 实现根据经纬度自定义标注图片样式2. 实现鼠标悬浮标注自定义弹窗样式内容 1. 实现根据经纬度自定义标注图片样式 设置 symbol 属性为 image://${require("/assets/img/dataView/point.png")} 图片地址即可&#xff0c;注意前面跟 image:// 特有的写法b…

2024最新版MySQL详细学习教程

MySQL数据库提供了很多函数包括&#xff1a; 数学函数&#xff1b;字符串函数&#xff1b;日期和时间函数&#xff1b;条件判断函数&#xff1b;系统信息函数&#xff1b;加密函数&#xff1b;格式化函数&#xff1b; 一、数学函数 数学函数主要用于处理数字&#xff0c;包括…

【iOS】push和pop、present和dismiss

目录 前言push和poppushpop present和dismisspresentdismiss实现模态对话框代码示例 区别总结 前言 push 和 present 是两种用于导航和切换视图控制器&#xff08;ViewController&#xff09;的常用方法&#xff0c;push与present都可以推出新的界面&#xff0c;present与dismi…

使用MongoDB存储和查询数据的Python函数实现

使用MongoDB存储和查询数据的Python函数实现 MongoDB是一种流行的NoSQL数据库,因其灵活的文档存储和高性能查询能力而广受欢迎。在本文中,我们将详细介绍如何使用Python实现一个函数来存储和查询MongoDB中的数据。本文将涵盖MongoDB的基本概念、Python与MongoDB的连接、数据…

Android系统dumpsys命令详解

文章目录 1. dumpsys 的工作原理2. 基本使用方法执行 dumpsys限制 dumpsys 的输出 3. 常见的 dumpsys 服务1. Activity Manager (activity)2. Battery Service (battery)3. Window Manager (window)4. Package Manager (package)5. Power Manager (power)6. Media DRM (media.d…

tomcat服务器

tomcat简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器。Tomcat 虽然和 Apache 或者 Nginx 这些 Web 服务器一样&#xff0c;具有处理 HTML 页面的功能&#xff0c;然而由于其处理静态 HTML 的能力远不及 Apache 或者 Nginx&#x…

Collection

java.util.Collections:是集合工具类 作用&#xff1a;Collections不是集合&#xff0c;而是集合的工具类 常用API addAll package Collections;import java.util.ArrayList; import java.util.Collections;public class CollectionsDemo {public static void main(String[]…

Android Kotlin 中的 `groupBy` 方法详解

在 Kotlin 中&#xff0c;groupBy 是一个非常有用的集合操作函数。我们可以使用它按照某个标准&#xff0c;将集合中的元素分组&#xff0c;形成一个 Map&#xff0c;其中 key 是我们分组的标准&#xff0c;value 是符合这个标准的元素列表。本文将通过几个实际例子&#xff0c…

使用 Node Media Server 和 FFmpeg 创建直播流,推送本地视频

Node.js安装&#xff1a; 参考这个 Nodejs安装教程 安装完成之后&#xff0c;记得修改一下npm源&#xff1a; npm config set registry https://registry.npmmirror.com下一步&#xff0c;安装node-media-server npm install node-media-server参考这个&#xff1a;安装ffmpe…

vue-cli创建一个可以执行的vue2工程

vue-cli创建一个可以执行的vue2工程 要使用 Vue CLI 创建一个可执行的 Vue 2 工程&#xff0c;请按照以下步骤操作&#xff1a;首先&#xff0c;确保你已经安装了 Node.js 和 npm&#xff08;Node.js 包管理器&#xff09;。安装 Vue CLI。在命令行中运行&#xff1a;创建一个…

Android DPC模式多开 APP

1、修改创建多个profile时超出限制 packages/apps/ManagedProvisioning/src/com/android/managedprovisioning/preprovisioning/PreProvisioningController.java // PO preconditions if (isProfileOwnerProvisioning()) {// If there is already a managed profile, first c…

马匹行为识别系统源码分享

马匹行为识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

身份证阅读器API模式 VUE Dorado7

VUE 新框架 // 身份证扫描 readIdCard(type) {// 1.连接axios.get(http://localhost:19196/openDevice).then(res > {if (res.data.resultFlag 0) {// 2.读卡axios.get(http://localhost:19196/readCard).then((res) > {if (res.data.resultFlag 0) {// this.$message…

大模型入门3:理解LLAMA

LLama在transformers库中的代码&#xff0c;以及各部分原理Llama3.1技术报告LLama 33b 微调尝试 Model a stack of DecoderBlocks(SelfAttention, FeedForward, and RMSNorm) decoder block 整体结构&#xff1a;最大的区别在pre-norm x -> norm(x) -> attention() -…

图解Redis 02 | String数据类型的原理及应用场景

介绍 在 Redis 中&#xff0c;String 是一种重要的数据类型&#xff0c;是最基本的 key-value 结构&#xff0c;在这个结构中&#xff0c; value 是一个字符串。value 所能容纳的数据最大长度为512M。 需要注意的是&#xff0c;这里的字符串不只指文本数据&#xff0c;它还可…

【Kubernetes】常见面试题汇总(十六)

目录 48.简述 Kubernetes PodsecurityPolicy 机制能实现哪些安全策略&#xff1f; 49.简述 Kubernetes 网络模型&#xff1f; 50.简述 Kubernetes CNl 模型&#xff1f; 48.简述 Kubernetes PodsecurityPolicy 机制能实现哪些安全策略&#xff1f; 在 PodSecurityPolicy 对象…

LSTM文本预测(Pytorch版)

任务&#xff1a;基于 flare 文本数据&#xff0c;建立 LSTM 模型&#xff0c;预测序列文字 1.完成数据预处理&#xff0c;将文字序列数据转化为可用于LSTM输入的数据 2.查看文字数据预处理后的数据结构&#xff0c;并进行数据分离操作 3.针对字符串输入&#xff08;" fla…