初级会员

- 积分
- 186
- 金钱
- 186
- 注册时间
- 2015-1-22
- 在线时间
- 57 小时
|
20金钱
本帖最后由 leozzd 于 2017-12-7 20:07 编辑
使用串口1的DMA,能正常发送,在接收上有好几个疑问:
1、中断上需要用DMA发送中断、DMA接收中断、串口接收中断吗?
2、还需开启串口接收空闲总中断吗?USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);
下面这段程序,在接收上哪里存在问题,请各路大神指点。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void usart1_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA , ENABLE); //使能USART1,GPIOA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1
USART_DeInit(USART1); //复位串口1
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//485EN PA.8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //内部上拉输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SEND_BTN = DISABLE;
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(USART1, &USART_InitStructure); //初始化串口
USART_Cmd(USART1, ENABLE); //使能串口
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //使能USART1发送DMA请求
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); //使能USART1接收DMA请求
//USART_ITConfig(USART1, USART_IT_IDLE , ENABLE); //空闲总中断
USART_ClearFlag(USART1, USART_FLAG_TC); // 清发送外城标志
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//DMA1_4_NVIC
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1 ; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//DMA1_5_NVIC
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//DMA1_4_Config
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART1->DR); //设置DMA源
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_TX_BUF; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为DMA的目的端
DMA_InitStructure.DMA_BufferSize = 2048; //传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据宽度8bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA传送优先级为高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
DMA_Init(DMA1_Channel4, &DMA_InitStructure); //初始化DMA通道4
DMA_Cmd(DMA1_Channel4, DISABLE); //关闭DMA1通道4
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); //使能DMA通道4传输完成中断
//DMA1_5_Config
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART1->DR); //设置DMA源
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_RX_BUF; //DMA外设基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为DMA的目的端
DMA_InitStructure.DMA_BufferSize = 10; //传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据宽度8bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA传送优先级为高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
DMA_Init(DMA1_Channel5, &DMA_InitStructure); //初始化DMA通道5
DMA_Cmd(DMA1_Channel5, ENABLE); //使能DMA1通道5
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); //使能DMA通道5传输完成中断
}
//DMA1_C4发送中断
void DMA1_Channel4_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_FLAG_TC4) != RESET)//等待通道4传输完成
{
DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
DMA_SendState_Flag = FREE;
}
}
//DMA1_C5接收中断
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC5) != RESET)
{
//DMA_Cmd(DMA1_Channel5, DISABLE); //关闭DMA1通道5
//DMA_ClearFlag(DMA1_IT_TC5); //清除通道4传输完成标志
DMA_SendState_Flag = FREE;
}
DMA_ClearITPendingBit(DMA1_IT_TC5);
usart1_send(USART1_RX_BUF, 1000);
}
void usart1_send(u8 *buffer, u16 len)
{
if(len == 0)
return ;
while (DMA_SendState_Flag == USEING);//判断是否占用
memcpy(USART1_TX_BUF,buffer,len); //复制数组
DMA_Cmd(DMA1_Channel4, DISABLE); //关闭DMA1通道4
DMA_SetCurrDataCounter(DMA1_Channel4,len); //DMA通道的DMA缓存的大小
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); //使能DMA通道4传输完成中断
DMA_Cmd(DMA1_Channel4, ENABLE); //使能USART1 TX DMA1 所指示的通道
DMA_SendState_Flag = USEING;
}
void usart1_printf(char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf((char*)USART1_TX_BUF, fmt, ap);
va_end(ap);
usart1_send(USART1_TX_BUF, strlen((const char*)USART1_TX_BUF));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
在接收数据时,DMA_InitStructure.DMA_BufferSize = 10; DMA接收缓存大小定为10,接收10个数据,打印也是10个,但是打印出来的结果错位了。
打印情况
总感觉这里的接收中断出现很大的问题。
|
最佳答案
查看完整内容[请看2#楼]
串口空闲中断就行了,给你个例子吧,串口DMA发送+串口空闲中断DMA接收。[mw_shl_code=applescript,true]void uart_init(u32 bound){
//GPIO端口设置
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCm ...
|