一篇介绍了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();
- LED_Init();
- KEY_Init();
- uart_init(9600);
-
- if (KEY2==0&&KEY3==0)
- {
- sys_mode_flag = MODE_CARD_READ;
- GPIO_Config();
-
-
- MAL_Config();
-
-
- Interrupts_Config();
-
-
- Set_USBClock();
- USB_Init();
- while (bDeviceState != CONFIGURED)
- {
- ;
- }
- USB_Configured_LED();
-
- while (1)
- {
- ;
- }
- }
- else
- {
- sys_mode_flag = MODE_IAP_DEVICE;
- Status = SD_Init();
- if (Status == SD_OK)
- {
-
- Status = SD_GetCardInfo(&SDCardInfo);
- }
- if (Status == SD_OK)
- {
- show_sdcard_info();
-
- Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
- }
- if (Status == SD_OK)
- {
- Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
- }
-
- 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文件系统挂载。
-
- 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 <fcount; i++ )
- {
- printf("\r\n第%d个文件:\r\n",i);
- printf("fname: %s \r\n",(char*)fileList[i]);
- }
- OS_EXIT_CRITICAL();
- }
这个函数用于扫描某个目录下面的文件,支持英文长文件名。关于FATFS的长文件名,只需配置ffconf.h中
#define _CODE_PAGE 437
#define _USE_LFN 1 /* 0 to 3 */
然后读取文件的时候使用finfo.lfname进行操作。
上面代码对读出来的文件名进行了排序。使用stdlib.H标准库中的函数qsort进行。
下面是串口调式的打印信息
![](https://img-blog.csdn.net/20130815091644156?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXEyMzYxMDYzMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
剩下的就是读取文件,CAN发送数据的功能。
代码:http://download.csdn.net/detail/qq236106303/5951065