最近项目中需要写个数据记录功能的程序。数据记录芯片用到了CH378。具体的流程图如下:通过不同的电源输入,来选择CH378的数据流向,通过模式选择开关,来选择CH378的通讯方式。

stm32 emmc 数据记录仪 stm32行车记录仪_stm32 emmc 数据记录仪

相关初始化及写数据代码如下。实际的调试中,参考了一部分CH378官方提供的初始化及数据读写函数。另外,对于文件名的创建也做了相应优化。即数据记录仪每次上下电会记录到不同的文件名下,这样有利于文件管理。

/* 头文件包含 */
#include "HAL.H"
/*******************************************************************************
* Function Name  : mInitCH378Host
* Description    : 初始化CH378
* Input          : None
* Output         : None
* Return         : 返回操作状态
*******************************************************************************/
UINT8 mInitCH378Host( void ) 
{
	UINT8  res;
    UINT8  res1;
	/* 接口硬件初始化,通过write_data_mode和sd_mode选择*/
	/* 读卡+串口;读卡+并口;写卡+串口;写卡+并口四种模式*/
    /* 根据不同通讯方式,分别进行硬件初始化 */
	CH378_Port_Init( );  	
	
	//串口方式(计算中断等待时间及串口接收等待时间,设置tf卡连接初始化返回值)
	if(write_data_mode==0x01)
	{
	  interrupt_wait=(u32)((float)115200*(float)8000000/(float)UART_WORK_BAUDRATE);
	  uart_wait=(u32)((float)115200*(float)16777200/(float)UART_WORK_BAUDRATE);
	  res1=0x00;
	}
	//并口方式(设定中断等待时间,不再需要串口接收等待时间,设置tf卡连接初始化返回值)
	else if(write_data_mode==0x02)
	{
	  interrupt_wait=(u32)((float)115200*(float)8000000/(float)115200);
	  uart_wait=(u32)((float)115200*(float)16777200/(float)115200);
	  res1=0x51;
	}
		
	/* 测试单片机与CH378之间的通讯接口 */
	while(1)
	{
	   
	 xWriteCH378Cmd( CMD11_CHECK_EXIST );  						
	 xWriteCH378Data( 0x65 );
	 res = xReadCH378Data( );
		
	 if(res==0x9A)
	 {
	   break;
	 }
	   
	}
	
	
#ifdef	UART_WORK_BAUDRATE
	/* 设置CH378串口通信波特率 */
	xWriteCH378Cmd( CMD31_SET_BAUDRATE );  						
	xWriteCH378Data( (UINT8)UART_WORK_BAUDRATE );
	xWriteCH378Data( (UINT8)( UART_WORK_BAUDRATE >> 8 ) );
	xWriteCH378Data( (UINT8)( UART_WORK_BAUDRATE >> 16 ) );
	//xEndCH378Cmd( );  										

	/* 设置单片机本身串口通信波特率 */
	mDelaymS( 3 );  
	Set_MCU_BaudRate( );  										


#endif

	/* 设置CH378工作模式,操作TF卡 */
	xWriteCH378Cmd( CMD11_SET_USB_MODE );  						 
	xWriteCH378Data( sd_mode );									

	/* 等待模式设置完毕,延时50ms */	
	mDelaymS( 50 );					
	
    res = xReadCH378Data( );
	
	if(res!=CMD_RET_SUCCESS)
	{
	  return 0x01;
	}
	//如果为写入TF卡模式
	if(sd_mode==0x03)
	{
	  while(1)
      {
      /* 判断磁盘是否连接 */	
      xWriteCH378Cmd( CMD0H_DISK_CONNECT );  						
	  res = xReadCH378Data( );
	
	  if(res==res1)
	  {
		 break;
	  }	  
	  }  
    }
	//如果为写入TF卡模式 
	if(sd_mode==0x03)
	{
	  while(1)
      {
      /* 初始化磁盘 */	
      xWriteCH378Cmd( CMD0H_DISK_MOUNT );  						
	  res = xReadCH378Data( );
	
	  if(res==res1)
	  {
	     return 0x00;
		 //break;
	  }	  
	  }   
    }
}

/*******************************************************************************
* Function Name  : main
* Description    : 主函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
UINT16	total;													 /* 记录当前缓冲在FILE_DATA_BUF中的数据长度 */
UINT8	xdata	FileDataBuf[0x4000];							 /* 文件缓冲区,太小则速度慢 */

void main( void ) 
{ 
    //返回状态
	UINT8  ret,status;
	UINT16 i;
	//用于存储文件名
	char filename[20]={0};
	
    /* 初始化CH378 */	
	status = mInitCH378Host( );  															 	
	mStopIfError( status );
	
	//修改文件名
	if(sd_mode==0x03)
	{
		
	  for(i=0;i<200;i++)
	  {
		//串口方式  
	    if(write_data_mode==0x01)
		{
		
		   sprintf( filename, "/LOGUART%d.BIN", i );
		}
		//并口方式
		else if(write_data_mode==0x02)
		{
		  sprintf( filename, "/LOGPORT%d.BIN", i );
		}
		
		ret=CH378FileOpen( filename ); 
		
		 /* 没有找到文件,必须新建文件 */
		if( ret == ERR_MISS_FILE ) 							
		{  
		
		    ret = CH378FileCreate( NULL ); 
			ret = CH378FileClose( FALSE ); 
            break;			
			
		}
		 /* 文件已经存在 */
		else if( ret == ERR_SUCCESS ) 							
		{  
		   continue;
		}
		
		//关闭文件
		ret = CH378FileClose( FALSE ); 
		  
	  }
	 
	 //文件名获取异常
	  if(i>200)
	  {
		return ;
	  }
	
	
	}

	while( 1 ) 													 
	{
		
		//串口获取1000个数据,total为实际获取到的数据量,1000表示想要的数据量
		//获取到的数据存储到FileDataBuf中
		total=uartGetData(USART_CHANNEL_4,FileDataBuf,1000);
		
		//如果未获取到数据,不再执行写入数据操作
		if(total==0x00)
		  continue;
		
		if(sd_mode==0x03)
		{
			
		   status=CH378FileOpen( filename );	
		   
		   if(status == ERR_SUCCESS)
		   {
			  /* 以扇区为单位移到文件尾部 */
			  status = CH378SecLocate( 0xFFFFFFFF );  			
			  mStopIfError( status ); 
		   }
		   else if(ret == ERR_MISS_FILE)
		   {
			  ret = CH378FileCreate( NULL );  
		   }
		   
		   //字节写数据
		   ret=CH378ByteWrite(FileDataBuf,total,NULL);
		   //关闭文件
		   ret = CH378FileClose( FALSE ); 
		   	
			
		}
		

	}
}
`