找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4292|回复: 5
打印 上一主题 下一主题
收起左侧

STM32 IAP之bootloader源码协议采用YMODEM

  [复制链接]
跳转到指定楼层
楼主
ID:393904 发表于 2018-9-5 10:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32 IAP之bootloader  协议采用YMODEM:
分bootloader工程和IAP工程代码。


* 本例程在 奋斗版STM32开发板V2,V2.1,V3,V5,MINI上调试通过           
*
* 文件名: main.c
* 内容简述:   
*      
*    演示通过串口1显示ADC1的11通道的测量结果
*    辅助软件:PC机上需要运行串口调试助手软件。
   
    基于MDK版本:        3.8
    基于官方外设库版本: 3.5   
*
* 文件历史:
* 版本号  日期       作者    说明
*
*/

1设计要求
利用ADC的第11通道对开发板输入的电压值作AD转换,采用连续转换模式,转换结果通过DMA通
道1读取。ADC转换的结果,每间隔1秒钟向串口发送一次。

2 硬件电路设计                                       

            
在开发板上通用I/O口PC.01与XS8的14脚相连,将PC.01映射到ADC第11通道,即可实现利用

ADC_IN11
对输入电压作AD转换。

3软件程序设计
    根据设计任务要求,软件程序主要包括:
    (1)    配置GPIO口,将PC.01配置为ADC的第11采样通道;将配置GPIO中PA.09和PA.10根

引脚为串口输入输出。
    (2)    设置ADC,将ADC_IN11设置为连续转换模式;
    (3)    配置DMA通道1用于ADC_IN14传输转换的结果;
    (4)    配置串口及相关发送功能;
    (5)    每隔1S向串口输出AD转换结果。

4 运行过程
(1)    使用Keil uVision3 通过JLINK仿真器连接开发板,使用串口线,连接实验板
上的UART1(XS5)和PC机的串口,打开实验例程目录下的STM32-FD-ADC.Uv2例程,编译链接工程;
(2)    在PC机上运行windows自带的超级终端串口通信程序(波特率115200、1位停止位、无校验

位、无硬件流
控制);或者使用其它串口通信程序;
(3)    点击MDK 的Debug菜单,点击Start/Stop Debug Session;
(4)    可以看到串口输出数值不断变化,正常显示结果如下所示。

