STM32使用USART基础(含printf重定义)(标准库)

配置USART

void USART1_Configuration(void)
{ 
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef  NVICinitStucture;	

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
  /*
  *  USART1_TX -> PA9 , USART1_RX ->    PA10
  */                
  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);           

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 9600;
  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);   //接收中断
	
	NVICinitStucture.NVIC_IRQChannel									=USART1_IRQn;//中断通道,选择串口中断
	NVICinitStucture.NVIC_IRQChannelPreemptionPriority=1;//配置中断优先级
	NVICinitStucture.NVIC_IRQChannelCmd								=ENABLE;//使能打开
	NVICinitStucture.NVIC_IRQChannelSubPriority				=0;//配置中断子优先级

	NVIC_Init(&NVICinitStucture);//串口结构体初始化
	
  USART_Cmd(USART1, ENABLE);
}

注意:若要使用中断组来设置中断优先级,则需要使用NVIC_Config(),如果只需要实现串口通信,可以把NVIC_Config()注释掉,使用USART_ITConfig(USART1, USART_IT_TXE, ENABLE)。两个函数不能同时使用,否则会出现错误

发送字符串

void USART_sendstring(USART_TypeDef* USARTx, char *String)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);      //清空传输完成标志
	while(String[i] != '\0')					//字符串结束符
	{
		USART_SendData(USARTx,String[i]);	//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);	//等待数据发送成功
		i++;
	}
}

/*
 USART_ClearFlag可选的USART_FLAG

 USART_FLAG_CTS: CTS 更改标志(不适用于 UART4 和 UART5)。
 USART_FLAG_LBD:  LIN中断检测标志
 USART_FLAG_TC:传输完成标志
 USART_FLAG_RXNE: 接收数据寄存器不为空标志
*/

stm32f10x_it.c里编写中断函数,中断函数名要对应startup_stm32f10x_hd.s里定义的中断入口名称,例如使用USRAT1对应的中断函数名就为USART1_IRQHandler

void USART1_IRQHandler()
{
	unsigned char ReceivedData;
	if (USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
	{
			ReceivedData = USART_ReceiveData( USART1 );
			USART_SendData(USART1,ReceivedData);
			USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}	

在首尾加入如下代码即可使用printf发送数据

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/*
********************************************************
void main()
{
}
********************************************************
*/

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

奉上main.c

void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

int main()
{
    char wstr[] ="成功了";
	char success[]="完成了";
	char i=0;
    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4);
	USART1_Configuration();
	while(i<5)
	{
		USART_sendstring(USART1,wstr);
		Delay (0xffffff);
		USART_sendstring(USART1,success);
		Delay (0xffffff);
		i++;
	} 
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在STM32USART2上使用printf函数,需要先配置相关的GPIO和USART2的参数,然后再通过定向标准输出流的方式将printf输出到USART2上。 以下是一个简单的示例代码: ``` #include "stm32f4xx.h" #include <stdio.h> void USART2_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 使能GPIOA和USART2的时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 配置PA2为USART2的TX引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 将PA2复用为USART2的TX引脚 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // 配置USART2的参数 USART_InitStructure.USART_BaudRate = 115200; 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_Tx; USART_Init(USART2, &USART_InitStructure); // 使能USART2 USART_Cmd(USART2, ENABLE); // 将标准输出流定向到USART2 // 注意:需要先在stdio.h中定义__io_putchar函数 // 例如:int __io_putchar(int ch) { USART_SendData(USART2, (uint8_t)ch); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); return ch; } stdout = &USART2; } int main(void) { USART2_Init(); // 使用printf输出字符串 printf("Hello, world!\r\n"); while (1) { // 主循环 } } ``` 需要注意的是,为了能够在printf使用float类型的输出,需要在工程属性中的C/C++ Build->Settings->Tool Settings->MCU Settings->Floating-point hardware选择Use 'printf' Floating Point.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值