STM32 IAP 设计实例 (二)

上一篇介绍了IAP的实现。这里开始介绍主机的一个设计实例。

 

目标功能:STM32做主机,硬件接口主要包括SD card, USB,CAN, LCD,按键。

主要功能:

1,通过USB链接到PC,将用于更新的APP程序的BIN文件,放入SD中。

2,STM32通过FATFS读写SD卡中的文件。

3,通过CAN接口发送数据给从机。

4,LCD和按键用于人机交互。

 

PC通过STM32 USB读取SD卡的部分功能直接使用使用了神州三号开发板中的例程。移植FATFS参考了网上的一些例子,比较乱。

 int main(void)
 {   
	uint16_t Status = 0; 
     
    delay_init();	     //延时初始化	  
	NVIC_Configuration(); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	LED_Init();		  	 //初始化与LED连接的硬件接口
	KEY_Init(); 
    uart_init(9600);  
	 
    if (KEY2==0&&KEY3==0)//按着组合按键启动,进入读卡器模式
    {
        sys_mode_flag = MODE_CARD_READ;
        GPIO_Config();

        /*MAL配置 */
        MAL_Config();
    
        /*中断配置 */
        Interrupts_Config();

        /*USB接口初始化*/
        Set_USBClock();//设置USB接口时钟
        USB_Init();//USB接口初始化
        while (bDeviceState != CONFIGURED)
        {
  	        ;//reserved
        }
        USB_Configured_LED();//设置USB接口的LED指示灯状态

        while (1)
        {    
  	    ;
        }
    }
    else
    {
        sys_mode_flag = MODE_IAP_DEVICE;
        Status = SD_Init();
        if (Status == SD_OK)
        {
            /*----------------- Read CSD/CID MSD registers ------------------*/
            Status = SD_GetCardInfo(&SDCardInfo);
        }
        if (Status == SD_OK)
        {
            show_sdcard_info();
            /*----------------- Select Card --------------------------------*/
            Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
        }
        if (Status == SD_OK)
        {
            Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
        }
        /* Set Device Transfer Mode to DMA */
        if (Status == SD_OK)
        {  
            Status = SD_SetDeviceMode(SD_DMA_MODE);
        }
        disk_initialize(0);
        f_mount(0, &fs);
        
        OSInit();   
        OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
        OSStart();
    }
 }


从main函数可以看出,上电如果按下组合按键,进入USB读卡器模式,可以在PC上将SD卡识别成可以移动磁盘。没按组合键,则将SD卡,通过FATFS文件系统挂载。

//扫描path录下的所有BIN文件
void scan_files(u8 *path)
{
    OS_CPU_SR cpu_sr;    
    FRESULT res;
    FILINFO finfo;
    char lfn[50];  //用于存长文件名
    DIR dirs;
    char* result;
    u8 i=0;
    
    finfo.lfsize = sizeof(lfn);
    finfo.lfname = lfn;

    OS_ENTER_CRITICAL();

    res = f_opendir(&dirs, (const TCHAR*)path); /* 打开工作目录 */
    if(res == FR_OK)
    {
        printf("working directory:%s\r\n",path);
        fcount = 0;
        while( f_readdir(&dirs, &finfo) == FR_OK)/* 依次读取文件名 */
        {
            if ( finfo.fattrib & AM_ARC) /* 判断是否为存档型文档 */ 
            {
                if(finfo.lfname[0] == NULL && finfo.fname !=NULL) /*当长文件名称为空,短文件名非空时转换*/
                {
                    finfo.lfname =finfo.fname;
                }
                /* 文件名为空即到达了目录的末尾,退出 */ 
                if( !finfo.lfname[0] )
                {
                    break;
                }
                result = strstr(finfo.lfname,  ".bin");
                if ( result != NULL)
                {   
                    printf("\r\n第%d个文件:\r\n",fcount);
                    printf("fname: %s \r\n",finfo.lfname );
                    printf("fsize: %d \r\n",finfo.fsize);
                    if ( fcount < MAX_FILE_COUNT)
                    {
                        strcpy((char*)fileList[fcount], finfo.lfname);
                    }
                    else//大于最多的存储量 
                    {
                        break;
                    }
                    fcount++;
                }
            }    
        }
    }
    qsort(fileList, fcount, sizeof(fileList[0]), cmp);
    printf("\r\n--------------------after sort--------------------\r\n");
    for ( i = 0 ; i 


这个函数用于扫描某个目录下面的文件,支持英文长文件名。关于FATFS的长文件名,只需配置ffconf.h中
#define _CODE_PAGE 437

#define _USE_LFN 1  /* 0 to 3 */

然后读取文件的时候使用finfo.lfname进行操作。

上面代码对读出来的文件名进行了排序。使用stdlib.H标准库中的函数qsort进行。

下面是串口调式的打印信息

STM32 IAP 设计实例 (二)_第1张图片

剩下的就是读取文件,CAN发送数据的功能。

 

代码:http://download.csdn.net/detail/qq236106303/5951065

你可能感兴趣的:(STM32 IAP 设计实例 (二))