上一篇介绍了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 <
- }
- 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
- {
- 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
- {
- 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进行。
下面是串口调式的打印信息
剩下的就是读取文件,CAN发送数据的功能。
关键字:STM32 IAP『本文转载自网络,版权归原作者所有,如有侵权请联系删除』