Job_SignsPads/STM32/Code/STM32F405/Application/usart.c
2025-04-22 10:29:37 +08:00

319 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "main.h"
// 串口1 是和ESP32通讯 串口2 是和PC通讯和查看Log
uint8_t USART1_RX_BUF[USART1_REC_LEN]; // 接收缓冲,最大USART_REC_LEN个字节.
uint32_t USART_RX_Length = 0; // bit15接收完成标志,bit13~0 接收到的有效字节数目
uint8_t USART2_RX_BUF[USART2_REC_LEN]; // 接收缓冲,最大USART_REC_LEN个字节.
uint32_t USART2_RX_STA = 0; // bit15接收完成标志,bit13~0 接收到的有效字节数目
uint8_t USART_DealFlag = 0; // 接收完成标志
//////////////////////////////////////////////////////////////////////////////////
// 如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h" //ucos 使用
#endif
//////////////////////////////////////////////////////////////////
// 加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
// 标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
// 定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
// 重定义fputc函数
int fputc(int ch, FILE *f)
{
USART_SendData(USART2, (uint8_t)ch); // 将字符强制转换为无符号整型
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
; // 检测
return ch;
}
#endif
void USART1_SendData(uint8_t *s, uint16_t lenth)
{
for (uint32_t i = 0; i < lenth; i++)
{
UART_SendByte(USART1, (uint8_t)s[i]);
}
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
;
}
void USART2_SendData(uint8_t *s, uint16_t lenth)
{
for (uint32_t i = 0; i < lenth; i++)
{
UART_SendByte(USART2, (uint8_t)s[i]);
}
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
;
}
void UART_SendByte(USART_TypeDef *USARTx, u8 SendData)
{
USART_SendData(USARTx, SendData);
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
;
}
// 初始化IO 串口1
// bound:波特率
void uart_init(u32 bound)
{
// GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1时钟
// 串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); // GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); // GPIOA10复用为USART1
// USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA9PA10
// USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound; // 波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
USART_Init(USART1, &USART_InitStructure); // 初始化串口1
USART_Cmd(USART1, ENABLE); // 使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 开启相关中断
#if USART_IDLE_IRQ_ENABLE
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 开启相关中断
#endif
// Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
}
// 初始化IO 串口2
// bound:波特率
void uart_init_2(u32 bound)
{
// GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 使能USART2时钟
// 串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // GPIOA2复用为USART2
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // GPIOA3复用为USART2
// USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // GPIOA2与GPIOA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA2PA3
// USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound; // 波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
USART_Init(USART2, &USART_InitStructure); // 初始化串口1
USART_Cmd(USART2, ENABLE); // 使能串口2
USART_ClearFlag(USART2, USART_FLAG_TC);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启相关中断
// Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // 串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
}
// void USART1_IRQHandler(void) //串口1中断服务程序--WIFI
// {
// u8 data;
// static uint16_t length = 0;
// static unsigned char pMem[2];
// #ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
// OSIntEnter();
// #endif
// if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
// {
// USART_ClearITPendingBit(USART1, USART_IT_RXNE); //只USART_ReceiveData也可以
// data = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据
// USART_SendData(USART2, data);
// while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
// ;
// if ((USART_RX_Length & 0x8000) == 0) //接收未完成
// {
// uart_flg = 1;
// USART1_RX_BUF[USART_RX_Length & 0X3FFF] = data;
// if (USART_RX_Length == 3) //有数据长度
// {
// pMem[0] = USART1_RX_BUF[2];
// pMem[1] = USART1_RX_BUF[3];
// uint16_t *p = (uint16_t *)pMem;
// length = *p;
// }
// USART_RX_Length++;
// if (USART_RX_Length > (USART1_REC_LEN - 1))
// {
// USART_RX_Length = 0; //接收数据错误,重新开始接收
// }
// if ((0xA5 == USART1_RX_BUF[0]) && (0x5A == USART1_RX_BUF[1]) &&
// ((USART_RX_Length == length + 4) || (USART1_RX_BUF[4] == 0x10))) //帧头正确,长度正确
// {
// USART_RX_Length |= 0x8000; //接收到结束符
// wifi_cmd_exe(); //通讯交流
// }
// else if ((0xA5 != USART1_RX_BUF[0]))
// {
// USART_RX_Length = 0;
// USART1_RX_BUF[0] = 0;
// memset(USART1_RX_BUF, 0, sizeof(USART1_RX_BUF));
// }
// }
// }
// #ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
// OSIntExit();
// #endif
// }
/**
* @function:USART1_IRQHandler
* @brief: USART1空闲中断
* @return {*}
* @author: lzc
*/
#if USART_IDLE_IRQ_ENABLE
void USART1_IRQHandler(void)
{
// u8 data;
static uint16_t length = 0;
static unsigned char pMem[2];
if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_ORE); // 清除溢出中断
}
// 接收中断的时候收集数据包
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 只USART_ReceiveData也可以
// 如果处理完成,继续接收
if (USART_DealFlag == 0)
{
// data = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据
// USART_SendData(USART2, data);
// while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
// ;
USART1_RX_BUF[USART_RX_Length] = USART_ReceiveData(USART1);
USART_RX_Length++;
}
}
// 空闲中断的时候说明串口没数据了,收集完成
else if (USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
{
USART1->SR;
USART1->DR;
// 标志位置1需要进行处理
USART_DealFlag = 1;
}
}
#endif
/**
* @function: USART1_IRQHandler
* @brief: 定时器超时中断
* @return {*}
* @author: lzc
*/
#if USART_TIMER_IRQ_ENABLE
void USART1_IRQHandler(void)
{
static uint16_t length = 0;
static unsigned char pMem[2];
if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{
USART_ReceiveData(USART1);
USART_ClearFlag(USART1, USART_FLAG_ORE); // 清除溢出中断
}
// 接收中断的时候收集数据包
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 只USART_ReceiveData也可以
// 如果处理完成,继续接收
if (USART_DealFlag == 0)
{
Time.CountNum = 0;
TIM_Cmd(TIM4, ENABLE); // 启动定时器
TIM_Cmd(TIM5, DISABLE); // 串口接收到,停止计算
USART1_RX_BUF[USART_RX_Length] = USART_ReceiveData(USART1);
USART_RX_Length++;
}
}
}
#endif
void USART2_IRQHandler(void) // 串口2中断服务程序--串口
{
u8 data;
#ifdef OS_TICKS_PER_SEC // 如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)
{
USART_ReceiveData(USART2);
USART_ClearFlag(USART2, USART_FLAG_ORE); // 清除溢出中断
}
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // 接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
data = USART_ReceiveData(USART2); //(USART1->DR); //读取接收到的数据
if ((USART2_RX_STA & 0x8000) == 0) // 接收未完成
{
if ((data == 0x0A) || (data == 0x0D))
{
USART2_RX_STA |= 0x8000; // 接收到结束符
// sys_cmd_exe(); // 通讯交流
}
else
{
USART2_RX_BUF[USART_RX_Length & 0x3FFF] = data;
USART2_RX_STA++;
if (USART2_RX_STA > (USART2_REC_LEN - 1))
{
USART2_RX_STA = 0; // 接收数据错误,重新开始接收
}
}
}
}
}