一,串口通信问题 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 ();等让中断恢复默认值。。详细可參考以下这篇文章也能够直接软件复位管他什么中断寄存器残留的.从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) /*!<FLASH base address in the alias region */ #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大小
IAP程序基本默认就可以,跟普通程序一样 在APP程序中须要设置一下偏移量 默认的条件下,图中IROM1的起始地址(Start)一般为0X08000000,大小(Size)为0X100000。即从0X08000000開始的1M空间为我们的程序存储(由于我们的STM32F4的FLASH大小是1M)。而图中,我们设置起始地址(Start)为0X08010000,即偏移量为0X10000(64K字节)。因而。留给APP用的FLASH空间(Size)仅仅有0X100000-0X10000=0XF0000(960K字节)大小了。设置好Start和Szie,就完毕APP程序的起始地址设置。
|