初级会员

- 积分
- 79
- 金钱
- 79
- 注册时间
- 2019-12-18
- 在线时间
- 19 小时
|
为什么我用串口2 DMA接收数据,进不去中断,好几天了,没找到问题,大佬帮忙看看吧,下面是两个配置。
#include "usart2.h"
#include "led.h"
void uart2_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART2,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //使能USART2,GPIOA时钟
//USART2_TX GPIOA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
//USART2_RX GPIOA.3初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART2, &USART_InitStructure); //初始化串口2
USART_ITConfig(USART2,USART_IT_IDLE, ENABLE);//开启串口空闲检测中断
USART_Cmd(USART2, ENABLE); //使能串口2
}
u8 USART2_Recive_leng = 0;
u8 USART2_Recive_flg = 0;
extern u8 ReciveBuff[128];
extern u8 TEXT_TO_REC[4096];
void USART2_IRQHandler(void) //串口2中断服务程序
{
u8 Clear = Clear;
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
{
Clear = USART2->SR; //读SR寄存器清除 清除USART2的IDLE中断
Clear = USART2->DR; //读DR寄存器清除
DMA_Cmd(DMA1_Channel6,DISABLE); //关闭DMA
USART2_Recive_leng = 128 - DMA_GetCurrDataCounter(DMA1_Channel6); //得到真正接收数据个数
if(USART2_Recive_leng > 128)
{
USART2_Recive_leng = 0; //避免接收数据超界
}
DMA1_Channel6->CNDTR = 128; //重新设置接收数据个数
DMA_Cmd(DMA1_Channel6,ENABLE); //开启DMA
USART2_Recive_flg = 1; //数据接收成功
}
USART_ClearFlag(USART2,USART_FLAG_TC); //清除USART2标志位
ReciveData_dis();
LED1 = 0;
}
void ReciveData_dis(void) //处理数据,接收的新数据包覆盖上一包数据
{
u8 i,t;
static u8 flag = 0;
if(flag > USART2_Recive_leng)
{
for(t = 0;t < flag;t++)
{
TEXT_TO_REC[t] = 0;
}
}
for(i = 0;i < USART2_Recive_leng;i++)
{
TEXT_TO_REC[i] = ReciveBuff[i]; //复制数据
}
ReciveBuff[USART2_Recive_leng] = '\0';
flag = i;
}
void ReciveData_DisLong(void) //处理数据,多包数据放到一个存储单元
{
static u8 i = 0; //记录每次接收数据的字节数
u8 j = 0;
for(j = i;j < USART2_Recive_leng + i;j++)
{
TEXT_TO_REC[j] = ReciveBuff[j]; //复制数据
}
ReciveBuff[j] = '\0'; //在每一包数据后加结尾
i = j+1; //向后移一个字节,准备存储下一包数据
}
# include "dma.h"
u16 DMA1_MEM_LEN; //保存DMA每次数据传送的长度
void DMA1_Init(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA1传输
DMA_DeInit(DMA_CHx); //将DMA的通道x寄存器重设为缺省值
DMA1_MEM_LEN = cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //存储器基地址
DMA_InitStructure.DMA_BufferSize = cndtr; //传输数据量
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为来源,从外设到存储器
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //不是存储器到存储器
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器字节传输
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //开启存储器增量
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //不循环传输
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节传输
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //不开启外设增量
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级中等
DMA_Init(DMA_CHx,&DMA_InitStructure);
DMA_ITConfig(DMA_CHx,DMA_IT_TC,ENABLE); //传输完成后产生中断
USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE); //使能串口2的DMA接收
DMA1_Enable(DMA1_Channel6);//开始一次DMA传输!
}
void DMA1_Enable(DMA_Channel_TypeDef *DMA_CHx) //使能DMA1_CHx
{
DMA_Cmd(DMA_CHx,DISABLE);
DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN); //设置通道传输的数据单元数
DMA_Cmd(DMA_CHx,ENABLE);
}
|
|