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();
}
}