因为实验的关系借用了葱花鱼仁兄写的实时曲线程序,是采用乒乓策略来接收数据的,设置了两个buffer来接收DMA得到的数据,每个buffer的长度是200,我发现在每秒钟接收到180个数据时程序是能够连续接收并写入文件的,但是现在因为别的原因每秒只能传出30个数据了,还是用原来的buffer不能连续接收数据了,于是我调整了一下buffer的长度,因为我发现如果buffer长度超过200很多的话,每秒传出180个数据也不能连贯接收,于是我把buffer的长度减短,也就是按比例减短吧,调整成15左右,但是我发现还是没有办法连续接收并写入文件,大概只能接收一次发送的数据,请问这是为什么呢?还有我对于程序是怎么实现连续接收的原理也不大明白,我把move_data跟display函数去掉后就不能实现连续接收了,下面我附上跟DMA接收这块有关的程序:
int Buff_OK=0; //DMA已经有接受完数据
int Free_Buff_No; //DMA缓冲可以进行处理的数据
u16 count=0;
char Buffer[40]={0}; //存储十进制数据
char buffer[512]; //读文件缓冲
char ReceiveBuffer0[200]; //DMA缓冲0
char ReceiveBuffer1[200]; //DMA缓冲1
然后这是主函数里面与DMA有关的部分:
int main(void){
u8 t=0;
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,4800);
RTC_Init();
KEY_Init();
LCD_Init();
USART_Receive_DMA();
while(1){
t=KEY_Scan();
res = f_mount(0, &fs);
if(t){
switch(t){
case 1: Create_files(dir_path,file_path);
scan_files(dir_path);
break;
case 2: Receive_Display();
break;
case 3: Read_file_Display(dir_path,file_path);
break;
default: break;
}
}
f_mount(0,NULL);
}
}
//绘制曲线
void display(void){
int i;
for(i=39;i>0;i--){
LCD_DrawLine(20+i*5,300-Buffer[i-1],20+(i+1)*5,300-Buffer);
}
}
//数组移动
void move_data(void){
int j;
for(j=0;j<39;j++){
Buffer[j]=Buffer[j+1];
}
}
//串口DMA方式接收数据处理后显示
void Receive_Display(void){
u16 i;
u8 t=0;
while(Buff_OK==1){
Buff_OK=0;
LCD_ShowNum(100,320,count,3,16);
if(Free_Buff_No==0){
Write_file_0(dir_path,file_path);
for(i=0;i<200;i++){
if(ReceiveBuffer0>=48 && ReceiveBuffer0<=57){
t=t*10+(((ReceiveBuffer0)&0x0f)%10);
}
if((i%2)==1){
move_data();
Buffer[39]=t;
t=0;
LCD_Fill(20,200,220,300,WHITE);
display();
}
}
}else{
Write_file_1(dir_path,file_path);
for(i=0;i<200;i++){
if(ReceiveBuffer1>=48 && ReceiveBuffer1<=57){
t=t*10+(((ReceiveBuffer1)&0x0f)%10);
}
if((i%2)==1){
move_data();
Buffer[39]=t;
t=0;
LCD_Fill(20,200,220,300,WHITE);
display();
}
}
}
}
}
//DMA1中断设置
void Set_DMA_ISR(void){
DMA1_Channel5->CCR|=1<<1; //允许TC中断
MY_NVIC_Init(0,1,DMA1_Channel5_IRQChannel,2);
}
//DMA1中断函数
void DMAChannel5_IRQHandler(void){
if(DMA1->ISR&(1<<17)){ //DMA1通道5传输完成
DMA1->IFCR|=1<<17; //清除DMA1通道5传输完成标志
count++;
if(Free_Buff_No==0){
MYDMA_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)ReceiveBuffer0,200);//DMA1通道5,外设为串口1,存储器为SendBuff,长度500.
Set_DMA_ISR();
USART1->CR3=1<<6; //使能串口1的DMA接收
MYDMA_Enable(DMA1_Channel5); //开始一次DMA接收
Free_Buff_No=1;
}else{
MYDMA_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)ReceiveBuffer1,200);//DMA1通道5,外设为串口1,存储器为SendBuff,长度500.
Set_DMA_ISR();
USART1->CR3=1<<6; //使能串口1的DMA接收
MYDMA_Enable(DMA1_Channel5); //开始一次DMA接收
Free_Buff_No=0;
}
Buff_OK=1;
}
}
//USART1用DMA方式接收数据
void USART_Receive_DMA(void){
Free_Buff_No=1;
MYDMA_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)ReceiveBuffer0,200);//DMA1通道5,外设为串口1,存储器为SendBuff,长度5200.
Set_DMA_ISR();
USART1->CR3=1<<6; //使能串口1的DMA接收
MYDMA_Enable(DMA1_Channel5);//开始一次DMA接收
}
//将DMA 缓冲0内数据写入文件
void Write_file_0(char *dir_path,char *file_path){
res = f_opendir(&dir,(TCHAR*)dir_path); //打开文件目录
res = f_open(&fsrc,(TCHAR *)file_path, FA_OPEN_ALWAYS | FA_WRITE); //打开文件
f_lseek(&fsrc,fsrc.fsize); //移动指针
f_write(&fsrc,&ReceiveBuffer0,sizeof(ReceiveBuffer0),&bw); //写数据
f_close(&fsrc);
}
//将DMA 缓冲1内数据写入文件
void Write_file_1(char *dir_path,char *file_path){
res = f_opendir(&dir,(TCHAR*)dir_path); //打开文件目录
res = f_open(&fsrc,(TCHAR *)file_path, FA_OPEN_ALWAYS | FA_WRITE); //打开文件
f_lseek(&fsrc,fsrc.fsize); //移动指针
f_write(&fsrc,&ReceiveBuffer1,sizeof(ReceiveBuffer1),&bw); //写数据
f_close(&fsrc);
}
|