Initial import of STM32 IoT sensor node
This commit is contained in:
+193
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user