我这个调试版本的程序意图是这样的:串口3 接收方式采用普通的中断来接收串口调试助手发送来的数据,接收到有用的数据后,就采用DMA方式回送一帧数据到串口调试助手,DMA发送完后要产生一个TC的中断,因为我要在这个中断的服务程序里设置一下RS485芯片的数据传输方向,必须要设置这个方向,(要不然会收不到数据,只能发送数据,芯片功能是这样)。 发送数据的前后时间段 ,我一直要控制一个小直流马达转动,还要一直进行AD转换来获取这个直流马达的转动位置,但是现在调试的时候,串口通过DMA发送一帧数据后,就死机了,不知道怎么回事,好像卡在DMA_Cmd(DMA1_Channel2, ENABLE);这句这里了,因为我在这条语句后面加了一些语句来验证,发现这条语句后面的程序都没有执行?
问题的现象就是:只能响应一次,响应完后就死机。
程序是照原子哥寄过来的光盘里的改的,原子哥的是DMA polling 发送,我的只是改成DMA interrupt 发送就不行了 大家帮忙看下吧,
相关程序如下:
char SendBuff[]="hello";
void Init_usart3(void);
void Init_DMA(void);
int main(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
Init_usart3();
Init_DMA();
while(1)
{
if(flag) //串口3接收中断里SET该变量 ,即收到一个上位机发来的数据,就启动一次DMA传输,
{
flag = 0;
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel2, ENABLE);
}
}
void USART3_IRQHandler(void) //串口3中断服务程序
{
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断
{
temp =USART_ReceiveData(USART3);
flag=1;
}
}
void DMA1_Channel2_IRQHandler(void) //DMA1通道2传输完成中断
{
if(DMA_GetITStatus(DMA1_IT_TC2) != RESET) //
{
DMA_ClearITPendingBit(DMA1_IT_TC2);
USART_DMACmd(USART3, USART_DMAReq_Tx, DISABLE) ;
}
}
void DMA_Configuration(void)
{
/* USART1 TX DMA4 Channel Config */
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能时钟
// delay_us(2);
DMA_DeInit(DMA1_Channel2); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize =7;// sizeof(SendBuff); //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel2, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);//添加中断配置
}
void NVIC_DMA_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel =DMA1_Channel2_IRQn; //USART1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
}
void Init_DMA(void)
{
DMA_Configuration();
NVIC_DMA_Configuration();
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=RS485_ENABLE_PIN;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP ;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(RS485_ENABLE_PORT, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置优先级分组:先占优先级0位,从优先级4位
//设置向量表的位置和偏移
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //向量表位于RAM
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //向量表位于FLASH
#endif
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //USART1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate= 9600;
USART_InitStructure.USART_WordLength =USART_WordLength_8b;
USART_InitStructure.USART_StopBits= USART_StopBits_1;
USART_InitStructure.USART_Parity =USART_Parity_No;
USART_InitStructure.USART_Mode= USART_Mode_Rx|USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3,USART_IT_RXNE, ENABLE);
USART_Cmd(USART3, ENABLE);
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
}
void Init_usart3(void)
{
NVIC_Configuration();
GPIO_Configuration();
USART_Configuration();
}
|