stm32通过485接串口做IAP

在做一个工程测量的项目,由于探头要下放到100米深,因此采用了走485差分信号的方式来提高传输距离和增强抗干扰能力,为了防止出问题时一遍一遍的拆开设备,所以决定通过预留出来的485的A,B线来进行固件的在线升级。

首先简要介绍一下IAP,IAP即In Application Programming(在应用中编程),一般stm32的程序下载的时候都是下载到flash中地址0x800 0000的地方,而IAP就是在0x8000000处放入IAP程序,将主程序放在后面的地方,当需要在线更新固件的时候,跳转到IAP程序中,调用flash函数重写擦写主程序所在flash地址处的内容,擦写成功后即重新跳转到主程序去运行。(更详细的介绍可以点击这个链接 http://www.51hei.com/stm32/4315.html )

stm32官方给了一个通过串口进行IAP的例程,其原理是按照ymodem协议(可自行谷歌,在此不做详细介绍),一个包一个包的发送,接收完一个包之后发送ACK,配合超级终端使用,超级终端可以按照ymodem协议来传送文件,省去了人为去编写PC端程序的工作。这个例程中提供了keil,IAR等集成开发环境的工程,在此基础上稍作修改即可完成我们的程序。首先要做的便是加上485的控制端,由于485是半双工的,接收数据的同时不能发送,发送时不能接收,所以需要加上485的收发控制,即在每次发送数据前使能485发送,发送完成之后使能485接收。例如下面代码中的RS485_TX_Enable()。

void Serial_PutString(uint8_t *s)
{
  RS485_TX_Enable();
  delay_ms(1);
  while (*s != '\0')
  {
    SerialPutChar(*s);
    s++;
  }
  RS485_TX_Disable();
  delay_ms(1);
}
第二个要修改的就是触发IAP的条件,官方例程中是检测一个按键是否按下,这个可以根据自己的用途做适当的修改。我们做的修改在一个固定的flash地址中写入一个标志,每次单片机复位时,如果检测到这个标志被写入flash就执行IAP程序,否则跳转到主函数正常执行。IAP的程序修改基本就结束了,然后就是用户程序中的配置。

用户程序中,大部分情况下程序是正常运行的,由于中断向量偏移表在0x8000004的位置,那个地方现在存放的是IAP程序的中断向量,因此要保证主程序能正常运行需要再main函数的最前面加上中断向量偏移的设置。NVIC_SetVectorTable(0x08000000,0x3000);(由于我的主程序放在0x8003000的地方,所有后面的偏移量是0x3000,),然后就是擦除更新标志,防止IAP程序中未擦除成功过导致又跳转到了IAP程序。最后就是如果收到上位机发来的更新固件命令,就在flash中写入更新标志,然后跳转到IAP程序的入口。跳转函数如下:

static void ProcUpdateFirmware(void)
{
	IWDG_ReloadCounter();
	do
	{
		FLASHStatus = FLASH_ErasePage(UpdataFirmwareFlagAddress);
		IWDG_ReloadCounter();
	}while(FLASHStatus != FLASH_COMPLETE );
	do
	{
		FLASHStatus = FLASH_ProgramWord(UpdataFirmwareFlagAddress, UpdataFlag);
		IWDG_ReloadCounter();
	}while(FLASHStatus != FLASH_COMPLETE );
	
	IWDG_ReloadCounter();
	JumpAddress = *(__IO uint32_t*) (IAPAddress+ 4);
	Jump_To_Application = (pFunction) JumpAddress;
	/* Initialize user application's Stack Pointer */
	__set_MSP(*(__IO uint32_t*) IAPAddress); 
	
	Jump_To_Application();
}

至此,程序编写就差不多完成了,keil下载时设置将主程序下载到0x8003000的位置,将IAP程序下载到0x8000000的位置。


测试结果如下:(电脑接一个usb转RS232,再接一个RS232转RS485的转接头,485的A,B线与探头留出来的A,B线相连)

1.先发送7E 00 0E 3E 00(自己定的通信协议,0e为命令字,代表更新固件)


2.断电,打开超级终端


 

配置如下


3.重新上电,出现菜单界面,按1进入下载状态


4.选择菜单栏“传送”,选择“发送文件”,按照Ymodem协议发送bin文件


5.下载成功后出现如下界面,按3,然后重启即可。


中途遇到的问题:在用超级终端开始传输文件时没有任何反应,用示波器测量发现485接收发送都有数据,控制引脚也有高有低,猜测是控制引脚的电平转换后延时不够,在每条控制485收发转换的地方加上延时函数,试了一下出现了超级终端的发送的界面,有总大小和进度等等,但最终显示“发送已经被远程终端取消”,每次都无法发送成功。网上搜了一下,没有什么有用的办法。然后去研究了ymodem协议,发现IAP程序在收到上位机命令后会一直向上位机发送一个字符C,直到上位机开始传送文件,而发送字符C的地方没有加入485控制语句,没有发送成功,加入后传输成功。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章