我需要实现一个关于HAL库的stm32f103ret6的keil代码,要求如下:我需要串口接收一个标志位lock,上位机通过232串口像我发送0或者1来操控lock里面的i/o口的调用函数,且此次接收的数据不循环接收,只接收一次;后我还需要接收一个get_temp_adc();get_temp_adc()是其他C文件的,接收这里面的数据,变成adc值来控制温度,不可以使用while语句。
时间: 2024-03-16 10:41:24 浏览: 50
stm32F103串口的调试,串口2发送数据串口1接收并在串口调试助手上显示keil工程源码.zip
下面是一个基于HAL库的stm32f103ret6的keil代码,实现了您的需求:
```c
#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
UART_HandleTypeDef huart1;
/* 初始化函数 */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void) {
/* MCU初始化 */
HAL_Init();
/* 系统时钟初始化 */
SystemClock_Config();
/* GPIO初始化 */
MX_GPIO_Init();
/* USART1初始化 */
MX_USART1_UART_Init();
uint8_t lock = 0; // lock标志位
uint8_t buf[2]; // 串口接收缓存
uint8_t adc_value = 0; // ADC数值
/* 等待串口接收到lock标志位 */
while (1) {
HAL_UART_Receive(&huart1, buf, 2, 1000);
if (buf[0] == 'l' && buf[1] == 'k') {
lock = 1;
break;
}
}
/* 等待串口接收到get_temp_adc指令 */
HAL_UART_Receive(&huart1, buf, 12, 1000);
if (memcmp(buf, "get_temp_adc", 12) == 0) {
/* 调用其他C文件中的get_temp_adc函数,获取ADC数值 */
adc_value = get_temp_adc();
/* 根据ADC数值控制温度 */
// ...
}
/* 根据lock标志位操作I/O口 */
if (lock) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // I/O口输出高电平
} else {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // I/O口输出低电平
}
while (1) {
}
}
/* 系统时钟配置函数 */
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/**配置内部时钟源为8Mhz RC振荡器**/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/**配置HCLK、PCLK1和PCLK2**/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI_DIV1;
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_0) != HAL_OK) {
Error_Handler();
}
}
/* GPIO初始化函数 */
void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIOA Periph clock enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* 配置PA0为推挽输出 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USART1初始化函数 */
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();
}
}
```
需要注意的是,这里的lock标志位是通过等待串口接收到 "lk" 来实现的,您可以根据实际需要修改这部分代码。此外,通过串口接收get_temp_adc指令并调用其他C文件中的get_temp_adc函数,获取ADC数值来控制温度,可以让您的代码更加灵活和可扩展。
阅读全文