STM32之串口移植(在固定的条件下才会进行编译)

stm串口函数在某些条件下想要让其串口打印,但是在某些时候不想让其进行串口打印

本例程就是提供了一个这样的例程:

1.对串口进行初始化配置

void uart_initwBaudRate(void)
	{
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	UART_InitTypeDef UART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
    
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE);	//使能UART2,GPIOA时钟
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 
    //UART2 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = UART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
    
    //UART 初始化设置
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);
    
	UART_InitStructure.UART_BaudRate = BaudRate;//串口波特率
	UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式
	UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位
	UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位
	UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制
	UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;	//收发模式
    
	UART_Init(UART2, &UART_InitStructure); //初始化串口1
	//UART2->BRR = 9;
	UART_ITConfig(UART2, UART_IT_RXIEN, ENABLE);//开启串口接受中断
	UART_ITConfig(UART2, UART_IT_TXIEN, DISABLE);
	UART_Cmd(UART2, ENABLE);                    //使能串口1 
    
	//UART2_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
	
  //UART2_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
		
	//printf("uart ok");
	
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_3);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_3);

	//RTS
  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//CTS
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_ResetBits(GPIOB, GPIO_Pin_7);
    
}

2.串口中断函数:

void UART2_IRQHandler(void)                	//串口1中断服务程序
{
	if(UART_GetITStatus(UART2, UART_IT_RXIEN)  != RESET)  //接收中断
	{
		UART_ClearITPendingBit(UART2,UART_IT_RXIEN);
		rxBuf[RxCont]=UART_ReceiveData(UART2);//串口2接受数据放在rxbuf
		RxTimeout = SysTick_Count + 1000;
		RxCont++;//接受数据的数量+1
		if(RxCont >= MAX_SIZE)//判断是否到达最大数量
		{
			RxCont = 0;//如果满了清0
		}
	}
	if(UART_GetITStatus(UART2, UART_IT_TXIEN)  != RESET)
	{
		UART_ClearITPendingBit(UART2,UART_IT_TXIEN);
		
		//
		TxTimeout = SysTick_Count + (20000/BaudRate);
		
		if (PosW < txLen)
		{
			UART_SendData(UART2,txBuf[PosW++]);
			
			
			if (PosW == txLen)
			{
				txLen = 0;
				PosW = 0;
			}
		}
		else
		{
			UART_ITConfig(UART2, UART_IT_TXIEN, DISABLE);
		}
	}
}

3.串口发送函数:

void  Usart2SendByte(char *data,u8 len)//发送一个字节 硬件连接选用的为USART2
    {	
            u8 t=0;
            for(t=0;t<len;t++)
            {
                RX_DATA_BUFF[t]=data[t];
                while((UART2->CSR&0x1)==0);//循环发送,直到发送完毕   while((UART1->SR&0X40)==0);//等待发送结束
                UART2->TDR=RX_DATA_BUFF[t];
            }
            UART_RX_STA=0;
        
    }

由函数3来进项串口数据的打印也是可以的,但是不能让其在某些时候不打印,本例程想要的结果就是让其在某些条件之下进行选择性的打印

 

4.一下是本次主要讲解的函数:

 void printf_uart(char *fmt,...)
 {
	 long  length = 0;
	 va_list ap;
	 char  *pt;
     int index = 0;
	 
	 va_start(ap,fmt);
	 vsprintf((char *)gPrintString,(const char *)fmt,ap);
	 pt = &gPrintString[0];
	 while(*pt!='\0') 
	 {
		 length++;
		 pt++;
	 }

    while(1)
    {
            Usart2SendByte(((char *)&gPrintString[index]), 1);
            index ++;
            if(index == length)
                break;
    }
     
	 //FuartSend((u8*)&gPrintString[0],length);
	 va_end(ap);
 } 
/*在上面的函数中
va_list(va_list是在C语言中解决变参问题的一组宏)
va_list表示可变参数列表类型,实际上就是一个char指针fmt


然后是va_start:va_start用于获取函数参数列表中可变的头指针
(获取函数可变参数列表)
1.输出参数为ap,类型为va_list:
用于保存函数参数列表中可变参数的头指针(
即可变参数列表)
2.输入参数fmt,ap指向fmt后面的参数,
为第一个参数的前一个参数,是一个固定参数

vsprintf((char *)gPrintString, fmt, ap):
送格式化输出到串中 ,函数说明:
vsprintf()会根据参数fmt 字符串来转换并格式化数据, 
然后将结果复制到参数char(*)gPrintString 的字符串数组,
直到出现字符串结束('\0')为止.
va_end():va_end用于结束对可变参数的处理。

对于这段代码的理解:
 printf函数首先定义了一个char指针fmt,
然后后面紧跟的是printf的变参,那么变参转换就开始了,
下一个函数va_start定义了一个指向变参的首指针args,
紧接着利用vsprintf函数,按照fmt格式以及通过args指针,
将变参一个个按照规定好的格式转换数据,
结果复制到char(*)gPrintString这个数组中,
最后结束可变参数处理。
这里我对于fmt这个指针的理解是,定义了一个指针类型,
转换结果就是按照这个指针的类型转换的,
这里转换的结果就是将变参转换成char字符型
就是字符串转换到一个数组中

*/

上面的函数在进行串口打印时候每次打印一个字符的,转化一个就打印一个

5.下面的函数为串口选择性打印函数

#define DisplayATCMD(_x)           if (!GetConnectedStatus()) do { printf_uart _x; } while(0)

上面的函数的选择性打印为当GetConnectedStatus()==0的时候,才会进行do   while(0)循环,但是为0,所以就会执行一次do后面的语句,因此可以实现选择性的打印,打印函数为 DisplayATCMD("123456789")  

 

 

 

本人也是小白,希望有错误的地方大家给指出来,及时修正共同进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值