这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 换逻辑分析仪_STM32F103(寄存器)串口2发送接收

共2条 1/1 1 跳转至

换逻辑分析仪_STM32F103(寄存器)串口2发送接收

工程师
2024-06-25 21:07:42   被打赏 15 分(兑奖)     打赏

STM32F103 使用寄存器方式配置和使用串口(USART)进行数据的发送和接收是一个相对底层且直接的操作。

以下是我例的一个简化的步骤,用于配置 STM32F103 的 USART进行基本的发送和接收操作:

1. 初始化 GPIOUSART2 通常使用 PA9 (TX) 和 PA10 (RX) 作为其引脚。你需要配置这两个引脚为复用推挽输出(对于 TX)和浮空输入(对于 RX)。2. 初始化 USART设置 USART 的波特率、数据位、停止位和校验位。使能 USART 的接收和发送中断(如果需要中断驱动)。使能 USART。3. 发送数据将数据写入 USART 的数据寄存器(USART->DR)。等待发送完成(可以通过查询标志位或中断来实现)。4. 接收数据读取 USART 的数据寄存器(USART->DR)来获取接收到的数据。清除相关的接收标志位。在中断服务例程中处理接收到的数据。

这里只给出一些关键的代码片段,而不是完整的初始化函数或中断服务例程。


还是把原理图弄过来,方便分析:

image.png

主核心代码:

image.png

串口初始化:

image.png

串口参数波特率:串口通信的速率起始位:标志一个数据帧的开始,固定为低电平数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行校验位:用于数据验证,根据数据位计算得来停止位:用于数据帧间隔,固定为高电平


image.png

还是把代码帖上来:

void My_USART1(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART1_InitStrue;
	NVIC_InitTypeDef NVIC_InitStructure;
	//1、串口时钟、GPIOA时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
	
	//2、GPIOA端口模式设置
	GPIO_InitStruct.GPIO_Pin = USART1_GPIO_PIN_TX;//PA9
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = USART1_GPIO_PIN_RX;//PA10
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(GPIOA, &GPIO_InitStruct);	
	
	//3、串口参数初始化
	
	USART1_InitStrue.USART_BaudRate = 9600;
	USART1_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART1_InitStrue.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	USART1_InitStrue.USART_Parity = USART_Parity_No;
	USART1_InitStrue.USART_StopBits=USART_StopBits_1;
	USART1_InitStrue.USART_WordLength = USART_WordLength_8b;
	
	USART_Init( USART1, &USART1_InitStrue);
	//4、开启中断并且初始化NVIC
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQn ;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	//5、使能串口
	USART_Cmd(USART1,ENABLE);
	
	//6、编写中断处理函数	
	
}

void USART_SendByte(USART_TypeDef* USARTx, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_USART_DATA(Data)); 
    
  /* Transmit Data */
  USARTx->DR = (Data & (uint16_t)0x01FF);
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

}

void USART_SendString( USART_TypeDef * USARTx, char *str)
{
     while(*str!='\0')
     {
         USART_SendByte( USARTx, *str++ );	
     }
     while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
}
uint8_t USART_ReceiveByte(USART_TypeDef* USARTx)
{
  while(USART_GetFlagStatus(USARTx,USART_FLAG_RXNE)==RESET);
  
  return (uint8_t)USART_ReceiveData(USART1);

}

void USART1_IRQHandler()
{
	u16 temp;
//	while(USART_GetITStatus(USART1,USART_IT_RXNE) == RESET);
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
	{
		temp = USART_ReceiveData(USART1);
	}
	
	USART_SendByte(USART1,temp);	

}
#pragma import(__use_no_semihosting)             
                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;          
_sys_exit(int x) 
{ 
	x = x; 
} 

int fputc(int ch, FILE *f)
{
		
		USART_SendData(USART1, (uint8_t) ch);			
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);			
		return (ch);
}


int fgetc(FILE *f)
{		
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
		return (int)USART_ReceiveData(USART1);
}
int main(void)
{
			char i;
		LED_GPIO_Config();
		delay_init();
		//KEY_GPIO_Config();
		//TIM2_Init(4999,7199);
	    My_USART1();
	    USART_SendString(USART1, "电子产品世界");
		while(1)			
		{
		
		};
}


解释一下函数的意思:

My_USART1(void)这个函数用于初始化USART1。时钟使能:首先,它使能了USART1和GPIOA的时钟,因为USART1的TX和RX引脚通常连接到GPIOA。GPIO初始化:然后,它设置了GPIOA的引脚模式,将TX引脚设置为复用推挽输出,RX引脚设置为浮空输入。USART初始化:接着,它配置了USART1的参数,如波特率、硬件流控制、工作模式、校验位、停止位和数据位。中断和NVIC配置:它启用了USART1的接收中断,并配置了NVIC(嵌套向量中断控制器)以处理该中断。使能串口:最后,它使能了USART1。USART_SendByte(USART_TypeDef* USARTx, uint16_t Data)这个函数用于发送一个字节的数据。参数检查:它首先检查传入的USART指针和数据是否在有效范围内。发送数据:然后,它将数据写入USART的数据寄存器(DR)。等待发送完成:它使用循环等待,直到TXE(发送数据寄存器空)标志被设置,表示数据已被发送出去。USART_SendString(USART_TypeDef * USARTx, char *str)这个函数用于发送一个字符串。发送字符串:它遍历字符串,对每个字符调用USART_SendByte函数进行发送。等待传输完成:在所有字符发送后,它等待TC(传输完成)标志被设置,表示整个字符串已发送完成。USART_ReceiveByte(USART_TypeDef* USARTx)这个函数的目的是接收一个字节的数据,但你的代码片段中USART_ReceiveByte函数没有完整,我会假设其可能的实现。接收数据:它应该读取USART的数据寄存器(DR)来获取接收到的数据。

清除中断标志:如果函数是为了中断驱动的接收而编写的,它还需要清除相应的中断标志。


实际工作状态:

1719321011129.jpg


发送接收回来的结果:

image.png

中文英文数字都可以收到:

image.png


总结:是重定义fputc函数,让他变成向上位机发送数据,发送的数据会通过串口调试助手打印出来。里面有接收函数,也发送,发送相关代码主要在函数里面实现。从这个串口代码中还是学到了如何使用串口的一些实用的功能,原来串口还可以这样用。




工程师
2024-07-10 09:27:32     打赏
2楼

666666


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]