一起来学小熊派 串口通信实现的3种方式集合 2021-07-23

创建项目

开启GPIO PC13 用于控制LED

 开启串口中断 开启使能 配置DMA

 

配置时钟

 

保存项目

MDK中进行编写

本文对printf函数进行配置重新回调 首先再usart.c中加入stdio.h的头文件

//再urat.c中重写fput函数
/* USER CODE BEGIN 1 */
	int fputc (int ch,FILE* f){
	uint8_t temp[1]={ch};
	{
	HAL_UART_Transmit(&huart1,temp,1,0xff);
	}
return HAL_OK;}


/* USER CODE END 1 */

还有最重要的一步  打开MicroLIB  非常重要!!!

摘自https://www.cnblogs.com/sumsung007/articles/6566767.html 预防丢失
使用微库,将以更精简短小的C 库替代标准C 库,减小代码大小。MicroLib 是默认C 库的备选库。它主要用于内存有限的嵌入式应用程序中。这些应用程序不在操作系统中运行。
如果你发现在Keil RealView MDK 中使用printf 函数,不能向串口输出信息,或者今后发现可以软件仿真,不能硬件仿真,MicroLib 提供了一个有限的stdio子系统,它仅支持未缓冲的stdin、stdout 和stderr。这样,即可使用printf()来显示应用程序中的诊断消息。要使用高级I/O 函数,就必须提供自己实现的以下基本函数,以便与自己的I/O 设备(如串口)配合使用。为所有输出函数:fprintf()、printf()、fwrite()、fputs()、puts()、putc()和putchar()等需要实现fputc()函数。为所有输入函数:fscanf()、scanf()fread()、read()、fgets()、gets()、getc() 和 getchar()等需要实现fgetc()函数。由于MicroLib 进行了高度优化,以使代码变得很小。因此,MicroLib 不完全符合ISO C99 库标准,仅提供有限的支持,不具备某些ISO C 特性。并且其他特性具有的功能比默认C 库少,MicroLib 与默认C 库之间的

主要差异是:
(1)MicroLib 不支持IEEE 754 关于二进制浮点算法标准,否则会产生不可预测的输出的结果,如NaN、无穷大。
(2)MicroLib 中不支持的转换为%lc、%ls 和%a。
(3)MicroLib 进行了高度优化,以使代码变得很小。
(4)MicroLib 不支持与操作系统交互的所有函数,如abort()、exit()、atexit()、clock()、time()、system()
和getenv()。不能将main()声明为带参数的,并且不能返回内容。
(5)不支持与文件指针交互的所有stdio 函数,否则将返回错误。仅支持三个标准流:stdin、stdout
和 stderr。即不完全支持stdio,仅支持未缓冲的stdin、stdout 和 stderr。
(6)MicroLib 不提供互斥锁来防止非线程安全的代码。
(7)MicroLib 不支持宽字符或多字节字符串。如果使用这些函数,则会产生链接器错误。
(8)与stdlib 不同,MicroLib 不支持可选择的单或双区内存模型。MicroLib 只提供双区内存模型,即单
独的堆栈和堆区。

这样,我们就重写了Fput函数,接着需要在main.c文件中也添加stdio.h,这样就可以使用printf函数了

加入3个宏,用于选择三种模式,即普通串口收发,中断串口收发,DMA串口收发。

//#define UART1 //宏定义普通模式
//#define UART1_IRQ //宏定义中断模式
#define UART1_DMA //宏定义DMA模式

 定义缓存 

/* USER CODE BEGIN PTD */
uint8_t Rdata,i;
uint8_t recv_buf;
uint8_t TdataIRQ[] ={"Welcome IOT IRQ!"};
uint8_t TdataDMA[] ={"Welcome IOT DMA!"};
/* USER CODE END PTD */

 

打印测试及串口中断和DMA的开启

 #ifdef UART1_IRQ
	HAL_UART_Receive_IT(&huart1,&Rdata,1);//触发中断接收
	HAL_UART_Transmit_IT(&huart1,TdataIRQ,sizeof(TdataIRQ));//触发中断发送
#endif
 #ifdef UART1_DMA
	HAL_UART_Receive_DMA(&huart1,&Rdata,1);//触发DMA接收
	HAL_UART_Transmit_DMA(&huart1,TdataDMA,sizeof(TdataDMA));//触发DMA发送
#endif

 在main函数循环中加入测试程序,用于比对三种模式的优缺点,不需要的可以不加

 /* USER CODE END WHILE */
		#ifdef UART1
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		HAL_Delay(300);
		    if(HAL_OK == HAL_UART_Receive(&huart1, &Rdata, 1, 0xFFFF))					
    {
			HAL_UART_Transmit(&huart1,&Rdata, 1, 0xFFFF);
			
		}
		#endif
		
		#ifdef UART1_IRQ
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		printf("UART1_IRQ Test!\r\n");
		HAL_Delay(2000);
		#endif
		
		#ifdef UART1_DMA
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		printf("UART1_DMA Test!%d\r\n",i);
		HAL_Delay(2000);
		i++;
		#endif		

    /* USER CODE BEGIN 3 */

 

重写回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
	
{
#ifdef UART1_IRQ
	HAL_UART_Transmit(&huart1,&Rdata,1,0xffff);//触发中断发送
	HAL_UART_Receive_IT(&huart1,&Rdata,1);//触发中断接收
#endif
#ifdef UART1_DMA
 HAL_UART_Transmit(&huart1,&Rdata,1,0xffff);//触发中断发送
//HAL_UART_Transmit_DMA(&huart1,&Rdata,1);//触发DMA发送
HAL_UART_Receive_DMA(&huart1,&Rdata,1);//触发DMA接收
#endif

}

然后编译写入重启小熊派即可实现功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值