×
单片机 > 单片机程序设计 > 详情

STM32 IAP 设计实例 (二)

发布时间:2020-08-21 发布时间:
|
上一篇介绍了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参考了网上的一些例子,比较乱。

[cpp] view plain copy
 
  1. int main(void)  
  2. {     
  3. uint16_t Status = 0;   
  4.       
  5.    delay_init();         //延时初始化        
  6. NVIC_Configuration();    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级  
  7. LED_Init();          //初始化与LED连接的硬件接口  
  8. KEY_Init();   
  9.    uart_init(9600);    
  10.    
  11.    if (KEY2==0&&KEY3==0)//按着组合按键启动,进入读卡器模式  
  12.    {  
  13.        sys_mode_flag = MODE_CARD_READ;  
  14.        GPIO_Config();  
  15.   
  16.        /*MAL配置 */  
  17.        MAL_Config();  
  18.      
  19.        /*中断配置 */  
  20.        Interrupts_Config();  
  21.   
  22.        /*USB接口初始化*/  
  23.        Set_USBClock();//设置USB接口时钟  
  24.        USB_Init();//USB接口初始化  
  25.        while (bDeviceState != CONFIGURED)  
  26.        {  
  27.             ;//reserved  
  28.        }  
  29.        USB_Configured_LED();//设置USB接口的LED指示灯状态  
  30.   
  31.        while (1)  
  32.        {      
  33.         ;  
  34.        }  
  35.    }  
  36.    else  
  37.    {  
  38.        sys_mode_flag = MODE_IAP_DEVICE;  
  39.        Status = SD_Init();  
  40.        if (Status == SD_OK)  
  41.        {  
  42.            /*----------------- Read CSD/CID MSD registers ------------------*/  
  43.            Status = SD_GetCardInfo(&SDCardInfo);  
  44.        }  
  45.        if (Status == SD_OK)  
  46.        {  
  47.            show_sdcard_info();  
  48.            /*----------------- Select Card --------------------------------*/  
  49.            Status = SD_SelectDeselect((u32) (SDCardInfo.RCA <
  50.        }  
  51.        if (Status == SD_OK)  
  52.        {  
  53.            Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);  
  54.        }  
  55.        /* Set Device Transfer Mode to DMA */  
  56.        if (Status == SD_OK)  
  57.        {    
  58.            Status = SD_SetDeviceMode(SD_DMA_MODE);  
  59.        }  
  60.        disk_initialize(0);  
  61.        f_mount(0, &fs);  
  62.          
  63.        OSInit();     
  64.        OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务  
  65.        OSStart();  
  66.    }  
  67. }  


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

[cpp] view plain copy
 
  1. //扫描path录下的所有BIN文件  
  2. void scan_files(u8 *path)  
  3. {  
  4.     OS_CPU_SR cpu_sr;      
  5.     FRESULT res;  
  6.     FILINFO finfo;  
  7.     char lfn[50];  //用于存长文件名  
  8.     DIR dirs;  
  9.     char* result;  
  10.     u8 i=0;  
  11.       
  12.     finfo.lfsize = sizeof(lfn);  
  13.     finfo.lfname = lfn;  
  14.   
  15.     OS_ENTER_CRITICAL();  
  16.   
  17.     res = f_opendir(&dirs, (const TCHAR*)path); /* 打开工作目录 */  
  18.     if(res == FR_OK)  
  19.     {  
  20.         printf("working directory:%s\r\n",path);  
  21.         fcount = 0;  
  22.         while( f_readdir(&dirs, &finfo) == FR_OK)/* 依次读取文件名 */  
  23.         {  
  24.             if ( finfo.fattrib & AM_ARC) /* 判断是否为存档型文档 */   
  25.             {  
  26.                 if(finfo.lfname[0] == NULL && finfo.fname !=NULL) /*当长文件名称为空,短文件名非空时转换*/  
  27.                 {  
  28.                     finfo.lfname =finfo.fname;  
  29.                 }  
  30.                 /* 文件名为空即到达了目录的末尾,退出 */   
  31.                 if( !finfo.lfname[0] )  
  32.                 {  
  33.                     break;  
  34.                 }  
  35.                 result = strstr(finfo.lfname,  ".bin");  
  36.                 if ( result != NULL)  
  37.                 {     
  38.                     printf("\r\n第%d个文件:\r\n",fcount);  
  39.                     printf("fname: %s \r\n",finfo.lfname );  
  40.                     printf("fsize: %d \r\n",finfo.fsize);  
  41.                     if ( fcount 
  42.                     {  
  43.                         strcpy((char*)fileList[fcount], finfo.lfname);  
  44.                     }  
  45.                     else//大于最多的存储量   
  46.                     {  
  47.                         break;  
  48.                     }  
  49.                     fcount++;  
  50.                 }  
  51.             }      
  52.         }  
  53.     }  
  54.     qsort(fileList, fcount, sizeof(fileList[0]), cmp);  
  55.     printf("\r\n--------------------after sort--------------------\r\n");  
  56.     for ( i = 0 ; i 
  57.     {  
  58.         printf("\r\n第%d个文件:\r\n",i);  
  59.         printf("fname: %s \r\n",(char*)fileList[i]);  
  60.     }  
  61.     OS_EXIT_CRITICAL();      
  62. }  


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

#define _USE_LFN 1  /* 0 to 3 */

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

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

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

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

关键字:STM32  IAP

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