串口发送数据:
#include "stm32f10x.h" // Device header
#include "stdio.h"
#include "stdarg.h"
/**
* 函 数:串口初始化
* 参 数:无
* 返 回 值:无
*/
void Serial_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*GPIO口初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //引脚将Pin_9初始化为复用推挽输出模式
/*USART1初始化*/
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate= 9600; //波特率,
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //硬件流控制,这里关闭
USART_InitStructure.USART_Mode= USART_Mode_Tx; //串口模式 ,选择发送模式
USART_InitStructure.USART_Parity= USART_Parity_No; //奇偶校验位,选择不需要
USART_InitStructure.USART_StopBits= USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength= USART_WordLength_8b;//字长,选择8b
USART_Init(USART1,&USART_InitStructure); //读入结构体,初始化串口
USART_Cmd(USART1,ENABLE);
}
/**
* 函 数:发送字节
* 参 数:要发送的字节,字长为8位
* 返 回 值:无
*/
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
/**
* 函 数:发送数组
* 参 数:*Array:数组首地址,Length:数组长度
* 返 回 值:无
*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Array[i]);
}
}
/**
* 函 数:发送字符串
* 参 数:*String:字符串首地址
* 返 回 值:无
*/
void Serial_SendString(char *String)
{
uint16_t i;
for(i=0;String[i]!='\0';i++)
{
Serial_SendByte(String[i]);
}
}
/**
* 函 数:X的Y立方
* 参 数:X:底数 Y:次方数
* 返 回 值:Result=X^Y;
*/
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result=1;
while(Y--)
{
Result*=X;
}
return Result;
}
/**
* 函 数:发送数字
* 参 数:Number:要发送的数字 Length: 发送多少位的数字
* 返 回 值:无
*/
void Serial_SendNumber(uint32_t Number ,uint8_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+0x30);
}
}
/**
* 函 数:使用printf需要重定向的底层函数
* 参 数:保持原始格式即可,无需变动
* 返 回 值:保持原始格式即可,无需变动
*/
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch); //将printf的底层重定向到自己的发送字节函数
return ch;
}
/**
* 函 数:自己封装的prinf函数
* 参 数:format 格式化字符串
* 参 数:... 可变的参数列表
* 返 回 值:无
*/
void Serial_Printf(char *format, ...)
{
char String[100]; //定义字符数组
va_list arg; //定义可变参数列表数据类型的变量arg
va_start(arg, format); //从format开始,接收参数列表到arg变量
vsprintf(String, format, arg); //使用vsprintf打印格式化字符串和参数列表到字符数组中
va_end(arg); //结束变量arg
Serial_SendString(String); //串口发送字符数组(字符串)
}
串口发送和接收数据:
#include "stm32f10x.h" // Device header
#include "stdio.h"
#include "stdarg.h"
uint8_t Serial_RxData;
uint8_t Serial_RxFlag;
/**
* 函 数:串口初始化
* 参 数:无
* 返 回 值:无
*/
void Serial_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*GPIO口初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //将Pin_9引脚初始化为复用推挽输出模式
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //将Pin_10引脚初始化为上拉输入模式
/*USART1初始化*/
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate= 9600; //波特率,
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //硬件流控制,这里关闭
USART_InitStructure.USART_Mode= USART_Mode_Tx|USART_Mode_Rx; //串口模式 ,选择发送与接收模式
USART_InitStructure.USART_Parity= USART_Parity_No; //奇偶校验位,选择不需要
USART_InitStructure.USART_StopBits= USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength= USART_WordLength_8b; //字长,选择8b
USART_Init(USART1,&USART_InitStructure); //读入结构体,初始化串口
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能USART_IT_RXNE标志位的中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //为什么分到第二组???
NVIC_InitTypeDef NCIC_InitStructure;
NCIC_InitStructure.NVIC_IRQChannel= USART1_IRQn; //选择中断通道
NCIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //使能中断通道
NCIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2; //抢占优先级
NCIC_InitStructure.NVIC_IRQChannelSubPriority= 2; //响应优先级
NVIC_Init(&NCIC_InitStructure); //初始化NVIC
}
/**
* 函 数:发送字节
* 参 数:要发送的字节,字长为8位
* 返 回 值:无
*/
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); //等待发送完成
}
/**
* 函 数:获取收到数据标志位 1:收到 0:未收到
* 参 数:无
* 返 回 值:标志位
*/
uint8_t Serial_GetRxFlag(void)
{
if(Serial_RxFlag == 1)
{
Serial_RxFlag=0;
return 1;
}
return 0;
}
/**
* 函 数: 获取串口收到的数据
* 参 数: 无
* 返 回 值: 收到的数据
*/
uint8_t Serial_GetRxData(void)
{
return Serial_RxData;
}
/**
* 函 数:发送数组
* 参 数:*Array:数组首地址,Length:数组长度
* 返 回 值:无
*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Array[i]);
}
}
/**
* 函 数:发送字符串
* 参 数:*String:字符串首地址
* 返 回 值:无
*/
void Serial_SendString(char *String)
{
uint16_t i;
for(i=0;String[i]!='\0';i++)
{
Serial_SendByte(String[i]);
}
}
/**
* 函 数:X的Y立方
* 参 数:X:底数 Y:次方数
* 返 回 值:Result=X^Y;
*/
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result=1;
while(Y--)
{
Result*=X;
}
return Result;
}
/**
* 函 数:发送数字
* 参 数:Number:要发送的数字 Length: 发送多少位的数字
* 返 回 值:
*/
void Serial_SendNumber(uint32_t Number ,uint8_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+0x30);
}
}
/**
* 函 数:使用printf需要重定向的底层函数
* 参 数:保持原始格式即可,无需变动
* 返 回 值:保持原始格式即可,无需变动
*/
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch); //将printf的底层重定向到自己的发送字节函数
return ch;
}
/**
* 函 数:自己封装的prinf函数
* 参 数:format 格式化字符串
* 参 数:... 可变的参数列表
* 返 回 值:无
*/
void Serial_Printf(char *format, ...)
{
char String[100]; //定义字符数组
va_list arg; //定义可变参数列表数据类型的变量arg
va_start(arg, format); //从format开始,接收参数列表到arg变量
vsprintf(String, format, arg); //使用vsprintf打印格式化字符串和参数列表到字符数组中
va_end(arg); //结束变量arg
Serial_SendString(String); //串口发送字符数组(字符串)
}
/**
* 函 数:USART1的中断函数
* 参 数:无
* 返 回 值:无
*/
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET ) //判断是否由USART_IT_RXNE标志位产生的中断
{ //SET表示USART_IT_RXNE产生中断
Serial_RxData= USART_ReceiveData(USART1); //取出收到的数据
Serial_RxFlag=1; //标志位置1表示收到数据 0则表示未收到数据
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断挂起标志位
}
}
串口发送HEX数据包:
#include "stm32f10x.h" // Device header
#include "stdio.h"
#include "stdarg.h"
uint8_t Serial_RxFlag;
uint8_t Serial_RxPacket[] = {0,0,0,0};
uint8_t Serial_TxPacket[] = {0,0,0,0};
/**
* 函 数:串口初始化
* 参 数:无
* 返 回 值:无
*/
void Serial_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*GPIO口初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //将Pin_9引脚初始化为复用推挽输出模式
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/*USART1初始化*/
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate= 9600; //波特率,
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //硬件流控制,这里关闭
USART_InitStructure.USART_Mode= USART_Mode_Tx|USART_Mode_Rx; //串口模式 ,选择发送与接收模式
USART_InitStructure.USART_Parity= USART_Parity_No; //奇偶校验位,选择不需要
USART_InitStructure.USART_StopBits= USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength= USART_WordLength_8b; //字长,选择8b
USART_Init(USART1,&USART_InitStructure); //读入结构体,初始化串口
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能USART_IT_RXNE标志位的中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //为什么分到第二组???
NVIC_InitTypeDef NCIC_InitStructure;
NCIC_InitStructure.NVIC_IRQChannel= USART1_IRQn; //选择中断通道
NCIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //使能中断通道
NCIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2; //抢占优先级
NCIC_InitStructure.NVIC_IRQChannelSubPriority= 2; //响应优先级
NVIC_Init(&NCIC_InitStructure); //初始化NVIC
}
/**
* 函 数:发送字节
* 参 数:要发送的字节,字长为8位
* 返 回 值:无
*/
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); //等待发送完成
}
/**
* 函 数:获取收到数据标志位 1:收到 0:未收到
* 参 数:无
* 返 回 值:标志位
*/
uint8_t Serial_GetRxFlag(void)
{
if(Serial_RxFlag == 1)
{
Serial_RxFlag=0;
return 1;
}
return 0;
}
/**
* 函 数: 获取串口收到的数据
* 参 数: 无
* 返 回 值: 收到的数据
*/
/**
* 函 数:发送数组
* 参 数:*Array:数组首地址,Length:数组长度
* 返 回 值:无
*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Array[i]);
}
}
/**
* 函 数:发送字符串
* 参 数:*String:字符串首地址
* 返 回 值:无
*/
void Serial_SendString(char *String)
{
uint16_t i;
for(i=0;String[i]!='\0';i++)
{
Serial_SendByte(String[i]);
}
}
/**
* 函 数:发送数据包
* 参 数:无
* 返 回 值:无
*/
void Serial_SendPacket()
{
Serial_SendByte(0xFF); //发送包头
Serial_SendArray(Serial_TxPacket, 4); //发送数据
Serial_SendByte(0xFE); //发送包尾
}
/**
* 函 数:X的Y立方
* 参 数:X:底数 Y:次方数
* 返 回 值:Result=X^Y;
*/
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result=1;
while(Y--)
{
Result*=X;
}
return Result;
}
/**
* 函 数:发送数字
* 参 数:Number:要发送的数字 Length: 发送多少位的数字
* 返 回 值:
*/
void Serial_SendNumber(uint32_t Number ,uint8_t Length)
{
uint16_t i;
for(i=0;i<Length;i++)
{
Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+0x30);
}
}
/**
* 函 数:使用printf需要重定向的底层函数
* 参 数:保持原始格式即可,无需变动
* 返 回 值:保持原始格式即可,无需变动
*/
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch); //将printf的底层重定向到自己的发送字节函数
return ch;
}
/**
* 函 数:自己封装的prinf函数
* 参 数:format 格式化字符串
* 参 数:... 可变的参数列表
* 返 回 值:无
*/
void Serial_Printf(char *format, ...)
{
char String[100]; //定义字符数组
va_list arg; //定义可变参数列表数据类型的变量arg
va_start(arg, format); //从format开始,接收参数列表到arg变量
vsprintf(String, format, arg); //使用vsprintf打印格式化字符串和参数列表到字符数组中
va_end(arg); //结束变量arg
Serial_SendString(String); //串口发送字符数组(字符串)
}
/**
* 函 数:USART1的中断函数
* 参 数:无
* 返 回 值:无
*/
void USART1_IRQHandler(void)
{
static uint8_t Rx_State =0; //静态变量 仅在此函数有效
static uint8_t pRxPacket =0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET )//判断是否由USART_IT_RXNE标志位产生的中断
{ //SET表示收到数据,RESET表示未收到数据
uint8_t RxData = USART_ReceiveData(USART1); //将收到的数据传给RxData
/*使用状态机来进行数据接收处理*/
if(Rx_State == 0) //状态0
{
if(RxData == 0xFF) //判断是否接收到包头
{
Rx_State = 1; //接收到包头 状态切换为1
pRxPacket= 0; //数据接收数组下标清零
}
}
else if(Rx_State == 1) //状态1 接收数据
{
Serial_RxPacket[pRxPacket] = RxData; //将接收到的数据缓存到Serial_RxPacket数组
pRxPacket++; //数据写入到数组后自动移位
if(pRxPacket == 3) //一个数据包的数据写入完成
{
Rx_State = 2; //切换为状态2
}
}
else if(Rx_State == 2) //状态2
{
if(RxData == 0xFE) //判断是否收到包尾
{
Rx_State = 0; //切换为状态0 为接收下一个数据包做准备
Serial_RxFlag = 1; //数据包接收完毕 标志位置1
}
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //手动清除终端挂起标志位
}
串口发送文本数据包: