STM32—串口发送于接收

目录

串口通讯

配置

1、初始化IO口

 2、初始化串口

1——发送一个字节

2——发送数组

3——发送字符串

4——发送半字

5——串口的重定向

中断配置

串口通讯

        串口通讯 (Serial Communication) 是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此 大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试 信息。

        所以很有必要去了解串口。

配置

        既然想要使用串口,那么就需要懂得配置,只有配置出我们想要的,才能保证设备之间的通讯。

         首先,寻找到与串口相对于的IO口,这里我以PA9,PA10,为例。

1、初始化GPIO口

USART_GPIO_Config()
{

    GPIO_InitTypeDef	GPIO_InitStruct ;
	
    //使能时钟一定要提前,不然会出现乱码的情况
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP ;	//复用输出,根据手册得出
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA, &GPIO_InitStruct );
	
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING ;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	
	GPIO_Init(GPIOA, &GPIO_InitStruct );
	
	USART_InitTypeDef	USART_InitStruct;
}

         串口的发送端口配置模式:复用输出,配置其他的模式会出现乱码。

        串口的接收端口配置模式:浮空输入,因为是接收端口。

 2、初始化串口

USART_Config()
{
    USART_InitTypeDef	USART_InitStruct;
	
	
    //下面的配置都是依据通讯设备之间的约定来配置的,二者必须约定一致,否则会出现乱码
	USART_InitStruct.USART_BaudRate=115200;//

	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( USART1,&USART_InitStruct);
	
	NVIC_Config();//中断初始化
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//当符合条件就进入中断
	
	USART_Cmd(USART1,ENABLE);//最后一步,使能串口
}

        这样只是把串口配置好了,但是二者的协议还没写好,对于STM32来说,只要调用相应的函数就可以。

        想要对方能接收数据,那么二者检验位、停止位、波特路等等都是必须一致的,这样传输的数据才能是准确无误的。

1——发送一个字节

void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,ch);
		
	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

         对于STM32来说,好多底层的代码都是已经写好了,我们只需要调用即可,比如上面的发送一个字节,等待发送字节完成。

2——发送数组


void USART_SendArray(USART_TypeDef* USARTx,uint8_t *array,uint16_t num)
{
	uint8_t i;
	for(i=0;i<num;i++)
	{
		USART_SendByte(USARTx,array[i]);
	}
	while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)== RESET);
}

         对于多个数据来说,等待的时间就不是说字节等待了,而是直接等待数据发送完成。

3——发送字符串

void USART_SendString(USART_TypeDef* USARTx,char *str)
{
	unsigned int i=0;
	
	while(*(str+i)!='\0')
	{
		USART_SendByte(USARTx,*(str+i));
		i++;
	}
	while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)== RESET);
}

         因为字符串的结尾标志就是 '\0',所以我们直接循环发送到结尾标识符即可。

4——发送半字

void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
	uint8_t temp_h, temp_l;
	
	/* 取出高八位 */
	temp_h = (ch&0XFF00)>>8;
	/* 取出低八位 */
	temp_l = ch&0XFF;
	
	/* 发送高八位 */
	USART_SendData(pUSARTx,temp_h);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
	/* 发送低八位 */
	USART_SendData(pUSARTx,temp_l);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	

}

5——串口的重定向

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(USART1, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(USART1);
}

        重定向是为了更加完美的使用printf()等函数;

注:

        为了更加明了的实验,我们在接收信息后产生中断,从而进行发送信息到串口,这样就能显示出我们的数据是否已经被接受;

中断配置

static void NVIC_Config()
{
	NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

 STM32f10x_it.c

void USART1_IRQHandler()
{
	uint8_t ucTemp;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
	{		
		ucTemp = USART_ReceiveData(USART1);
		USART_SendData(USART1,ucTemp);    
	}	 
}