串口中断接收

1、串口中断接收

1.使能串口接收

usart_receive_config(BSP_USART, USART_RECEIVE_ENABLE); // 使能串口接收

2.串口中断配置

配置中断的时候需要配置优先级

#define BSP_USART_IRQ		 USART0_IRQn
nvic_irq_enable(BSP_USART_IRQ, 2, 2); // 配置中断优先级

中断类型

描述

USART_INT_TBE

发送缓冲区空中断。

USART_INT_TC

发送完成中断。

USART_INT_RBNE

接收缓冲区不为空中断和溢出错误中断。如果开启了这个中断,每当接收到一个字符,就会触发这个中断。

USART_INT_IDLE

空闲检测中断。如果开启了这个中断,将会在一帧数据传输完成之后触发中断,一般用来判断一帧数据是否传输完成。

/* 接收中断:判断数据传输完成 */
		usart_interrupt_enable(BSP_USART,USART_INT_RBNE);
		/* 帧中断 */
		usart_interrupt_enable(BSP_USART,USART_INT_IDLE);
		// 然后进入中断函数中接收数据

3.串口变量定义

//串口缓冲区的数据长度:
#define      USART_RECEIVE_LENGTH       4096
//串口缓冲区和接收完成标志:
uint8_t       g_recv_buff[USART_RECEIVE_LENGTH]; // 接收缓冲区
uint16_t     g_recv_length = 0;                  // 接收数据长度
uint8_t       g_recv_complete_flag = 0;          // 接收完成标志位

4.串口中断接收服务函数

/*串口中断函数
USART0的中断函数
#define BSP_USART_IRQHandler  USART0_IRQHandler
*/
void BSP_USART_IRQHandler()
{
	if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE)==SET) //说明有数据到来
	{
		//将接收到来的数据储存在数组之中
		//串口接收函数usart_data_receive自带清除标志位的功能
		g_recv_buff[g_recv_length++]=usart_data_receive(BSP_USART);
	}
	//传输完成之后进入空闲中断之中
	if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE)==SET) //说明有数据到来
	{
		usart_data_receive(BSP_USART);
		g_recv_buff[g_recv_length]='\0';//数组接收数据结束
		g_recv_complete_flag = 1; //数据传输完成标志位
	}
}

5.串口中断接收数据处理

在main函数中进行接收数据处理

while(1) {
			
			if(g_recv_complete_flag == 1)
			{
				g_recv_complete_flag = 0; // 数据处理完成之后,数据标志位置0
				printf("g_recv_length:%d ",g_recv_length);
				printf("g_recv_buff:%s\r\n",g_recv_buff);
				memset(g_recv_buff,0,g_recv_length);//将数组进行清零
				g_recv_length=0;
			}
    }

2、串口DMA接收

1.开启时钟

/* 开启时钟 */
	rcu_periph_clock_enable(BSP_DMA_RCU);

2.配置参数结构体

	/* 定义输出参数结构体*/
	dma_single_data_parameter_struct dma_init_struct;
	/* dma复位 */
	dma_deinit(BSP_DMA,BSP_DMA_CH);
	/*  */
		 dma_init_struct.periph_addr = (uint32_t)&USART_DATA(BSP_USART) ;        /*!< peripheral base address: 
																					外设基地址 由于是外设到内存,所以基地址为串口(外设)的地址 
																					函数USART_DATA是取得参数的基地址*/
     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;         /*!< peripheral increasing mode :生长模式,外设对应固定模式*/  

     dma_init_struct.memory0_addr = (uint32_t)g_recv_buff;       /*!< memory 0 base address :内存地址为串口输出的数组*/
		 dma_init_struct.memory_inc = DMA_PERIPH_INCREASE_ENABLE;         /*!< memory increasing mode:内存为增量模式 */

     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;/*!< transfer data size of peripheral 位宽为8位*/

     dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;      /*!< DMA circular mode:循环模式:不使用循环模式 */
		 dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;          /*!< channel data transfer direction :传输模式->外设到内存*/
     dma_init_struct.number = ;             /*!< channel transfer number */
     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;   //超高优先级
	dma_single_data_mode_init(BSP_DMA,BSP_DMA_CH,&dma_init_struct);

3.使能通道外设

/* 对应的	通道有有八个不同的通道,这里需要配置USART_RX,就选择100通道,其对应的8421就是4,所以选择 DMA_SUBPERI4	*/
	dma_channel_subperipheral_select(BSP_DMA,BSP_DMA_CH,DMA_SUBPERI4);

4.使能DMA中断

/* dma 使能 */
		 dma_channel_enable(BSP_DMA,BSP_DMA_CH);
		 /* dma 中断使能:传输完成中断 */
		 dma_interrupt_enable(BSP_DMA,BSP_DMA_CH,DMA_CHXCTL_FTFIE);
		 /* 使能中断优先级 */
		 nvic_irq_enable(BSP_DMA_CH_IRQ,2,1);

5.使能外设DMA(串口)

/* 将对应的dma串口使能,配置了串口dma接收功能 */
		 usart_dma_receive_config(BSP_USART, USART_DENR_ENABLE);

6.DMA中断服务函数

//#define BSP_DMA_CH_IRQHandler   DMA1_Channel2_IRQHandler  // DMA中断服务函数名
void BSP_DMA_CH_IRQHandler(void)
{
	if(dma_interrupt_flag_get(BSP_DMA,BSP_DMA_CH,DMA_INT_FLAG_FTF)==SET)  //第三个参数为传输模式:完全传输模式
	{
		dma_interrupt_flag_clear(BSP_DMA,BSP_DMA_CH,DMA_INT_FLAG_FTF);
		g_recv_complete_flag = 1;//数据传输完成标志位
	}
}

7.DMA接收数据处理

要实现数据的不定长接收那么

void BSP_USART_IRQHandler()
{
//	if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE)==SET) //说明有数据到来
//	{
//		//将接收到来的数据储存在数组之中
//		//串口接收函数usart_data_receive自带清除标志位的功能
//		g_recv_buff[g_recv_length++]=usart_data_receive(BSP_USART);
//	}
	//传输完成之后进入空闲中断之中
	if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE)==SET) //说明有数据到来
	{
		usart_data_receive(BSP_USART);
		
		/* dma 传输数据量处理 : 实际使用数据量 = 最大量 - 获取的剩余数据量 */
		g_recv_length=USART_RECEIVE_LENGTH-dma_transfer_number_get(BSP_DMA,BSP_DMA_CH);
		g_recv_buff[g_recv_length]='\0';//数组接收数据结束
		g_recv_complete_flag = 1; //数据传输完成标志位
		
		dma_channel_disable(BSP_DMA,BSP_DMA_CH);//dma通道先失能才能继续配置
		//再一次配置dma使其可以多次传输数据
		dma_config();

	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值