Initial import of STM32 IoT sensor node

This commit is contained in:
yzfh
2026-10-19 15:47:18 +08:00
commit a51794b022
100 changed files with 46274 additions and 0 deletions
+193
View File
@@ -0,0 +1,193 @@
#include "usart1.h"
static struct queue usart1_rx_queue;
/*
* IO 管脚
* 接收管脚 PA10 USART1_RX (悬空输入)
* 发送管脚 PA9 USART1_TX (复用推挽输出)
* 另外一个线 VSS(共地)
*/
// 初始化 usart1, baud 为波特率
void usart1_init(uint32_t baud)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// 初始化接收队列
queue_init(&usart1_rx_queue);
// 使能 PA9 和 PA10 的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 使能 USART1 外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 设置 PA9 为发送管脚
// 复用推挽输出
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 设置 PA10 为接收管脚
// 悬空输入
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 初始化 USART1 控制器
// 设置波特率
USART_InitStruct.USART_BaudRate = baud;
// 字长 8bit
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
// 停止位 1bit
USART_InitStruct.USART_StopBits = USART_StopBits_1;
// 校验位(无)
USART_InitStruct.USART_Parity = USART_Parity_No;
// 收发
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 硬件流控制(无)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStruct);
// 使能串口 1
USART_Cmd(USART1, ENABLE);
// 初始化接受中断(暂不接收)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 清除中断标志位
USART_ClearFlag(USART1, USART_FLAG_TC);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 中断通道
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 开启接收寄存器非空中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
// 编写冲断处理函数
void USART1_IRQHandler(void)
{
uint8_t ch;
// 如果是接收寄存器非空中断,则读取数据
if (USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)
{
ch = USART_ReceiveData(USART1);
// 将接收到的字符放入接收队列
// 如果队列已满会丢掉此字节
queue_enqueue(&usart1_rx_queue, ch);
}
}
// 用于串口发送一个字节的数据
void usart1_put_char(uint8_t ch)
{
// 发送数据
USART_SendData(USART1, ch);
// 等待发送数据完毕
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
}
// 用于串口发送一段数据,遇到 '\0' 结束
void usart1_output(const char *buf)
{
const char *pchar;
for (pchar = buf; *pchar; ++pchar)
{
usart1_put_char((uint8_t)*pchar);
}
}
// 用于串口发送一段数据,遇到 '\0' 结束,末尾添加 '\r\n' 换行符结束
void usart1_output_aline(const char *buf)
{
usart1_output(buf);
usart1_output("\r\n");
}
// 从串口读取一行数据放入 buf, buf 的最大长度为 buf_len
int usart1_input(char *buf, int buf_len)
{
int i = 0;
int ch = '\0';
for (i = 0; i < buf_len - 1; i++)
{
if (queue_is_empty(&usart1_rx_queue))
{
delay_ms(1);
if (queue_is_empty(&usart1_rx_queue))
{
break;
}
}
queue_dequeue(&usart1_rx_queue, &ch);
buf[i] = ch;
}
buf[i] = '\0';
return i;
}
// 从串口读取一行数据放入 buf, 当遇到 '\r\n' 时结束读取,并添加尾零 '\0'
int usart1_input_aline(char *buf, int buf_len)
{
int i;
int ch = '\0';
for ( i = 0; i < buf_len; i++)
{
// 等待,直到有数据读取
while (queue_is_empty(&usart1_rx_queue))
{
delay_ms(1);
}
queue_dequeue(&usart1_rx_queue, &ch);
buf[i] = ch;
// 遇到换行符
if (ch == '\n')
{
buf[i] = '\0';
// 检查前一个字符是否是回车符
if (i >= 1 && buf[i - 1] == '\r')
{
i--;
buf[i] = '\0';
}
break;
}
}
return i;
}
// 清空串口的接收队列
void usart1_clear_rx_queue(void)
{
}
// 添加 fputc 函数,实现 printf 重定向
int fputc(int ch, FILE *f)
{
usart1_put_char(ch);
return ch;
}
// 添加 fgetc 函数,实现 scanf 重定向
int fgetc(FILE *f)
{
int ch = '\0';
while (queue_is_empty(&usart1_rx_queue))
{
delay_ms(1);
}
queue_dequeue(&usart1_rx_queue, &ch);
return ch;
}