在之前的《STM32串口IAP》一文中,通過傳輸數據流來升級程序,但是這種"裸"數據的傳輸方式存在這許多的問題,比如它沒有容錯機制,不能保證數據的正確傳輸,還比如說它無法獲知升級文件的信息,導致它在判斷何時停止接收數據上“猶豫不決”。正式為了解決上面的問題,才引進了YModem協議。
在《YModem協議簡介》一文中,已經詳細介紹了YModem的協議,這里就不再贅述,這篇文章就來講講如何將YModem協議轉換成代碼,并應用到串口升級的功能中。
還是以我自己的規范工程為例,講講走YModem協議的IAP工程的的實現。
1、工程的修改
1)串口升級當然需要用到USART與FLASH了,我的原工程已經添加了串口的庫文件stm32f10x_usart.c與stm32f10x_flash.c,所以就不需要在添加這兩個文件了。
2)新建IAP.c和IAP.h兩個文件分別保存到BSP文件夾下的src與inc兩個文件中。并將IAP.c文件添加到BSP工程組中。
3)新建YMoem.c和YMoem.h兩個文件分別保存到BSP文件夾下的src與inc兩個文件中。并將YModem.c文件添加到BSP工程組中。
4)新建Download.c和Download.h兩個文件分別保存到BSP文件夾下的src與inc兩個文件中。并將Download.c文件添加到BSP工程組中。
5)新建Upload.c和Upload.h兩個文件分別保存到BSP文件夾下的src與inc兩個文件中。并將Upload.c文件添加到BSP工程組中。
也就是說在BSP的工程組中有:BSP.c、IAP.c、YModem.c、Download.c、Upload.c這幾個文件,如下:
2、IAP.c與IAP.h的編寫
這個文件與之前在《STM32串口IAP》一文中的IAP.c與IAP.h文件代碼相似,只是做了細微的一些調整,不過這里還是仔細講述下。
同樣的考慮到開發板資源,我采用串口1作為升級的通道,所以原先在規范工程中作為調試接口的串口1的相關代碼需要從BSP.c與BSP.h兩個文件中完全刪除掉,出現此之外還要打開stm32f10x_it.c文件中將串口中斷服務程序的相關代碼刪除掉。
與完成一樣,IAP.c中第一個函數就是IAP_Init(),在這個函數中,配置串口相關的代碼,如配置串口引腳,串口時鐘,串口屬性,串口中斷等,具體的代碼如下:
/************************************************************* Function : IAP_Init Description: IAP初始化函數,初始化串口1 Input : none return : none *************************************************************/void IAP_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(COM1_RCC, ENABLE);//使能 USART2 時鐘 RCC_APB2PeriphClockCmd(COM1_GPIO_RCC, ENABLE);//使能串口2引腳時鐘 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//配置 USART2 的Tx 引腳類型為推挽式的 GPIO_InitStructure.GPIO_Pin = COM1_TX_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(COM1_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//配置 USART2 的Rx 為輸入懸空 GPIO_InitStructure.GPIO_Pin = COM1_RX_PIN; GPIO_Init(COM1_GPIO_PORT, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200;//設置波特率為115200 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//設置數據位為8位 USART_InitStructure.USART_StopBits = USART_StopBits_1;//設置停止位為1位 USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //沒有硬件流控 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//發送與接收 USART_Init(COM1,&USART_InitStructure);//串口2相關寄存器的配置 USART_Cmd(COM1,ENABLE);//使能串口2 }
上面的代碼中可以看出,這次我沒有打開串口中斷,而是使用查詢法來接收串口數據。
接下去在編寫串口的發送接收程序,代碼如下:
/************************************************************* Function : IAP_SerialSendByte Description: 串口發送字節 Input : c-要發送的字節 return : none *************************************************************/void IAP_SerialSendByte(u8 c){ USART_SendData(COM1, c); while (USART_GetFlagStatus(COM1, USART_FLAG_TXE) == RESET) {}}/************************************************************* Function : IAP_SerialSendStr Description: 串口發送字符串 Input : none return : none *************************************************************/void IAP_SerialSendStr(u8 *s){ while(*s != ' 主站蜘蛛池模板: 张家界市| 汪清县| 延安市| 夹江县| 油尖旺区| 浦北县| 怀远县| 灌阳县| 南陵县| 渝北区| 浙江省| 邛崃市| 横山县| 黔南| 平谷区| 博兴县| 吴川市| 蒙自县| 凯里市| 泸定县| 马尔康县| 称多县| 柯坪县| 曲靖市| 理塘县| 临沧市| 井研县| 瑞昌市| 和龙市| 汉阴县| 都江堰市| 南漳县| 枣庄市| 镇赉县| 陆良县| 宜宾县| 韶关市| 右玉县| 陕西省| 海安县| 镶黄旗|