天助可以搜索别人网站,网络营销推广方法还会有哪些,天津建站软件,双流区规划建设局官方网站文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode… 文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode6、USART_HardwareFlowControl Ⅶ、串口发送数据可变参数函数模拟实现printf Ⅷ、串口接收数据包含发送Ⅸ、USART收发数据包1、收发HEX数据包2、收发文本数据包 USART串口通信 USARTUniversal Synchronous/Asynchronous Receiver/Transmitter通用同步/异步收发器是一种用于串行通信的硬件模块它支持同步需要SCL时钟线和异步两种通信模式 Ⅰ、硬件电路 TX 为发送端 RX 为接收端若是设备之间的电平标准不一致时则需要加上电平转换芯片
Ⅱ、常见的电平标准 TTL电平 供电范围在0~5V输出 高电平1大于2.7V低电平0小于0.5V 输入 高电平1大于2.0V低电平0小于0.8V TTL电平输入脚悬空时内部认为是高电平且TTL电平输出不能驱动CMOS电平输入 CMOS电平 供电范围在3~15V输出 高电平1大于4.6V低电平0小于0.05V 输入 高电平1大于3.5V低电平0小于1.5V LVTTL电平 是TTL的一种低功耗变种供电电压通常小于等于3.3V输出 高电平1大于2.4V低电平0小于0.4V 输入 高电平1大于2.0V低电平0小于0.8V RS232电平 输出 -5~-15V 输出15~15V 输出0 输入 -3~-15V 输入13~15V 输入0 LVDS电平 低电压差分信号驱动器由驱动差分线对的电流源组成电流通常为3.5mA接收器具有很高的输入阻抗输入端允许信号上携带的直流偏置电平范围为0.227~2.173V RS485电平 采用差分传输方式输出A、B之间的电压差高电平2~6V低电平-2~-6V STM32使用的是TTL电平
Ⅲ、串口参数及时序 波特率Baud Rate 波特率是串口通信中每秒传输的符号数通常以bps位/秒为单位波特率必须在通信双方之间匹配否则会导致数据传输错误 数据位Data Bits 数据位是指每个字符中用于传输实际数据的位数常见的数据位设置有8位 停止位Stop Bits 停止位是在每个字符传输结束后用于标识字符结束的位数可以是1位、1.5位或2位停止位 奇偶校验Parity 奇偶校验是一种错误检测机制通过在数据位后面添加一个校验位来实现可以设置为无校验None、奇校验Odd、偶校验Even或标记/空格校验Mark/Space 波特率串口通信的速率 起始位标志一个数据帧的开始固定为低电平 数据位数据帧的有效载荷1为高电平0为低电平低位先行 校验位用于数据验证根据数据位计算得来 停止位用于数据帧间隔固定为高电平 一个数据帧10位 起始位1bit数据位8bit1byte停止位1bit 一个数据帧11位 起始位1bit数据位8bit校验位1bit停止位1bit 实测串口时序 Ⅳ、STM32的USART简介 USART是STM32内部集成的硬件外设可根据数据寄存器的一个字节数据自动生成数据帧时序从TX引脚发送出去也可自动接收RX引脚的数据帧时序拼接为一个字节数据存放在数据寄存器里 自带波特率发生器最高达4.5Mbits/s可据此配置通讯的波特率 可配置数据位长度无校验位8bit有校验位9bit、停止位长度0.5/1/1.5/2 确定了帧的间隔 可选校验位无校验/奇校验/偶校验 支持同步模式有时钟CLK输出、硬件流控制可控的发送和接收数据、DMA串口支持DMA转运数据、智能卡、IrDA、LIN STM32F103C8T6 USART资源 USART1挂载在上APB2总线上、 USARTAPB1、 USART3APB1 流控 nCTS: 清除发送若是高电平在当前数据传输结束时阻断下一次的数据发送判断对方是否准备好接收数据nRTS: 发送请求若是低电平表明USART准备好接收数据告诉对方自己是否准备好接收数据 TXE 和 RXNE 是判断发送状态和接收状态的重要标志位 TDR与RDR都是通过DR寄存器来实现其功能
数据帧 起始位侦测 数据采样 进行三次数据采样增加容错采样时钟是波特率的16倍
波特率发生器 发送器和接收器的波特率由波特率寄存器BRR里的DIV确定 计算公式 波特率 f P C L K 2 / 1 16 ∗ D I V 波特率 \frac{f_{PCLK2/1} }{16 * DIV} 波特率16∗DIVfPCLK2/1 解释PCLK1或PLCK2的时钟频率除以16倍的DIV DIV分为整数部分12bit和小数部分4bit整数部分高位补0小数部分低位补0
Ⅴ、USART函数介绍
// 重置指定的USART为默认值
void USART_DeInit(USART_TypeDef* USARTx);// 初始化指定的USART根据初始化结构体配置参数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
// 初始化USART初始化结构体的默认值
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
// 初始化指定的USART时钟根据时钟初始化结构体配置参数
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
// 初始化USART时钟初始化结构体的默认值
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);// 开启或关闭指定的USART
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART的中断
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);// 开启或关闭USART的DMA请求
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);// 设置USART地址
void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);// 配置USART唤醒模式
void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);// 开启或关闭USART接收器唤醒功能
void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 配置USART LIN断裂检测长度
void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);// 开启或关闭USART LIN模式
void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 通过USART发送数据
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
// 通过USART接收数据
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);// 发送USART断点信号
void USART_SendBreak(USART_TypeDef* USARTx);// 设置USART保护时间
void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);// 设置USART预分频器
void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);// 开启或关闭USART智能卡模式
void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
// 开启或关闭USART智能卡NACK应答
void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
// 开启或关闭USART半双工模式
void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART 8位过采样模式
void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);// 开启或关闭USART单线方法
void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);// 配置USART IrDA模式
void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);// 开启或关闭USART IrDA模式
void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);// 获取USART标志状态
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
// 清除USART标志
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);// 获取USART中断状态
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
// 清除USART中断待处理位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
Ⅵ、USART_InitTypeDef结构体参数
成员名称描述uint32_t USART_BaudRateUSART通信波特率使用公式计算IntegerDivider ((PCLKx) / (16 * USART_BaudRate))uint16_t USART_WordLength指定每帧传输或接收的数据位数量可以是8位、9位等取决于ref USART_Word_Lengthuint16_t USART_StopBits指定传输的停止位数量可以是1位或2位取决于ref USART_Stop_Bitsuint16_t USART_Parity指定奇偶校验模式包括奇校验、偶校验或无校验取决于ref USART_Parityuint16_t USART_Mode指定是否启用接收或发送模式取决于ref USART_Modeuint16_t USART_HardwareFlowControl指定是否启用硬件流控制模式如RTS/CTS取决于ref USART_Hardware_Flow_Control成员名称
1、USART_BaudRate
类型uint32_t无符号32位整数用途配置USART通信的波特率说明通过设置这个成员可以定义USART通信的速率即每秒传输的比特数。波特率的计算涉及到外设时钟频率PCLKx和这个成员的值。计算公式如前所述用于确定整数除数和分数除数以设置USART的时钟分频确保正确的波特率
2、USART_WordLength 类型uint16_t无符号16位整数 用途指定每帧传输或接收的数据位数量 说明这个参数决定了数据帧中数据位的长度。它可以是8位、9位等具体值取决于ref USART_Word_Length枚举 ref USART_Word_Length 配置USART通用同步/异步收发传输器的数据位长度 宏定义 USART_WordLength_8b 值((uint16_t)0x0000)描述定义了一个8位数据长度的宏。当USART配置为8位数据长度时每个数据帧包含8个数据位 USART_WordLength_9b 值((uint16_t)0x1000)描述定义了一个9位数据长度的宏。当USART配置为9位数据长度时每个数据帧包含9个数据位 宏函数 IS_USART_WORD_LENGTH(LENGTH) 描述这是一个宏函数用于检查给定的数据位长度是否有效参数LENGTH代表USART的数据位长度功能检查LENGTH是否等于USART_WordLength_8b或USART_WordLength_9b返回值如果LENGTH有效返回1真否则返回0假 表格 宏定义值描述USART_WordLength_8b0x00008位数据长度USART_WordLength_9b0x10009位数据长度 宏函数描述IS_USART_WORD_LENGTH(LENGTH)检查LENGTH是否为有效的USART数据位长度
3、USART_StopBits 类型uint16_t无符号16位整数 用途指定传输的停止位数量 说明这个参数定义了在数据帧结束后传输的停止位的数量可以是1位或2位具体值取决于ref USART_Stop_Bits枚举 ref USART_Stop_Bits 定义了USART通用同步/异步收发传输器的停止位配置 宏定义 USART_StopBits_1 值((uint16_t)0x0000)描述定义了一个1个停止位的宏。在USART通信中1个停止位是最常见的配置 USART_StopBits_0_5 值((uint16_t)0x1000)描述定义了0.5个停止位的宏。这种配置不常见主要用于某些特定的通信协议 USART_StopBits_2 值((uint16_t)0x2000)描述定义了2个停止位的宏。这种配置用于提高数据传输的可靠性特别是在噪声较大的通信环境中 USART_StopBits_1_5 值((uint16_t)0x3000)描述定义了1.5个停止位的宏。这种配置同样不常见主要用于某些特定的通信协议 宏函数 IS_USART_STOPBITS(STOPBITS) 描述这是一个宏函数用于检查给定的停止位设置是否有效参数STOPBITS代表USART的停止位设置功能检查STOPBITS是否等于USART_StopBits_1、USART_StopBits_0_5、USART_StopBits_2或USART_StopBits_1_5中的任一个返回值如果STOPBITS有效返回1真否则返回0假 表格 宏定义值描述USART_StopBits_10x00001个停止位USART_StopBits_0_50x10000.5个停止位USART_StopBits_20x20002个停止位USART_StopBits_1_50x30001.5个停止位 宏函数描述IS_USART_STOPBITS(STOPBITS)检查STOPBITS是否为有效的USART停止位设置
4、USART_Parity 类型uint16_t无符号16位整数 用途指定奇偶校验模式 说明这个参数决定了是否启用奇偶校验以及使用哪种类型的校验奇校验、偶校验或无校验。当启用校验时计算出的校验位会被插入到传输数据的最高有效位MSB位置。具体值取决于ref USART_Parity枚举 ref USART_Parity 定义了USART通用同步/异步收发传输器的奇偶校验配置 宏定义 USART_Parity_No 值((uint16_t)0x0000)描述定义了一个无奇偶校验的宏。当设置为无奇偶校验时USART通信不包含校验位 USART_Parity_Even 值((uint16_t)0x0400)描述定义了一个偶校验的宏。当设置为偶校验时USART通信中的数据帧会包含一个校验位使得数据位加上校验位的总和为偶数 USART_Parity_Odd 值((uint16_t)0x0600)描述定义了一个奇校验的宏。当设置为奇校验时USART通信中的数据帧会包含一个校验位使得数据位加上校验位的总和为奇数 宏函数 IS_USART_PARITY(PARITY) 描述这是一个宏函数用于检查给定的奇偶校验设置是否有效参数PARITY代表USART的奇偶校验设置功能检查PARITY是否等于USART_Parity_No、USART_Parity_Even或USART_Parity_Odd中的任一个返回值如果PARITY有效返回1真否则返回0假 表格 宏定义值描述USART_Parity_No0x0000无奇偶校验USART_Parity_Even0x0400偶校验USART_Parity_Odd0x0600奇校验 宏函数描述IS_USART_PARITY(PARITY)检查PARITY是否为有效的USART奇偶校验设置
5、USART_Mode 类型uint16_t无符号16位整数 用途指定是否启用接收或发送模式 说明这个参数决定了USART是处于接收模式、发送模式还是两者都启用。具体值取决于ref USART_Mode枚举 ref USART_Mode 定义了USART通用同步/异步收发传输器的工作模式 宏定义 USART_Mode_Rx 值((uint16_t)0x0004)描述定义了一个仅接收模式的宏。当设置为仅接收模式时USART仅用于接收数据 USART_Mode_Tx 值((uint16_t)0x0008)描述定义了一个仅发送模式的宏。当设置为仅发送模式时USART仅用于发送数据 宏函数 IS_USART_MODE(MODE) 描述这是一个宏函数用于检查给定的工作模式设置是否有效参数MODE代表USART的工作模式设置功能检查MODE是否为有效的接收模式、发送模式或两者的组合即接收和发送模式。它通过与0xFFF3进行按位与操作来确保只有接收和发送模式位被设置其他位应为0。同时也检查MODE不为0因为0表示没有启用任何模式返回值如果MODE有效返回1真否则返回0假 表格 宏定义值描述USART_Mode_Rx0x0004仅接收模式USART_Mode_Tx0x0008仅发送模式 宏函数描述IS_USART_MODE(MODE)检查MODE是否为有效的USART工作模式设置
6、USART_HardwareFlowControl 类型uint16_t无符号16位整数 用途指定是否启用硬件流控制模式 说明硬件流控制用于控制数据的传输速率以防止接收器溢出。这个参数决定了是否启用硬件流控制如RTS/CTS请求发送/清除发送。具体值取决于ref USART_Hardware_Flow_Control枚举 ref USART_Hardware_Flow_Control 定义了USART通用同步/异步收发传输器的硬件流控制配置 宏定义解释 USART_HardwareFlowControl_None 值((uint16_t)0x0000)描述定义了一个无硬件流控制的宏。当设置为无硬件流控制时USART通信不使用任何硬件流控制信号 USART_HardwareFlowControl_RTS 值((uint16_t)0x0100)描述定义了一个仅使用请求发送RTS信号的硬件流控制宏。RTS信号用于通知接收设备是否准备好接收数据 USART_HardwareFlowControl_CTS 值((uint16_t)0x0200)描述定义了一个仅使用清除发送CTS信号的硬件流控制宏。CTS信号用于通知发送设备是否应该开始发送数据 USART_HardwareFlowControl_RTS_CTS 值((uint16_t)0x0300)描述定义了一个同时使用RTS和CTS信号的硬件流控制宏。这种配置提供了双向的硬件流控制以确保数据传输的同步和可靠性 宏函数 IS_USART_HARDWARE_FLOW_CONTROL(CONTROL) 描述这是一个宏函数用于检查给定的硬件流控制设置是否有效参数CONTROL代表USART的硬件流控制设置功能检查CONTROL是否等于USART_HardwareFlowControl_None、USART_HardwareFlowControl_RTS、USART_HardwareFlowControl_CTS或USART_HardwareFlowControl_RTS_CTS中的任一个返回值如果CONTROL有效返回1真否则返回0假 表格 宏定义值描述USART_HardwareFlowControl_None0x0000无硬件流控制USART_HardwareFlowControl_RTS0x0100使用RTS硬件流控制USART_HardwareFlowControl_CTS0x0200使用CTS硬件流控制USART_HardwareFlowControl_RTS_CTS0x0300同时使用RTS和CTS硬件流控制 宏函数描述IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)检查CONTROL是否为有效的USART硬件流控制设置
Ⅶ、串口发送数据
#include stm32f10x.h // Device header
#include stdio.h //为了移植printf
//USART串口
//TX--PA9void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin GPIO_Pin_9;GPIO_Init(GPIOA, GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode USART_Mode_Tx;//仅发送模式USART_InitStruct.USART_Parity USART_Parity_No;//无校验USART_InitStruct.USART_StopBits USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, USART_InitStruct);//初始化USATR1USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET);
}/*************************************************************************************** 名称 Serial_SendArray* 功能 通过串口发送数组* 参数 uint16_t* Arr数组指针* 参数 uint16_t Length数组长度* 返回值 无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i 0;for(i 0;iLength;i){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称 Serial_SendString* 功能 通过串口发送字符串* 参数 char* Stringxxxxxxx* 返回值 无*****************************/
void Serial_SendString(char* String)
{while(*String ! \0){Serial_SendByte(*String);String;}
}//返回num的SQ次方内部函数
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret 1;while(SQ--)ret * num;return ret;
}
/*************************************************************************************** 名称 Serial_SendNum* 功能 通过串口发送数字* 参数 数字及数字长* 返回值 无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i 0;for(i 0; i Length; i){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) 0);//\0是为了偏移可将数字转换为其对应的ASCII字符}
}//重定向printf须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}
可变参数函数模拟实现printf
#include stdarg.hvoid Serial_Printf(char* format, ...)
{char String[200];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String);
}Ⅷ、串口接收数据包含发送
#include stm32f10x.h // Device header
#include stdio.h //为了移植printf
//USART串口
//TX--PA9
//RX--PA10uint8_t Serial_RxData 0;//接收的数据
uint8_t Serial_RxFlag 0;//标志位void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化发送GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin GPIO_Pin_9;GPIO_Init(GPIOA, GPIO_InitStruct);//初始化接收GPIOGPIO_InitStruct.GPIO_Mode GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin GPIO_Pin_10;GPIO_Init(GPIOA, GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode USART_Mode_Tx | USART_Mode_Rx;//发送接收模式USART_InitStruct.USART_Parity USART_Parity_No;//无校验USART_InitStruct.USART_StopBits USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, USART_InitStruct);//初始化USATR1//开启USART的中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//设置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置嵌套向量中断控制器NVIC的优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel USART1_IRQn;//选择IRQ通道NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;//启用这个IRQ通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;//设置抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 1;//设置响应优先级为1NVIC_Init(NVIC_InitStruct); USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET);
}/*************************************************************************************** 名称 Serial_SendArray* 功能 通过串口发送数组* 参数 uint16_t* Arr数组指针* 参数 uint16_t Length数组长度* 返回值 无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i 0;for(i 0;iLength;i){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称 Serial_SendString* 功能 通过串口发送字符串* 参数 char* Stringxxxxxxx* 返回值 无*****************************/
void Serial_SendString(char* String)
{while(*String ! \0){Serial_SendByte(*String);String;}
}//返回num的SQ次方内部函数
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret 1;while(SQ--)ret * num;return ret;
}
/*************************************************************************************** 名称 Serial_SendNum* 功能 通过串口发送数字* 参数 数字及数字长* 返回值 无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i 0;for(i 0; i Length; i){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) 0);//\0是为了偏移可将数字转换为其对应的ASCII字符}
}//重定向printf须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}
//**********************************************************************************
uint8_t Serial_GetFlag(void)//获取标志
{if(Serial_RxFlag 1){Serial_RxFlag 0;return 1;}return 0;
}uint8_t Serial_GetData(void)//获取数据
{return Serial_RxData;
}//中断函数
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1, USART_IT_RXNE) SET)//判断中断标志位{Serial_RxData USART_ReceiveData(USART1);Serial_RxFlag 1;USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}
Ⅸ、USART收发数据包
1、收发HEX数据包 包头FF 包尾FE 含包头包尾固定包长的数据包 uint8_t Serial_RxPacketFlag 0;//数据包标志位uint8_t Serial_RxPacket[4] { 0 };//接收数据包的缓冲数组...
...
//**********************************************************************************
uint8_t Serial_GetPacketFlag(void)//获取数据包标志
{if(Serial_RxPacketFlag 1){Serial_RxPacketFlag 0;return 1;}return 0;
}/*************************************************************************************** 名称 Serial_SendPacket* 功能 发送数据量为4字节的HEX数据包* 参数 Serial_RxPacket_4bt* 返回值 无*****************************/
void Serial_SendPacket(uint8_t* Serial_RxPacket_4bt)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(Serial_RxPacket_4bt, 4);//发送数据Serial_SendByte(0xFE);//发送包尾
}//中断函数
void USART1_IRQHandler(void)
{static uint8_t RxState 0;//初始化状态static uint8_t Count 0;//记录接收数据的个数if(USART_GetITStatus(USART1, USART_IT_RXNE) SET)//判断中断标志位{uint8_t RxData USART_ReceiveData(USART1);//获取数据if(RxState 0)//等待包头{if(RxData 0xFF)//接收到包头{RxState 1;//转移至状态1Count 0;}}else if(RxState 1)//接收数据{Serial_RxPacket[Count] RxData;Count;if(Count 4){RxState 2;//转移至状态2Count 0;//状态清零}}else if(RxState 2)//等待包尾{if(RxData 0xFE)//接收到包尾{RxState 0;//转移至状态0Serial_RxPacketFlag 1;//接收到数据包表标志位} }USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}
2、收发文本数据包 包头 包尾换行符 含包头包尾固定包长的数据包 #include stm32f10x.h // Device header
#include stdio.h //为了移植printf
//USART串口
//TX--PA9
//RX--PA10#define RxPacket_Length_MAX 200 //接收文本数据包的最大长度
uint8_t Serial_RxPacketFlag 0;//数据包标志位//需要手动清零char Serial_RxPacket[RxPacket_Length_MAX] { 0 };//接收文本数据包的缓冲数组void Serial_Init(void)
{//使能GPIO和USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//初始化发送GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin GPIO_Pin_9;GPIO_Init(GPIOA, GPIO_InitStruct);//初始化接收GPIOGPIO_InitStruct.GPIO_Mode GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin GPIO_Pin_10;GPIO_Init(GPIOA, GPIO_InitStruct);//配置USARTUSART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate 9600;//配置波特率USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None;//是否选择硬件流控USART_InitStruct.USART_Mode USART_Mode_Tx | USART_Mode_Rx;//发送接收模式USART_InitStruct.USART_Parity USART_Parity_No;//无校验USART_InitStruct.USART_StopBits USART_StopBits_1;//1个停止位USART_InitStruct.USART_WordLength USART_WordLength_8b;//数据帧包含8个数据位USART_Init(USART1, USART_InitStruct);//初始化USATR1//开启USART的中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//设置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置嵌套向量中断控制器NVIC的优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel USART1_IRQn;//选择IRQ通道NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;//启用这个IRQ通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;//设置抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 1;//设置响应优先级为1NVIC_Init(NVIC_InitStruct); USART_Cmd(USART1, ENABLE);//开启USART串口通信
}//发送一个字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);//发送一个字节//获取USART标志状态(等待)传输数据寄存器空标志while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET);
}/*************************************************************************************** 名称 Serial_SendArray* 功能 通过串口发送数组* 参数 uint16_t* Arr数组指针* 参数 uint16_t Length数组长度* 返回值 无*****************************/
void Serial_SendArray(uint8_t* Arr, uint16_t Length)
{uint16_t i 0;for(i 0;iLength;i){Serial_SendByte(Arr[i]);}
}/*************************************************************************************** 名称 Serial_SendString* 功能 通过串口发送字符串* 参数 char* Stringxxxxxxx* 返回值 无*****************************/
void Serial_SendString(char* String)
{while(*String ! \0){Serial_SendByte(*String);String;}
}//返回num的SQ次方内部函数
static uint32_t Serial_GetSquare(const int num, int SQ)
{uint32_t ret 1;while(SQ--)ret * num;return ret;
}
/*************************************************************************************** 名称 Serial_SendNum* 功能 通过串口发送数字* 参数 数字及数字长* 返回值 无*****************************/
void Serial_SendNum(uint32_t Num, uint8_t Length)
{uint8_t i 0;for(i 0; i Length; i){Serial_SendByte((Num / Serial_GetSquare(10, Length - i - 1) % 10) 0);//\0是为了偏移可将数字转换为其对应的ASCII字符}
}//重定向printf须勾选魔法棒中的Use MicroLlB
int fputc(int ch, FILE *stream)
{Serial_SendByte(ch);return ch;
}/*************************************************************************************** 名称 Serial_SendHEXPacket* 功能 发送数据量为4字节的HEX数据包* 参数 Serial_RxPacket_4bt* 返回值 无*****************************/
void Serial_SendHEXPacket(uint8_t* Serial_RxPacket_4bt)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(Serial_RxPacket_4bt, 4);//发送数据Serial_SendByte(0xFE);//发送包尾
}//中断函数
void USART1_IRQHandler(void)
{static uint8_t RxState 0;//初始化状态static uint8_t Count 0;//记录接收数据的个数if(USART_GetITStatus(USART1, USART_IT_RXNE) SET)//判断中断标志位{uint8_t RxData USART_ReceiveData(USART1);//获取数据if(RxState 0)//等待包头{if(RxData Serial_RxPacketFlag 0)//接收到包头(且防止传输过快导致数据错位){RxState 1;//转移至状态1Count 0;}}else if(RxState 1)//接收数据{if(RxData \r)//判断是否是包尾1{RxState 2;//转移至状态2}else{Serial_RxPacket[Count] RxData;Count;}}else if(RxState 2)//等待包尾{if(RxData \n)//接收到包尾2{RxState 0;//转移至状态0Serial_RxPacket[Count] \0;//添加结束标志位 Serial_RxPacketFlag 1;//接收到数据包标志位}}USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
} .h头文件 #ifndef __SERIAL_H__
#define __SERIAL_H__
#include stdint.hextern char Serial_RxPacket[];//接收文本数据包的缓冲数组
extern uint8_t Serial_RxPacketFlag;//数据包标志位//需要手动清零void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t* Arr, uint16_t Length);
void Serial_SendString(char* String);
void Serial_SendNum(uint32_t Num, uint8_t Length);void Serial_SendHEXPacket(uint8_t* Serial_RxPacket_4bt);//发送数据量为4字节的数据包#endif