stm32—串口使用

### 串口数据发送


#include <string.h>				//先引用这个字符串操作库。

char str[]=" HALLO WORD "; 		//定义这个数组字符串。
	  
HAL_UART_Transmit(&huart2, str, strlen(str), 100);
//&huart2,这里他是一个指针,所以要用取地址符。2是代表,串口2.
//str ,是你定义的字符串(数组)的名字。(uint8_t *)需要强制转换为这个数据类型。(char也是8位的,互转没关系)
//strlen(str),这是一个函数,可以取出str这个字符串的长度。
//100,代表100毫秒后,不管有没有发送成功,都停止发送。


串口数据接收


#include <string.h>				//先引用这个字符串操作库。

char str[]=" HALLO WORD "; 		//定义这个数组字符串。

HAL_UART_Receive(&huart2,text, 2, HAL_MAX_DELAY);
//将接受的数据,放在huart2当中。(这是程序预先生成好的buff,来缓存串口的接收数据的)
//text是一个数组,将huar2t的数据自动移到,text这个数组中。
//需要接收的数据长度
//HAL_MAX_DELAY,一直等着,直到,该程序“2”,接收到了2个数据。才会执行下一个程序。

以上方式,都会阻塞程序运行。。。为了不耽误程序运行,可以使用“串口中断”

引脚设置为串口后。

返回mian.c
找到stm32f1xx_it.c
找到,当前串口引脚的,中断函数


页面跳转到了,这个页面。

__wek,代表这个函数可以重新定义。—复制出来,在其它地方使用。

当接收完成,会自动运行这个函数。
例如,我要接收10个数据。。。当10个数据接收完成,会自动进入这个函数。


#include <string.h>				//先引用这个字符串操作库。

char str[]=" HALLO WORD "; 		//定义这个数组字符串。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);		//反转IO的电平
	HAL_UART_Transmit_IT(&huart2, text, 2);		

	HAL_UART_Receive_IT(&huart2, text, 2);		//如果不再次调用,中断执行后,就会彻底结束。
}


void main()
{
	HAL_UART_Receive_IT(&huart2, text, 2);//必须得使用一次,不然,该中断不会开启。

}


串口DMA的使用

DMA,可以搬运数据,不需要MCU来搬运。
当移位寄存器种,没有数据的时候,DMA会自动的把,发送数据寄存器里的内容,放进移位寄存器。
当接收移位寄存器放满后,DMA会自动的把里面的内容,放入接收数据寄存器种。

这个代码种,与上面讲到的“中断接收函数一致”他们使用同一个中断向量。所以返回函数一样。

/只不过,与上面的函数不一样的是,,,上面进入这个中断是因为,每次接收/发射了1个字节的数据。/实际程序验证,不是这个样子/———————实际验证是:当接收完毕后,才会触发这个中断。

DMA串口中断是因为,接收/发射完成时,产生的中断。


#include <string.h>				//先引用这个字符串操作库。

char str[]=" HALLO WORD "; 		//定义这个数组字符串。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);		//反转IO的电平
	HAL_UART_Transmit_DMA(&huart2, text, 2);		

	HAL_UART_Receive_DMA(&huart2, text, 2);		//如果不再次调用,中断执行后,就会彻底结束。
}


void main()
{
	HAL_UART_Receive_DMA(&huart2, text, 2);//必须得使用一次,不然,该中断不会开启。

}


串口空闲中断—–可以用于,接收不定长度的串口数据

;使用void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)这个函数,必须在此之前写__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);——–否则会在数据接收到一半,就触发这个函数


#include <string.h>				//先引用这个字符串操作库。

char text[99]; 		//定义这个数组字符串。

extern DMA_HandleTypeDef hdma_usart2_rx;	//这里需要声明, DMA_HandleTypeDef hdma_usart2_rx该参数已经在其它文件中定义。编译的时候,会自动去找。


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart==&huart2)//验证,当这个中断函数发生的时候,确实是串口2.
	{
		HAL_UART_Transmit_DMA(&huart2, text, Size);	//&huart2是串口2,text是自己声明的数组。Size是固定写法,是这个函数的回传给Size的。。。。因为这是接收不定长度的数据。所以,Size是当前这个中断发生的时候,系统自己会给Size赋值。
		HAL_UARTEx_ReceiveToIdle_DMA(&huart2, text, sizeof(text));//如果不知道自己定义数组的长度,就用sizeof(text)去取,这句话是为了,避免接收的数据,溢出了(数组放不下。)
		__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);	//这个函数有毛病,会在数据接收一半的时候,触发一次,所以--------必须在函数声明前加入:extern DMA_HandleTypeDef hdma_usart2_rx;	//这里需要声明, DMA_HandleTypeDef hdma_usart2_rx该参数已经在其它文件中定义。编译的时候,会自动去找。
	}
}



void main()
{
	HAL_UART_Receive_DMA(&huart2, text, 2);//必须得使用一次,不然,该中断不会开启。

}

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年12月14日
下一篇 2023年12月14日

相关推荐