当前位置:首页 > 单片机 > 单片机
[导读]IAP的源码等资料我上传了,压缩包内有12个文件,,http://download.csdn.net/detail/f907279313/7524849(要积分的辛苦收集的你们就给点积分吧)还有另一篇博客总结的IAP:http://blog.csdn.net/super_demo/article/

IAP的源码等资料我上传了,压缩包内有12个文件,,http://download.csdn.net/detail/f907279313/7524849(要积分的辛苦收集的你们就给点积分吧)

还有另一篇博客总结的IAP:http://blog.csdn.net/super_demo/article/details/32133257

一,串口通信问题

1,串口通信两端的TTL电平要一致,看选用的芯片,要么都是3.3V要么都是5V。。当两端电平不一致时通常是收不到数据的。。当检测程序等都没有问题但是依然收不到数据时,考虑检测一下两端的电平是否一致。。可用示波器查看收发数据时的电平


2,在写IAP是使用的官方的库函数,结果串口一直收不到正确的数据。不管我发什么,收到的都是0x58或者0xF6,而且我发5个字节只能收到2个。。确定自己的程序逻辑没问题,然后怀疑是使用的库函数有问题。使用beyond compare挨着对照了一下以前写过的正确的程序。。发现系统初始化时外部晶振没有改。。在SystemInit();时就是为了/* 配置系统时钟为168M 使用外部8M晶体+PLL*/ 在函数内有一个宏定义#define PLL_M 25.。。。库函数默认的是25但是我们必须要使用8M的晶振。。所以要把25改成8.。。。。。。改完测试通过。。。。。


3,在问题2的时候自己犯了个错误。当时我把另一个程序的库文件都拷过来了替换了原来的库文件,结果直接进不了中断了。有中断程序就死了。。。如图所示

有中断时汇编显示就跳到了黄色的那句话。然后程序就死了。。其实进不了中断首先想到的是中断向量表的问题。当时一着急没想到这个问题。。复制过来的库文件是我写的IAP的APP程序,我把其中的中断向量表改了,我不是在main函数中改的,我是直接改的库函数中的偏移量,然后就把这个问题给忘了,导致找了半天终于意识到是中断向量表出了问题。。。


4,串口一上电未初始化时就开始疯狂的发乱码,等初始化完成之后就不发了。如图


解决方法:我是看的官方的例程,如果需要更新再初始化串口,如果不需要更新的话就不初始化串口。所以把串口初始化部分写在了后面的判断中。。。这样操作会出现上述问题。把串口的初始化部分写到main函数的前端就不会出现这个问题了。。至于具体为什么会这样的原因还没搞明白。。。

经过询问大神们说不初始化的时候会有浮空电平,有时出现乱发一些数据也正常。。。。


5,我在写iap升级的时候,使用的是一次性全部接收完70K的bin文件,再去升级。。后期程序越写越多,最后编译完的bin文件大于了70K导致升级不能成功。前面的$HEAD命令能接收,发完bin文件后$TAIL命令接收不到。。。。。这是由于bin文件的大小超过了70k大小的buff后面的内容无法接收了。。。。。。。。。。。。。正规的升级应该接收10k或者多少就编程一次。。。。。。。。



二,FLASH问题

1,flash的擦除

实际上是把flash的内容全部写1(擦除完再读的话读出来的全是0XFF),flash的编程要按字(32位)或半字(16位)编程,当接收的数据是奇数位是要补上0,凑够半字来编程。

2,写进flash跟读出来的不一样

注意编程flash时变量的存储接收等要用unsigned类型的。存储接收的变量类型要一致。以免造成越界问题,导致看到的数不一致


3,flash做存储用时

当时写了个程序,用flash来存数据,然后再读出来,遇到的问题是设备不断电时可以完整的读出来,设备断电后读不出了。要读多少个数我是把个数也存储在flash中的。最终发现问题是程序中一个标志位的操作有问题,每次断电后再上电会自动把这个个数写为0,导致每次都读不出来数



三,数组越界问题

1,嵌入式程序通常要求少占内存,通常变量能定义8位不定义16位。。一定要注意变量的最大值。(细心一点)。。在越界问题上,吃亏了好几次了。。。。

eg:①,我定义了一个int16_t的变量来接收flash中的一个变量值0xABCD。。结果很显然越界了。。换成uint16_t即可

②,定义了一个串口接收数据计数器uint16_t 的变量,要接收60k的APP程序,自认为足够用了,但是串口发送60K大小的文件发送的字节数大于了65535,,,又耽误了好久时间。。。

谨记:要细心



四,关于APP与IAP互跳之间的中断处理问题

跳转时中断问题还是一个比较棘手的问题。。经常跳转之后无法进入中断,然后百度了一下,自己理解大概是,跳转时只是强制改变了PC指正的位置,但是里面的中断寄存器什么的都没有变,这样中断存在,但是中断函数什么的都没有了,造成程序死掉。。我在写的过程中也遇到了问题,第一次从iap跳到app正常,但是从app跳回iap的时候由于残留的中断太多,在iap中程序死了。我的处理方式是把app中的跳转命令换成了系统复位NVIC_SystemReset();(不同的固件库可能函数名不同)其他的处理理的方式据我所知还有有①跳转之前复位或者关闭所有打开的中断②跳转后在初始化时加入RCC_DeInit();,,NVIC_DeInit();等让中断恢复默认值。。具体可参考下面这篇文章http://dzdesigned80.blog.163.com/blog/static/203259238201272425313152/总之要注意中断寄存器的复位。也可以直接软件复位管他什么中断寄存器残留的.从iap跳到app前可以用USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);来关闭串口接收中断。从app跳转回iap可以用软件复位。



