数据发送
流程:串口发送数据,全部数据发送完毕后,会产生一个发送中断,所以
发送数据分为两部分,
A、发送数据
B、中断处理
A、发送数据
u16 Uart_Send_Data(void* buffer, u16 size)
{
if(!size) return 0;// 判断长度是否有效
while (DMA_GetCurrDataCounter(DMA1_Channel4));// 检查DMA发送通道内是否还有数据
if(buffer) memcpy(sendbuf, buffer,(size 》 1024?1024:size));
//DMA发送数据-要先关 设置发送长度 开启DMA
DMA_Cmd(DMA1_Channel4, DISABLE);
DMA1_Channel4-》CNDTR = size;// 设置发送长度
DMA_Cmd(DMA1_Channel4, ENABLE); // 启动DMA发送
return size;
}
B、中断处理
1)中断处理相关准备工作
typedef enum _UartEvent_
{
E_uart_0 = 0,// 没有事件
E_uart_tc=0x40, //发送完成
E_uart_idle=0x80, //接收完成
}UartEvent;
u16 receivelen = 0;// 声明接收数据长度
UartEvent event;//申明一个事件参数
//清除DMA 缓存,并终止DMA
void Uart_Dma_Clr(void)
{
DMA_Cmd(DMA1_Channel4, DISABLE);
DMA1_Channel4-》CNDTR=0;
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA1_Channel5-》CNDTR=DMASIZE ;
DMA_Cmd(DMA1_Channel5, ENABLE);
}
// 获取一个事件,事件分为发送完成事件和接收完成事件,可以根据事件进行进行处理
UartEvent Uart_Get_Event(void)
{
UartEvent e;
if(!DMA1_Channel5-》CNDTR) Uart_Dma_Clr();// 如果产生一个事件后,接收数据通道已经没有了缓存空间,进行清除DMA清空
return event;
}
// 清除对应的事件
void Uart_Clr_Event(UartEvent event_in)
{
event&=~event_in;
}
2) 中断处理,当所有数据发送完毕,串口1产生一个发送完成中断
void Uatr1_Back_IRQHandler()
{
u8 tem;
if(USART_GetITStatus(USART1,USART_IT_IDLE)!= RESET)
{
tem=USART1-》SR;//先读SR,然后读DR才能清除
tem=USART1-》DR;
tem=tem;
Uart_Set_Event(E_uart_idle);
receivelen =DMASIZE - DMA1_Channel5-》CNDTR;// 总的buf长度减去剩余buf长度,得到接收到数据的长度
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
}
**if(USART_GetITStatus(USART1,USART_IT_TC)!= RESET) // 全部数据发送完成,产生该标记**
{
USART_ClearITPendingBit(USART1, USART_IT_TC); // 清除完成标记
DMA_Cmd(DMA1_Channel4, DISABLE); // 关闭DMA
DMA1_Channel4-》CNDTR=0; // 清除数据长度
Uart_Set_Event(E_uart_tc); //设置发送完成事件
}
}
4、接收数据
根据上图描述,流程如下:
1、串口接收到数据
2、DMA自动取走数据
3、DMA把数据存到内存receive[1024]中
4、串口接收完毕后会产生一个空闲中断
根据上面流程,我们接收数据需要做到两步:
1)串口产生一个空闲中断后,设置一个接收完成事件
中断处理:
void Uatr1_Back_IRQHandler()
{
u8 tem;
**if(USART_GetITStatus(USART1,USART_IT_IDLE)!= RESET)**
{
tem=USART1-》SR;//先读SR,然后读DR才能清除
tem=USART1-》DR;// 清除DR
tem=tem; // 防止编译器警告
Uart_Set_Event(E_uart_idle);// 设置接收完成(空闲)事件
receivelen =DMASIZE - DMA1_Channel5-》CNDTR;// 总的buf长度减去剩余buf长度,得到接收到数据的长度
USART_ClearITPendingBit(USART1, USART_IT_IDLE); // 清除空闲中断
}
if(USART_GetITStatus(USART1,USART_IT_TC)!= RESET) // 全部数据发送完成,产生该标记
{
USART_ClearITPendingBit(USART1, USART_IT_TC); // 清除完成标记
DMA_Cmd(DMA1_Channel4, DISABLE); // 关闭DMA
DMA1_Channel4-》CNDTR=0; // 清除数据长度
Uart_Set_Event(E_uart_tc); //设置发送完成事件
}
}
2)接收数据函数检测事件,如果发现是接收完成事件,取走数据,并且做相关清除操作
u8 Uart_Receive_Data(u8*recbuf u16 *revLen)
{
u8 *str;
if( event & E_uart_idle) // 是否产生空闲中断
{
str = Uart_Get_Data(revLen);
memcpy(recbuf,receivebuf,*revLen);
Uart_Clr_Event(E_uart_idle);
Uart_Dma_Clr();
return TRUE;
}
else
{
revLen = 0;
return FALSE;
}
}
评论