想让DMA接收不定长的数据,思路是定义一个定时器 设定固定的时间(5ms)中断。串口有数据发送过来就清空定时器的值,让定时器重新定时直到串口5ms内没有数据发送过来就默认它这一段数据发送完成。定义一个长度变量。在串口接收中断中接收一个数据长度变量就++一次。这样就得到一组数据的长度。
//定义了一个1ms的定时器。数据接收完成后定时器失能,并且time清零
void timer0_isr() interrupt 1
{
time_count++;
if(time_count >= 5)
{
receive_flag = 1;
time_count = 0;
TR0 = 0;
}
}
//接收到第一个数据开启定时器。之后接收的数据都会让定时器计数清零
void uart1_isr() interrupt 4 using 1
{
if (RI) //是接收中断(接收中断请求标志位为1)
{
RI = 0; //清零RI位(该位必须软件清零)
if(first == 0) //是第一个数据
{
TR0 = 1; //定时器0开始计时
first = 1;
}
else
{
time_count = 0; //清零串口接收超时软件计数器
}
receive_length++; //接收数据长度加1
}
if(TI)
{
TI = 0;
}
}
接收完成后将数据放在需要的数组,和DMA定长数据接收一样。
u8 receive_mod(void)
{
u8 temp = 0;
if(receive_flag == 1)
{
memcpy(buffer_rx , receive_array , receive_length); //将接收的数据拷贝到串口DMA发送源地址
DMA_UR1R_CR = 0x00;
DMA_UR1R_AMT = array_lenth-1; //设置传输总字节数: n+1
DMA_UR1R_RXAH = (u8)((u16)&receive_array >> 8);//设置UART1 DMA接收目的地址
DMA_UR1R_RXAL = (u8)((u16)&receive_array);
DMA_UR1R_CR = 0xA1; //开启UART1 DMA接收功能,开始 UART1_DMA 自动接收,清除 FIFO
DMA_UR1R_DONE = 0;
// send_mod(buffer_rx , receive_length); //将接收的数据通过串口发送出去
receive_flag = 0;
temp = receive_length;
clear_mod();
return temp;
}
return temp;
}
注:数组大小应该设置最大避免溢出