五,总结一下在IAP升级中APP程序的中断向量表的偏移


1.关于APP程序的中断向量表地址偏移(三种方法,stm32F2与F4系列通用。三种方法本质一样只是看到网上的各种例程的表现形式不一样)

①直接操作寄存器

在APP程序的main函数的开头设置中断向量表偏移

SCB->VTOR = FLASH_BASE | 0x10000;

其中0x10000是偏移量。。也就是前面的IAP程序所占用的空间大小,要是你的main函数中有SystemInit();的话要在SystemInit();之后添加。

因为SystemInit();中有中断向量表的偏移操作

在void SystemInit (void)系统初始化函数中有初始化中断向量表的语句

#ifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* 使用内部SRAM启动设置这一句. */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* 使用内部FLASH启动设置这句*/

#endif

可以直接修改VECT_TAB_OFFSE的值,这个值代表偏移量。不建议这么改,不建议修改库文件,应为后面其他程序用的话经常忘了这里动过中断向量表,导致中断不能正常运行(我就因为这个浪费了快一天时间,串口就是进不了中断)

其中

#define FLASH_BASE ((uint32_t)0x08000000) /*!

#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM baseaddress in the alias region */

对应keil设置中的(这是一般程序默认的,IAP升级中APP程序的这个地方还得根据中断偏移量改)




② 使用库函数设置偏移量

在库文件中有专门的一个函数

在APP程序初始化时调用函数NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000);

其中/* Vector Table Base----------------------------------*/

#define NVIC_VectTab_RAM ((u32)0x20000000)

#define NVIC_VectTab_FLASH ((u32)0x08000000)

/***********************************************************************

Function Name : NVIC_SetVectorTable

* Description : Sets the vector table location andOffset.

* Input : - NVIC_VectTab: specifies if thevector table is in RAM or

* FLASH memory.

**********************************************************************/

void NVIC_SetVectorTable(u32NVIC_VectTab, u32 Offset)

{

/* Check the parameters */

assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));

assert_param(IS_NVIC_OFFSET(Offset));

SCB->VTOR = NVIC_VectTab " (Offset & (u32)0x1FFFFF80);

}


③修改库文件(不建议使用)

直接修改固件库里面的数值。在void SystemInit(void)下的

/* Configure the Vector Table location add offsetaddress ------------------*/

#ifdefVECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;/* Internal SRAM */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;/* Internal FLASH */

#endif

直接修改

#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.

This valuemust be a multiple of 0x200. */

#define VECT_TAB_OFFSET 0x10000 /*!< Vector Table base offsetfield.

This valuemust be a multiple of 0x200. */


2.关于IAP程序与APP程序keil中的设置

Stm32的flash都是从0x8000000开始的,结束地址看片子的flash大小

Stm32的sram都是从0x2000000开始的,结束地址看片子的sram大小

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

电磁铁是一种利用电流产生磁场的装置,具有快速响应、易于控制等特点,在工业自动化、电子设备、科学实验等领域有着广泛的应用。STM32是一款功能强大的微控制器,具有高性能、低功耗、易于编程等优点,是控制电磁铁的理想选择。本文...

关键字: 电磁铁 微控制器 STM32

边缘人工智能的实现涉及到三个基本 要素:安全性,连接性、自主性,而其中自主性是AI能力的体现,也是边缘AI有别于其他传统的物联网的关键。而通过ST Edge AI套件,就可以帮助各种不同类型的开发者实现覆盖全硬件平台的全...

关键字: 边缘人工智能 AI STM32

今天,小编将在这篇文章中为大家带来STM32单片机最小系统的有关报道,通过阅读这篇文章,大家可以对它具备清晰的认识,主要内容如下。

关键字: 单片机 单片机最小系统 STM32

STM32是一款由STMicroelectronics生产的微控制器系列,具有高性能、低功耗和丰富的外设资源。其中,串口通信是一种常用的通信方式,可以实现与其他设备之间的数据传输。

关键字: STM32 串口通信 微控制器

STM32是一种广泛使用的微控制器,具有丰富的通信接口。其中,串口通信是STM32与其他设备或系统进行数据交换的重要方式之一。本文将详细介绍STM32串口通信的原理、应用及常见故障。

关键字: STM32 串口通信

由于目前缺乏相应的监测技术,地下电缆线路出现异常运行状态无法被及时发现,久而久之易演变成大故障,最终只能通过更换地下电缆进行修复,耗费大量的人力、物力。鉴于此,开发了一种基于STM32的地下电缆异常状态检测系统,利用热传...

关键字: STM32 地下电缆

交通灯控制器是用于控制交通信号灯运行的设备,它可以根据交通流量、行人需求以及其他因素,动态地调整信号灯的变化时间和绿灯时长,以保证交通的流畅和安全。

关键字: 交通信号灯 STM32

通用MCU的成功与否,产品本身PPA固然重要,但除此外很大程度上取决于开发生态。生态的繁荣可以让其中的每一位参与者受益,当然也会反哺到MCU产品本身,影响到新的产品定义和走向。

关键字: ST STM32 MCU

摘要:在水位传感器的出厂检测过程中需要进行气密性检测,为此,设计了一个基于STM32的水位传感器气密性检测仪。该检测仪采用直压式气体检漏的方法,以STM32F030R8为控制核心,控制气泵进行充气,压力传感器检测气压并通...

关键字: 气密性 水位传感器 STM32

在2023年STM32峰会上,看通用MCU的未来发展方向。

关键字: STM32 ST AI 无线
关闭
关闭