usart1 print AD_value --------------------------
The current AD value = 2096
The current AD value = 2096
The current AD value = 2048
The current AD value = 2087
The current AD value = 2112
The current AD value = 2112
The current AD value = 2003
The current AD value = 1998
The current AD value = 1999
The current AD value = 2092
The current AD value = 2048
The current AD value = 2051
The current AD value = 2056
The current AD value = 2048
The current AD value = 2048
The current AD value = 2096
The current AD value = 2001
....
....
  1. #include "stm32f10x.h"          
  2. #include "stm32f10x_adc.h"
  3. #include "stm32f10x_dma.h"
  4. #include "stm32f10x_rcc.h"
  5. #include "stm32f10x_gpio.h"
  6. #include "stm32f10x_usart.h"         
  7. #include "stm32f10x_flash.h"
  8. #include "misc.h"                 
  9. #include  <stdarg.h>

  10. #define ADC1_DR_Address    ((u32)0x4001244C)         
  11. #define FLASH_IAP_ADDR                0x08000000          //iap程序起始地址(存放在FLASH)

  12. #define LED1   GPIO_Pin_5
  13. #define LED2   GPIO_Pin_6
  14. #define LED3   GPIO_Pin_3

  15. static unsigned long ticks;
  16. unsigned char Clock1s;


  17. vu16 ADC_ConvertedValue;

  18. typedef  void (*iapfun)(void);
  19. iapfun jump2iap;

  20. void RCC_Configuration(void);  
  21. void ADC_Configuration(void);
  22. void Usart1_Init(void);
  23. void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);
  24. void LED_Configuration(void);
  25. void KEY_Configuration(void);
  26. void iap_jump(u32 iapxaddr);

  27. /****************************************************************************
  28. * 名    称:int main(void)
  29. * 功    能:主函数
  30. * 入口参数:无
  31. * 出口参数:无
  32. * 说    明:
  33. * 调用方法:
  34. ****************************************************************************/
  35. int main(void)
  36. {       
  37.         static  _Bool flag_ledtoogle=0;
  38.   RCC_Configuration();                     //设置内部时钟及外设时钟使能
  39.         LED_Configuration();
  40.         KEY_Configuration();
  41.   Usart1_Init();                             //串口1初始化  
  42.   ADC_Configuration();                                 //ADC初始化
  43.   USART_OUT(USART1,"\r\n USART1 print AD_value -------------------------- \r\n");
  44.   while(1)
  45.   {
  46.            if (ticks++ >= 900000)
  47.                 {        //间隔时间显示转换结果
  48.                         ticks   = 0;
  49.                         Clock1s = 1;
  50.                         flag_ledtoogle^=1;
  51.                 }
  52.                 if(flag_ledtoogle)
  53.                 {
  54.                                 GPIO_ResetBits(GPIOB, LED1);  //熄灭LED0-3       
  55.                 }               
  56.                 else
  57.                 {
  58.                                 GPIO_SetBits(GPIOB, LED1);  //熄灭LED0-3       
  59.                 }
  60.          if (Clock1s)
  61.                  {
  62.                                 Clock1s = 0;   
  63.                                          
  64.                                 USART_OUT(USART1,"The current AD value = %d \r\n", ADC_ConvertedValue);
  65.      }  
  66.                  
  67.                  if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)  == 0x00)
  68.                  {
  69.                                 iap_jump(FLASH_IAP_ADDR);
  70.                  }
  71.   }
  72. }
  73. //=============================================================================================
  74. //函数名称: void iap_jump(u32 iapxaddr)
  75. //输入参数: appxaddr:用户代码起始地址.
  76. //输出参数:
  77. //返回值  :
  78. //功能描述: 跳转到IAP
  79. //注意事项: void
  80. //=============================================================================================
  81. void iap_jump(u32 iapxaddr)
  82. {
  83.         if(((*(vu32*)iapxaddr)&0x2FFE0000)==0x20000000)        //检查栈顶地址是否合法.0x20000000是sram的起始地址,也是程序的栈顶地址
  84.         {
  85. //                printf("ok\r\n");
  86.                 //Delay_Ms(10);
  87.                 jump2iap=(iapfun)*(vu32*)(iapxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
  88.         //        MSR_MSP(*(vu32*)iapxaddr);                                        //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
  89.                 __set_MSP(*(__IO uint32_t*) iapxaddr);
  90.                 jump2iap();                                                                        //跳转到APP.
  91.         }
  92.         else
  93.         {
  94. //                printf("iap program loss,please check\r\n");
  95.         }
  96. }
  97. /*******************************************************************************
  98.   * @函数名称        KEY_Configuration
  99.   * @函数说明   按键初始化
  100.   * @输入参数   无
  101.   * @输出参数   无
  102.   * @返回参数   无
  103. *******************************************************************************/
  104. void KEY_Configuration(void)
  105. {
  106.     GPIO_InitTypeDef GPIO_InitStructure;
  107.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  108.     //配置按键
  109.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  110.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  111.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  112. }
  113. /*******************************************************************************
  114.   * @函数名称        LED_Configuration
  115.   * @函数说明   配置使用LED
  116.   * @输入参数   无
  117.   * @输出参数   无
  118.   * @返回参数   无
  119. *******************************************************************************/
  120. void LED_Configuration(void)
  121. {
  122.     GPIO_InitTypeDef GPIO_InitStructure;
  123.     //使能LED所在GPIO的时钟
  124.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
  125.     //初始化LED的GPIO
  126.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  127.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         
  128.                 GPIO_InitStructure.GPIO_Pin =  LED1;
  129.           GPIO_Init(GPIOB, &GPIO_InitStructure);       
  130.                 GPIO_SetBits(GPIOB, LED1);  //熄灭LED0-3
  131.        
  132.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);       
  133.           //初始化LED的GPIO
  134.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  135.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  136.                 GPIO_InitStructure.GPIO_Pin =  LED2 | LED3;         
  137.                 GPIO_Init(GPIOD, &GPIO_InitStructure);                       
  138.   
  139.     GPIO_SetBits(GPIOD, LED2 | LED3);  //熄灭LED0-3
  140. }

  141. /****************************************************************************
  142. * 名    称:void ADC_Configuration(void)
  143. * 功    能:ADC 配置函数
  144. * 入口参数:无
  145. * 出口参数:无
  146. * 说    明:
  147. * 调用方法:
  148. ****************************************************************************/
  149. void ADC_Configuration(void)
  150. {
  151.         ADC_InitTypeDef ADC_InitStructure;
  152.         GPIO_InitTypeDef GPIO_InitStructure;
  153.         DMA_InitTypeDef DMA_InitStructure;

  154.     //设置AD模拟输入端口为输入 1路AD 规则通道
  155.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  156.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  157.           GPIO_Init(GPIOC, &GPIO_InitStructure);
  158.         /* Enable DMA clock */
  159.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  160.    /* Enable ADC1 and GPIOC clock */
  161.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);

  162.           /* DMA channel1 configuration ----------------------------------------------*/
  163.         //使能DMA
  164.         DMA_DeInit(DMA1_Channel1);
  165.         DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;                                    //DMA通道1的地址
  166.         DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;                    //DMA传送地址
  167.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                                    //传送方向
  168.         DMA_InitStructure.DMA_BufferSize = 1;                                                                            //传送内存大小,1个16位
  169.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;         
  170.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                            //传送内存地址递增
  171.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;                //ADC1转换的数据是16位
  172.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                                //传送的目的地址是16位宽度
  173.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                                        //循环
  174.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  175.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  176.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  177.    
  178.         /* 允许DMA1通道1传输结束中断 */
  179.         //DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);


  180.         //使能DMA通道1
  181.         DMA_Cmd(DMA1_Channel1, ENABLE);
  182.   
  183.   
  184.         //ADC配置
  185.         /* ADC转换时间: ─ STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
  186.         ADC采样范围0-3.3V    */
  187.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);                   //设置ADC的时钟为72MHZ/6=12M

  188.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC1工作在独立模式
  189.         ADC_InitStructure.ADC_ScanConvMode = ENABLE;                //模数转换工作在扫描模式(多通道)还是单次(单通道)模式
  190.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在连续模式,还是单次模式
  191.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
  192.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
  193.         ADC_InitStructure.ADC_NbrOfChannel = 1;               //规定了顺序进行规则转换的ADC通道的数目。这个数目的取值范围是1到16
  194.         ADC_Init(ADC1, &ADC_InitStructure);
  195.        
  196.         /* ADC1 regular channels configuration [规则模式通道配置]*/

  197.         //ADC1 规则通道配置
  198.           ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);          //通道11采样时间 55.5周期
  199.          

  200.         //使能ADC1 DMA
  201.         ADC_DMACmd(ADC1, ENABLE);
  202.         //使能ADC1
  203.         ADC_Cmd(ADC1, ENABLE);       
  204.        
  205.         // 初始化ADC1校准寄存器
  206.         ADC_ResetCalibration(ADC1);
  207.         //检测ADC1校准寄存器初始化是否完成
  208.         while(ADC_GetResetCalibrationStatus(ADC1));
  209.        
  210.         //开始校准ADC1
  211.         ADC_StartCalibration(ADC1);
  212.         //检测是否完成校准
  213.         while(ADC_GetCalibrationStatus(ADC1));
  214.        
  215.         //ADC1转换启动
  216.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);         
  217. }
  218. /****************************************************************************
  219. * 名    称:void RCC_Configuration(void)
  220. * 功    能:系统时钟配置为72MHZ, 外设时钟配置
  221. * 入口参数:无
  222. * 出口参数:无
  223. * 说    明:
  224. * 调用方法:无
  225. ****************************************************************************/
  226. void RCC_Configuration(void){

  227.   SystemInit();
  228.   RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  229.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  230.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  231.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
  232.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
  233.                                                   | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE);
  234. }

  235. /****************************************************************************
  236. * 名    称:void Usart1_Init(void)
  237. * 功    能:串口1初始化函数
  238. * 入口参数:无
  239. * 出口参数:无
  240. * 说    明:
  241. * 调用方法:无
  242. ****************************************************************************/
  243. void Usart1_Init(void)
  244. {
  245.   GPIO_InitTypeDef GPIO_InitStructure;
  246.   USART_InitTypeDef USART_InitStructure;

  247.   RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 , ENABLE);         //使能串口1时钟

  248.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                               //LCD背光控制
  249.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  250.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  251.   GPIO_Init(GPIOD, &GPIO_InitStructure);
  252.   GPIO_ResetBits(GPIOD, GPIO_Pin_13);                                      //LCD背光关闭       

  253.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                                  //USART1 TX
  254.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  255.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                     //复用推挽输出
  256.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                     //A端口

  257.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                          //USART1 RX
  258.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;            //复用开漏输入
  259.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                  //A端口

  260.   USART_InitStructure.USART_BaudRate = 9600;                                                //速率115200bps
  261.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;                //数据位8位
  262.   USART_InitStructure.USART_StopBits = USART_StopBits_1;                        //停止位1位
  263.   USART_InitStructure.USART_Parity = USART_Parity_No;                                //无校验位
  264.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件流控
  265.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                                        //收发模式

  266.   /* Configure USART1 */
  267.   USART_Init(USART1, &USART_InitStructure);                                                        //配置串口参数函数   
  268.    /* Enable the USART1 */
  269.   USART_Cmd(USART1, ENABLE);       
  270.   
  271. }
  272. /******************************************************
  273.                 整形数据转字符串函数
  274.         char *itoa(int value, char *string, int radix)
  275.                 radix=10 标示是10进制        非十进制,转换结果为0;  

  276.             例:d=-379;
  277.                 执行        itoa(d, buf, 10); 后
  278.                
  279.                 buf="-379"                                                                                     
  280. **********************************************************/
  281. char *itoa(int value, char *string, int radix)
  282. {
  283.     int     i, d;
  284.     int     flag = 0;
  285.     char    *ptr = string;

  286.     /* This implementation only works for decimal numbers. */
  287.     if (radix != 10)
  288.     {
  289.         *ptr = 0;
  290.         return string;
  291.     }

  292.     if (!value)
  293.     {
  294.         *ptr++ = 0x30;
  295.         *ptr = 0;
  296.         return string;
  297.     }

  298.     /* if this is a negative value insert the minus sign. */
  299.     if (value < 0)
  300.     {
  301.         *ptr++ = '-';

  302.         /* Make the value positive. */
  303.         value *= -1;
  304.     }

  305.     for (i = 10000; i > 0; i /= 10)
  306.     {
  307.         d = value / i;

  308.         if (d || flag)
  309.         {
  310.             *ptr++ = (char)(d + 0x30);
  311.             value -= (d * i);
  312.             flag = 1;
  313.         }
  314.     }

  315.     /* Null terminate the string. */
  316.     *ptr = 0;

  317.     return string;

  318. } /* NCL_Itoa */
  319. /****************************************************************************
  320. * 名    称:void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...)
  321. * 功    能:格式化串口输出函数
  322. * 入口参数:USARTx:  指定串口
  323.                         Data:   发送数组
  324.                         ...:     不定参数
  325. * 出口参数:无
  326. * 说    明:格式化串口输出函数
  327.                 "\r"        回车符           USART_OUT(USART1, "abcdefg\r")   
  328.                         "\n"        换行符           USART_OUT(USART1, "abcdefg\r\n")
  329.                         "%s"        字符串           USART_OUT(USART1, "字符串是:%s","abcdefg")
  330.                         "%d"        十进制           USART_OUT(USART1, "a=%d",10)
  331. * 调用方法:无
  332. ****************************************************************************/
  333. void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){

  334.         const char *s;
  335.     int d;
  336.    
  337.     char buf[16];
  338.     va_list ap;
  339.     va_start(ap, Data);

  340.         while(*Data!=0){                                                          //判断是否到达字符串结束符
  341.                 if(*Data==0x5c){                                                                          //'\'
  342.                         switch (*++Data){
  343.                                 case 'r':                                                                  //回车符
  344.                                         USART_SendData(USARTx, 0x0d);          

  345.                                         Data++;
  346.                                         break;
  347.                                 case 'n':                                                                  //换行符
  348.                                         USART_SendData(USARTx, 0x0a);       
  349.                                         Data++;
  350.                                         break;
  351.                                
  352.                                 default:
  353.                                         Data++;
  354.                                     break;
  355.                         }
  356.                        
  357.                          
  358.                 }
  359.                 else if(*Data=='%'){                                                                          //
  360.                         switch (*++Data){                               
  361.                                 case 's':                                                                                  //字符串
  362.                         s = va_arg(ap, const char *);
  363.                         for ( ; *s; s++) {
  364.                             USART_SendData(USARTx,*s);
  365.                                                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  366.                         }
  367.                                         Data++;
  368.                         break;
  369.                     case 'd':                                                                                  //十进制
  370.                         d = va_arg(ap, int);
  371.                         itoa(d, buf, 10);
  372.                         for (s = buf; *s; s++) {
  373.                             USART_SendData(USARTx,*s);
  374.                                                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  375.                         }
  376.                                         Data++;
  377.                         break;
  378.                                 default:
  379.                                         Data++;
  380.                                     break;
  381.                         }                 
  382.                 }
  383.                 else USART_SendData(USARTx, *Data++);
  384.                 while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
  385.         }
  386. }
  387. /******************* (C) COPYRIGHT 2013 奋斗STM32 *****END OF FILE****/
