[mw_shl_code=c,true]
[mw_shl_code=c,true]//RS485总线串口、DMA初始化[/mw_shl_code]
[/mw_shl_code]
[mw_shl_code=c,true]void Init_RS485(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB2Periph_AFIO,ENABLE); //使能USART2时钟
USART_DeInit(USART2); //复位串口2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE); //复位串口2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE); //停止复位
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(USART2, &USART_InitStructure); //初始化串口
USART_Cmd(USART2, ENABLE); //使能串口
// USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启串口接收中断
//配置USART2_RX的DMA_CH6接收中断
NVIC_Configuration();//中断优先级配置
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn; //使能DMA1_CH6(USART2_RX)中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//配置USART2_TX的DMA_CH7发送中断
NVIC_Configuration();//中断优先级配置
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; //使能DMA1_CH7(USART2_RX)中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//配置USART2的接收DMA通道
DMA_ClearITPendingBit(DMA1_IT_TC6); //清通道6完成中断
DMA_Config(DMA1_Channel6,(u32)&USART2->DR,(u32)U2_ReceBuff,8,DMA_DIR_PeripheralSRC);//USART2_RX
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC,ENABLE); //开启USART1_DMA_CH6完成中断
DMA_Cmd(DMA1_Channel6, ENABLE); //开启DMA_CH6通道
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); //开启USART2接收DMA
//配置USART2的发送DMA通道
DMA_ClearITPendingBit(DMA1_IT_TC7); //清通道7完成中断
DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)U2_SendBuff,7,DMA_DIR_PeripheralDST);//USART2_TX
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC,ENABLE); //开启USART1_DMA_CH7完成中断
// DMA_Cmd(DMA1_Channel7, ENABLE); //开启DMA_CH7通道
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); //开启USART2发送DMA
// RS485_EN = 1; //485发送模式
RS485_EN = 0; //默认485接收模式
}
//USART2_RX_DMA完成中断服务函数
void DMA1_Channel6_IRQHandler(void)
{
// u8 i = 0;
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC,DISABLE); //关闭USART2_DMA_CH2接收完成中断
printf("ok\r\n");
if(DMA_GetITStatus(DMA1_IT_TC6) != RESET)
{//以下为从机状态数据帧解码函数
// Frame_Decoding(); //帧解码函数
printf("%x\r\n",U2_ReceBuff[0]);
printf("%x\r\n",U2_ReceBuff[1]);
printf("%x\r\n",U2_ReceBuff[2]);
printf("%x\r\n",U2_ReceBuff[3]);
printf("%x\r\n",U2_ReceBuff[4]);
printf("%x\r\n",U2_ReceBuff[5]);
printf("%x\r\n",U2_ReceBuff[6]);
printf("%x\r\n",U2_ReceBuff[7]);
}
DMA_ClearITPendingBit(DMA1_IT_TC6);
DMA_Config(DMA1_Channel6,(u32)&USART2->DR,(u32)U2_ReceBuff,8,DMA_DIR_PeripheralSRC);//USART2_RX
DMA_Cmd(DMA1_Channel6, ENABLE); //开启DMA_CH6通道
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC,ENABLE); //开启USART2_DMA_CH6接收完成中断
}
//USART2_TX_DMA完成中断服务函数
void DMA1_Channel7_IRQHandler(void)
{
// u8 i = 0;
printf("send ok");
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC,DISABLE); //关闭USART2_DMA_CH7接收完成中断
if(DMA_GetITStatus(DMA1_IT_TC7) != RESET)
{//以下为RS485基于MODBUS协议发送完成后定时器延时函数
printf("send ok");
}
// printf("\r\n");
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)U2_ReceBuff,7,DMA_DIR_PeripheralDST);//USART2_TX
DMA_Cmd(DMA1_Channel7, ENABLE); //开启DMA_CH7通道
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC,ENABLE); //开启USART2_DMA_CH7接收完成中断
}
int main(void)
{
u8 s = 1;
NVIC_Configuration();//中断优先级配置
SystemInit(); //系统72M初始化
uart_init(9600); //串口
delay_init(72); //软件延时
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //先开启AFIO复用时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//才能调用本句关闭JTAG开启SWD,JTAG引脚释放为GPIO
Init_RS485(9600); //RS485总线初始化
while(1)
{
printf("while1 ok\r\n");
delay_ms(500);
Frame_Send(Cabinet1,Demand_Slave,0x00);
delay_ms(500);
}
}[/mw_shl_code]
现象是无论DMA接收完成还是发送完成,均不会进入中断,不过USART2经485可以正常发送数据,只是进入不了中断,中断服务函数名与.s启动文件中一样,DMA1时钟开启。还请各位帮忙解答一下,卡半天了。
|