STM32L151 UART串口参数与接收不定长度数据

UART是单片机的一种重要的通信接口,通信参数涉及到波特率、数据长度、奇偶校验、停止位。
工业上往往有要求在线修改(无需重启单片机)串口通信参数的要求,同时对奇偶校验也有要求,除无校验、奇校验、偶校验外,还有MARK校验和SPACE校验:

void bsp_SetUartBaud(COM_PORT_E _ucPort,uint32_t _baud,uint16_t _wordLen, uint16_t _parity, uint16_t _stopBits)
{
	USART_InitTypeDef USART_InitStructure;
	
	
	USART_InitStructure.USART_BaudRate = _baud;

	if (_parity==0)
	{
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		USART_InitStructure.USART_Parity = USART_Parity_No ;
	}
	else if (_parity==1)
	{
		if (_wordLen==7)
		{
			USART_InitStructure.USART_WordLength = USART_WordLength_8b;
			USART_InitStructure.USART_Parity = USART_Parity_Odd ;
		}
		else
		{
			USART_InitStructure.USART_WordLength = USART_WordLength_9b;
			USART_InitStructure.USART_Parity = USART_Parity_Odd ;
		}
	}
	else if (_parity==2)
	{
		if (_wordLen==7)
		{
			USART_InitStructure.USART_WordLength = USART_WordLength_8b;
			USART_InitStructure.USART_Parity = USART_Parity_Even ;
		}
		else
		{
			USART_InitStructure.USART_WordLength = USART_WordLength_9b;
			USART_InitStructure.USART_Parity = USART_Parity_Even ;
		}
	}
	else if (_parity==3)//Mark校验
	{
		USART_InitStructure.USART_WordLength = USART_WordLength_9b;
		USART_InitStructure.USART_Parity = USART_Parity_No ;		
	}
	else if (_parity==4)//Space校验
	{
		USART_InitStructure.USART_WordLength = USART_WordLength_9b;
		USART_InitStructure.USART_Parity = USART_Parity_No ;		
	}
	

	
	if (_stopBits==1)
		USART_InitStructure.USART_StopBits = USART_StopBits_1;
	else
		USART_InitStructure.USART_StopBits = USART_StopBits_2;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
	switch (_ucPort)
	{
		case COM1:USART_Init(USART1, &USART_InitStructure);break;
		case COM2:USART_Init(USART2, &USART_InitStructure);break;
		case COM3:USART_Init(USART3, &USART_InitStructure);break;
		case COM4:USART_Init(UART4, &USART_InitStructure);break;
		case COM5:USART_Init(UART5, &USART_InitStructure);break;
		default:USART_Init(USART1, &USART_InitStructure);break;
	}	
}

void COM_SendString(COM_PORT_E _ucPort, uint8_t* Data,u16 Len,uint16_t Parity)
{
	uint16_t i=0;
	USART_TypeDef *pUart;

	pUart = ComToUart(_ucPort);
	if (pUart == 0)
	{
		return;
	}
	
	USART_ClearFlag(pUart,USART_FLAG_TC);
	for(i=0;i<Len;i++)
	{
		switch (Parity)
		{
			case 3:USART_SendData(pUart,  0x100 | *Data);break;//MARK校验
			case 4:USART_SendData(pUart,  0xFF  & *Data);break;//SPACE校验
			default:USART_SendData(pUart, *Data);break;
		}
		while( USART_GetFlagStatus(pUart, USART_FLAG_TC) == RESET );
		Data++;
	}
}

另外,串口在接收数据时,数据的长度是不固定的,这种情况下就要使用IDLE中断。
IDLE中断是在串口接收完一串完整数据后,电平归0一段时间(不同波特率下这段时间会有区别)产生的中断,IDLE中断的产生代表数据传输过程完毕:

static void InitHardUart(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

#if UART1_FIFO_EN == 1		/* 串口1 TX = PA9   RX = PA10 或 TX = PB6   RX = PB7*/

	/* 第1步:打开GPIO和USART部件的时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	/* 第2步:将USART Tx的GPIO配置为推挽复用模式 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* 第3步:将USART Rx的GPIO配置为浮空输入模式
		由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
		但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
	*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* 第4步: 配置串口硬件参数 */
	USART_InitStructure.USART_BaudRate = UART1_BAUD;	/* 波特率 */
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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);

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	/* 使能接收中断 */
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);	/* 使能IDLE中断 */
	/*
		USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
		注意: 不要在此处打开发送中断
		发送中断使能在SendUart()函数打开
	*/
	USART_Cmd(USART1, ENABLE);		/* 使能串口 */

	/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
		如下语句解决第1个字节无法正确发送出去的问题 */
//	USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清发送完成标志,Transmission Complete flag */
#endif
}

void USART1_IRQHandler(void)
{
	uint8_t clear;
	
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) 
	{
		USART_ClearITPendingBit(USART1,USART_IT_RXNE); 
		if (RxCount1 >=UART1_RX_BUF_SIZE)
			RxCount1=0;
		g_RxBuf1[RxCount1] = USART_ReceiveData(USART1); 		
		RxCount1++;
	}
	if (USART_GetITStatus(USART1,USART_IT_IDLE) != RESET) 
	{
		clear=USART1->SR;
		clear=USART1->DR;
		RecvFinished1=1;
	}
	if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET) 
	{		
	  USART_ClearFlag(USART1,USART_FLAG_ORE); 
	  USART_ReceiveData(USART1);
	} 
}


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值