复制代码
  1. //=======================================Copyright(c)===========================================
  2. //                                                                                         Auto Code Making Company
  3. //                                                                                        Auto Code Department
  4. //                                                                                                CopyRight Private
  5. //-------------------------------------------------FileMessage------------------------------------
  6. //FileName          main.c
  7. //Author         yanggang
  8. //Creation Time
  9.           
  10. //Description
  11. //-----------------------------------------------当前版本修订----------------------------------
  12. //修改人       
  13. //版        本         
  14. //修改日期       
  15. //Description       
  16. //=============================================================================================


  17. /*******************************************************************************
  18. ** 文件名:                 mian.c
  19. ** 功能:                USART初始化和RCC设置,然后从common.c中执行主菜单
  20. ** 相关文件:        stm32f10x.h
  21. *******************************************************************************/

  22. /* 包含头文件 *****************************************************************/
  23. #include "common.h"
  24. /* 类型声明 ------------------------------------------------------------------*/
  25. /* 宏 ------------------------------------------------------------------------*/
  26. #define LED0   GPIO_Pin_0
  27. #define LED1   GPIO_Pin_1
  28. #define LED2   GPIO_Pin_2
  29. #define LED3   GPIO_Pin_3
  30. /* 变量 ----------------------------------------------------------------------*/
  31. extern pFunction Jump_To_Application;
  32. extern uint32_t JumpAddress;

  33. /* 函数声明 ------------------------------------------------------------------*/
  34. void Delay(__IO uint32_t nCount);
  35. void LED_Configuration(void);
  36. static void IAP_Init(void);
  37. void KEY_Configuration(void);
  38. void GPIO_Configuration(void);
  39. void USART_Configuration(void);
  40. /* 函数功能 ------------------------------------------------------------------*/

  41. /*******************************************************************************
  42.   * @函数名称        main
  43.   * @函数说明   主函数
  44.   * @输入参数   无
  45.   * @输出参数   无
  46.   * @返回参数   无
  47. *******************************************************************************/
  48. int main(void)
  49. {
  50.     //Flash 解锁
  51.     FLASH_Unlock();
  52.     LED_Configuration();
  53.     //配置按键
  54.     KEY_Configuration() ;
  55.     IAP_Init();
  56.     //按键是否按下
  57.     if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)  == 0x00)
  58.     {
  59.         //假如USER1按键按下
  60.         //执行IAP驱动程序更新Flash程序

  61.         SerialPutString("\r\n======================================================================");
  62.         SerialPutString("\r\n=                                                                    =");
  63.         SerialPutString("\r\n=     In-Application Programming Application  (Version 1.0.0)        =");
  64.         SerialPutString("\r\n=                                                                    =");
  65.         SerialPutString("\r\n======================================================================");
  66.         SerialPutString("\r\n\r\n");
  67.         Main_Menu ();
  68.     }
  69.     //否则执行用户程序
  70.     else
  71.     {
  72.         //判断用户是否已经下载程序,因为正常情况下此地址是栈地址。
  73.         //若没有这一句的话,即使没有下载程序也会进入而导致跑飞。
  74.         if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
  75.         {
  76.             SerialPutString("Execute user Program\r\n\n");
  77.             //跳转至用户代码
  78.             JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
  79.             Jump_To_Application = (pFunction) JumpAddress;

  80.             //初始化用户程序的堆栈指针
  81.             __set_MSP(*(__IO uint32_t*) ApplicationAddress);
  82.             Jump_To_Application();
  83.         }
  84.         else
  85.         {
  86.             SerialPutString("no user Program\r\n\n");
  87.         }
  88.     }

  89.     while (1)
  90.     {
  91.     }
  92. }


  93. /*******************************************************************************
  94.   * @函数名称        LED_Configuration
  95.   * @函数说明   配置使用LED
  96.   * @输入参数   无
  97.   * @输出参数   无
  98.   * @返回参数   无
  99. *******************************************************************************/
  100. void LED_Configuration(void)
  101. {
  102.     GPIO_InitTypeDef GPIO_InitStructure;
  103.     //使能LED所在GPIO的时钟
  104.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE , ENABLE);
  105.     //初始化LED的GPIO
  106.     GPIO_InitStructure.GPIO_Pin = LED0 | LED1 | LED2 | LED3;
  107.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  108.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  109.     GPIO_Init(GPIOE, &GPIO_InitStructure);
  110.     GPIO_SetBits(GPIOE,  LED2 | LED3);  //熄灭LED0-3
  111.        
  112. }

  113. /*******************************************************************************
  114.   * @函数名称        KEY_Configuration
  115.   * @函数说明   按键初始化
  116.   * @输入参数   无
  117.   * @输出参数   无
  118.   * @返回参数   无
  119. *******************************************************************************/
  120. void KEY_Configuration(void)
  121. {
  122.     GPIO_InitTypeDef GPIO_InitStructure;
  123.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  124.     //配置按键
  125.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  126.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  127.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  128. }

  129. /*******************************************************************************
  130.   * @函数名称        GPIO_Configuration
  131.   * @函数说明   配置使用USART1的相关IO管脚
  132.   * @输入参数   无
  133.   * @输出参数   无
  134.   * @返回参数   无
  135. *******************************************************************************/
  136. void GPIO_Configuration(void)
  137. {
  138.     GPIO_InitTypeDef GPIO_InitStructure;

  139.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
  140.     // 配置 USART1 Tx (PA.09) 作为功能引脚并上拉输出模式
  141.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  142.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  143.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  144.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  145.     //配置 USART1 Tx (PA.10) 作为功能引脚并是浮空输入模式
  146.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  147.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  148.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  149. }

  150. /*******************************************************************************
  151.   * @函数名称        IAP_Init
  152.   * @函数说明   配置使用IAP
  153.   * @输入参数   无
  154.   * @输出参数   无
  155.   * @返回参数   无
  156. *******************************************************************************/
  157. void IAP_Init(void)
  158. {
  159.     USART_InitTypeDef USART_InitStructure;

  160.     /* USART1 配置 ------------------------------------------------------------
  161.          USART1 配置如下:
  162.           - 波特率      = 115200 baud
  163.           - 字长        = 8 Bits
  164.           - 一个停止位
  165.           - 无校验
  166.           - 无硬件流控制
  167.           - 接受和发送使能
  168.     --------------------------------------------------------------------------*/
  169.     USART_InitStructure.USART_BaudRate = 9600;
  170.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  171.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  172.     USART_InitStructure.USART_Parity = USART_Parity_No;
  173.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  174.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  175.     GPIO_Configuration();
  176.     USART_Init(USART1, &USART_InitStructure);
  177.     // 使能 USART1
  178.     USART_Cmd(USART1, ENABLE);
  179. }

  180. /*******************************************************************************
  181.   * @函数名称        Delay
  182.   * @函数说明   插入一段延时时间
  183.   * @输入参数   nCount: 指定延时时间长度
  184.   * @输出参数   无
  185.   * @返回参数   无
  186. *******************************************************************************/
  187. void Delay(__IO uint32_t nCount)
  188. {
  189.     for (; nCount != 0; nCount--);
  190. }

  191. #ifdef  USE_FULL_ASSERT

  192. /*******************************************************************************
  193.   * @函数名称        assert_failed
  194.   * @函数说明   报告在检查参数发生错误时的源文件名和错误行数
  195.   * @输入参数   file: 源文件名
  196.                                   line: 错误所在行数
  197.   * @输出参数   无
  198.   * @返回参数   无
  199. *******************************************************************************/
  200. void assert_failed(uint8_t* file, uint32_t line)
  201. {
  202.     /* 用户可以增加自己的代码用于报告错误的文件名和所在行数,
  203.        例如:printf("错误参数值: 文件名 %s 在 %d行\r\n", file, line) */

  204.     //死循环
  205.     while (1)
  206.     {
  207.     }
  208. }
  209. #endif

  210. /*******************************文件结束***************************************/
复制代码

全部资料51hei下载地址:
STM32 IAP之bootloader 协议采用YMODEM.rar (3.78 MB, 下载次数: 147)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:490150 发表于 2019-3-15 16:56 | 只看该作者
下载看看,看着不错
回复

使用道具 举报

板凳
ID:447445 发表于 2019-8-27 09:19 | 只看该作者
参考一下。
回复

使用道具 举报

地板
ID:20672 发表于 2019-11-5 15:10 | 只看该作者
x谢谢分享~~
回复

使用道具 举报

5#
ID:439102 发表于 2020-2-26 13:55 | 只看该作者
谢谢分享,参考一下
回复

使用道具 举报

6#
ID:248019 发表于 2020-3-10 13:59 | 只看该作者
正在学习,感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表