初级会员

- 积分
- 121
- 金钱
- 121
- 注册时间
- 2019-7-4
- 在线时间
- 23 小时
|
void Usart2_Tx_DMAConfig() //串口2-DMA的发送初始化配置
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA1时钟
DMA_DeInit(DMA1_Channel7);//查映像,USART2_TX为DMA1的7通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;//外设DMA一个地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&HW_SendData;//数据内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA单向传输
DMA_InitStructure.DMA_BufferSize = Buffer_Len;//缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//缓存地址增长
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//存储器到存储器使能,仅DMA2用
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel7,DMA_IT_TC,ENABLE);//开启DMA发送完成中断
DMA_Cmd(DMA1_Channel7, DISABLE); //关闭DMA传输
}
void Usart2_Rx_DMAConfig() //串口2-DMA的接收初始化配置
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA1时钟
/* DMA1 channel6 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel6);//查映像,USART2_RX为DMA1的6通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; ;//外设DMA一个地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&usart2_buf;//数据内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA单向传输
DMA_InitStructure.DMA_BufferSize = Buffer_Len;//缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//缓存地址增长
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//8bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//只用DMA1优先级可随意
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//存储器到存储器使能,仅DMA2用
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
/* Enable DMA1 channel6 */
DMA_Cmd(DMA1_Channel6, ENABLE);//开启DMA传输
}
void uart2_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART2,GPIOA时钟在uart1_init()里已经打开了
//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
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//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
USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE); //*******使能串口2的DMA发送 *******
USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE); //*******使能串口2的DMA接收 *******
Usart2_Tx_DMAConfig();
Usart2_Rx_DMAConfig();
}
void Dma_Send_Enable(DMA_Channel_TypeDef* DMAy_Channelx,u16 ndtr) //DMA的发送使能
{
DMA_SetCurrDataCounter(DMAy_Channelx,ndtr); //数据传输量
DMA_Cmd(DMAy_Channelx, ENABLE); //开启DMA传输
}
//DMA的发送完成中断函数
void DMA1_Channel7_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC7)!=RESET) //等待DMA1_channel7传输完成
{
断点2: DMA_ClearFlag(DMA1_FLAG_TC7); //清除DMA1_channel7传输完成标志
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);//等待发送为空
DMA_Cmd(DMA1_Channel7,DISABLE); //关闭DMA
DMA_ClearITPendingBit(DMA1_IT_TC7); //清除中断屏蔽位
}
}
//串口2中断服务程序,接收红外返回数据
void USART2_IRQHandler(void)
{
u8 i;
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //接收中断(5A data1 data2 crc)
{
DMA_Cmd(DMA1_Channel6, DISABLE);//开启DMA传输
i =USART_ReceiveData(USART2); //读DR,是为了清除IDLE中断
index_usart2 = Buffer_Len - DMA_GetCurrDataCounter(DMA1_Channel6);//获得这一帧的数据长度
if(index_usart2!=0)
{
RX2_OK=1; //数据帧接收标志位置1
for(i=0;i<index_usart2;i++)
{
SendBuffer[i]= usart2_buf[i]; //将接收的数据保存
}
for(i=0;i<index_usart2;i++) //将数据缓存区清零
{
usart2_buf[i]=0;
}
}
DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_HT6 | DMA1_FLAG_TE6 ); //清除DMA1_Channel3传输完成标志(非中断标志)
DMA_SetCurrDataCounter(DMA1_Channel6, Buffer_Len); //设置DMA接收单元的长度
DMA_Cmd(DMA1_Channel6, ENABLE);//开启DMA传输
}
}
发送部分
if(HW_SendNum>0)
{
m_Out[0] = BPHW_STX; //帧头
btCheckSum=m_Out[0];
for(i=0;i<HW_SendNum;i++)
{
m_Out[i+1] = HW_SendData[i];
btCheckSum += HW_SendData[i];//加法
}
m_Out[1 + HW_SendNum] = btCheckSum%256; //校验码
m_Out[2 + HW_SendNum] = BPHW_ETX1; //帧尾
m_Out[3 + HW_SendNum] = BPHW_ETX2; //帧尾
HW_SendNum = HW_SendNum + BPHW_SELEN;
for ( i = 0;i<HW_SendNum;i++)
{
HW_SendData[i] = m_Out[i];
}
断点1:Dma_Send_Enable(DMA1_Channel7,HW_SendNum);//使能并开始DMA发送
// HW_SendNum=0;
//// for(i=0;i<20;i++)
//// {
//// HW_SendData[i]=0;
//// }
串口2的DMA发送中断,查找了很多遍,不知配置哪里出问题。调试时候发现HW_SendData数组在断点1处有数据,在进入发送完成中断的断点2处:HW_SendData数组全部为0;且串口一直没数据出来。不知什么原因。DR也观察不到有数据。初调试请各位帮忙看看?
|
|