stm32 hal库 串口显示ds18b20 Pa3为ds18b20的gpio引脚 KEY4为pb4 使用串口3 115200波特率。编写程序,实现以下功能。 使用终端A上的扩展IO口PA3连接DS18B20温度传感器。 每当按键ASW4按下,通过串口上报温度数据一次,温度发送格式: "C:25.26\r\n" 串口发送格式(字符串) 备注: C为大写字母,温度值结果保留小数点后2位有效数字。 串口发送的字符串应包含换行、回车符号:"\r\n"。
时间: 2024-03-16 07:46:56 浏览: 67
好的,这是一个比较具体的问题,需要用到STM32的HAL库。以下是代码实现的步骤:
1. 首先,需要在 CubeMX 中配置串口3,并初始化PA3和PB4引脚的GPIO设置,以及中断模式下的按键输入设置。
2. 在代码中使用下面的代码初始化串口3:
```
/* 串口3初始化 */
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();
}
```
3. 在主函数中,使用下面的代码初始化DS18B20的GPIO引脚:
```
/* 初始化DS18B20引脚 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
```
4. 接下来,需要使用DS18B20的协议进行温度读取。这里可以使用OneWire协议,其实现方式如下:
```
/* OneWire协议读取DS18B20温度 */
float read_temp()
{
uint8_t data[2];
float temp;
// Step 1. 发送复位脉冲
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_Delay(480);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(60);
// Step 2. 等待DS18B20发出应答信号
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_Delay(60);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(20);
// Step 3. 读取DS18B20的温度数据
HAL_UART_Transmit(&huart3, (uint8_t*) "read_temp\n", 10, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_Delay(3);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(15);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_Delay(3);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(15);
HAL_UART_Transmit(&huart3, (uint8_t*) "reading...\n", 11, 1000);
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_RESET); // 等待DS18B20拉低总线
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_SET); // 等待DS18B20拉高总线
for (uint8_t i = 0; i < 2; i++) {
for (uint8_t j = 0; j < 8; j++) {
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_RESET); // 等待DS18B20拉低总线
HAL_Delay(1);
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_SET) {
data[i] |= (1 << j);
}
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_SET); // 等待DS18B20拉高总线
}
}
// Step 4. 计算温度值
temp = (float)(data[1] << 8 | data[0]) / 16.0;
return temp;
}
```
5. 接下来,需要编写中断服务函数,当按键ASW4按下时,触发中断,并通过串口发送温度数据:
```
/* 中断服务函数:按键ASW4按下 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_4) {
float temp = read_temp();
char buffer[16];
sprintf(buffer, "C:%.2f\r\n", temp);
HAL_UART_Transmit(&huart3, (uint8_t*) buffer, strlen(buffer), 1000);
}
}
```
6. 最后,在主函数中开启中断,并进入while循环:
```
/* 开启按键中断 */
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
/* 进入while循环 */
while (1)
{
}
```
这样就完成了基于STM32 HAL库的DS18B20温度传感器读取和串口发送的代码实现。
阅读全文