- 多串口定义prrintf
- 接受不定长字符串
- 串口发送16进制
- [ ]多串口的printf
·上篇 写了串口一重新定义为printf但是其他串口无法使用printf 在c语言中有个库为“stdarg.h”标准参数 主要目的是为了函数接收可变参数里面含有4个标准宏
#ifdef __clang__
typedef __builtin_va_list va_list;
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#if __STDC_VERSION__ >= 199900L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#endif
所以在串口的定义要包含这个头文件“stdarg.h”
串口二的printf
void Usart2_printf(char *fmt,...)
{
char buffer[USART2_TXBUFF_SIZE]; //USART2_TXBUFF_SIZE为外部定义发送的最大长度
int i = 0;
va_list arg_ptr;
va_start(arg_ptr, fmt); //初始化list
vsnprintf(buffer, USART2_TXBUFF_SIZE+1, fmt, arg_ptr); //将数据返回到buffer
while ((i < USART2_TXBUFF_SIZE) && buffer[i])
{
USART_SendData(USART2, (u8)buffer[i++]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); //判断标志为是否复位
}
va_end(arg_ptr);//arg_ptr为空释放内存
}
串口3的printf和串口二的printf差不多只要将USART2改为USART3就可以了,同理其他串口也是
- [ ]串口接受不定长字符串
方法一:使用DMA来接受(个人觉得较为麻烦,本人不使用,只是简单了解一下)
方法二:使用IDLE中断进行判断(还行,较为简单)
.。。。。。.。。。。。。主要介绍方法二
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。)
首先
要使能IDLE中断 配置如下
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate = Bound;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART3,&USART_InitStruct);
USART_Cmd(USART3,ENABLE);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
USART_ITConfig(USART3,USART_IT_IDLE,ENABLE); //IDLE中断必须使能
接下来就是接受数据的代码
int Receive3_data = 0;//串口接受的数据个数
int Receive3_flag = 0;//判断串口是否接受到数据
char USART3_Receive[125] ;//用来接受串口发来的数据
void USART3_IRQHandler(void)
{
int clear = clear;
if(USART_GetITStatus(USART3,USART_IT_RXNE) != RESET) //判断是否有数据传过来
{
USART3_Receive[Receive3_data++] = USART_ReceiveData(USART3);//接收数据
}
else if(USART_GetITStatus(USART3,USART_IT_IDLE) != RESET)
{
clear = USART3->SR;//先读sr寄存器再度dr寄存器
clear = USART3->DR;
Receive3_data = 0;
Receive3_flag = 1;
}
}
这是串口3接受不定长字符串 其他串口页雷同 稍微改动一下就可以了
- 串口发送16进制并将0x00发送数去
数据的第一位为要发送的数据的长度(data[0]为发送数据的长度)/
void Usart3_TxData(unsigned char *data)
{
int i;
while((USART3->SR&0X40)==0);
for(i = 1;i <= data[0];i ++)
{
USART3->DR = data[i];
while((USART3->SR&0X40)==0);
}
}
使用方法
Usart2_printf("%s","sdadsadsa");//就像printf使用一样