单片机STM32F103C8T6TR中的TR什么意思?

前言 因为现在网上资料很多,但是很多博主水平不一样,有很多时候,自己在网上找了很多资料,因为自己智商不够,有时候感觉很多关键性的东西没说清楚,导致解决不了问题.那现在就从一个小白的角度来记录自己做过的东西,希望能帮助到以后会涉及到相关东西的小伙伴,也给以后自己留一些参考的资料. 这个是在我自己焊接好,并且通过烧写代码和连接传感器测试成功后才写的这个,所以只要不出错,按照这个方案是完全可以成功的.话不多说,开始搞事. 第一步:找到单片机芯片原理图,这个网上一搜一堆的,不过建议还是去搜芯片的data

}


1.1 STM32出现硬件错误可能有以下原因:

  • 内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。
  • 堆栈溢出。增加堆栈的大小。

1.2 出现问题时排查的方法:

1、发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12、Return address、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址,因此在堆栈中反数第三个字即为出错位置。

2、默认的HardFault_Handler处理方法是B .将它改成BX LR直接返回的形式。然后在这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句那儿。
这个有时候可能需要在反汇编模式下调试,因为可以是程序跑飞一会儿才出现HardFault_Handler。

3、还是将中断函数修改,打印中断时的一些信息:

每一种处理器模式下都有一个专用的物理寄存器作为备份的程序状态寄存器SPSR , 当特定的异常发生时,这个物理寄存器负责保存CPSR当前程序状态寄存器的内容, 当异常处理程序返回时,再将内容恢复到当前程序状态器中,继续向下执行原来程序.

PC    程序计数器,是用来计数的,指示指令在存储器的存放位置,也就是个地址信息.

出现问题时排查的方法:

      发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12、LR、PC、XPRS 寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。

注意:寄存器均是32位,且STM32是小端模式。(参考Cortex-M3权威)

发生异常后我们可以首先查看LR寄存器的值,确认当前使用的堆栈是MSP还是PSP,然后找到相对应的堆栈指针,并在内存中查看相对应堆栈的内容,内核将R0~R3,R12,LR,PC,XPRS寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。

 FLASH_SAVE_ADDR是开始存储的基地址,STM32F103C8T6内部flash大小是64K,在STM32的内部闪存(FLASH)地址起始于0x,一般情况下,程序就从此地址开始写入。因此STM32F103C8T6的结束地址应该是64*1024转换成16进制后加上单片机flash的基地址得到的结果就是0x,那么以上代码设置了FLASH_SAVE_ADDR为0X已经超出了该单片机的范围,因此如果在用此单片机操作flash是如果对这个地址进行写和读的会发生错误。现在假设你在不知情的状况下对这个地址进行了操作,然后程序运行时进入

HardFault_Handler中断中。那么要找出错误代码在哪个地方,可以使用以下方法(调试软件MDK):

3:等待代码运行到此,这时查看LR寄存器的

如果是正常运行那么显示的寄存器类似下图所示:

     发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。在Cortex_M3权威指南中可以看到如下图所示:

     由这张图可见,这个按位或的作用是把R14寄存器的低4位设为D,在这个异常返回后进入线程模式,使用线程堆栈PSP,因为任务运行时要确保使用的是线程模式,只有发生中断或异常时,才让系统进入Handle模式并使用MSP。

     在xPortPendSVHandler里之所以没有这一行,是因为在进入这个异常前,系统正在跑任务,使用的就是线程模式和PSP,进入异常后变成Handle模式和MSP,但在异常返回时会自动回到这个异常发生前的模式也就是线程模式与PSP。

在vPortSVCHandler这个函数被调用之前,系统一直是处于Handle模式并使用MSP的。(因为复位后就是Handle模式,因此大部分没用上系统的STM32的工程,都是让STM32处于Handle这个最高模式下运行的。)

      看到LR寄存器中的值是0xFFFFFFFD,因此我应该去看PSP的地址,找到该地址的地址然后如下图所示打开内存,输入上面找到的寄存器地址,右键选择以long型查看地址如下所示:

然后查看这个地址向下数六个long地址,为什么是6个long地址呢,因为由于异常发生时,内核将R0~R3、R12、Returnaddress、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址;

大概是0x08xxxxxx这样开始的即为出错的代码位置,然后可以反汇编查看,如下图所示:

可以看到是对应的C语言程序是在读FLASH函数中发生了错误,因此可以判断为访问越界的问题。

2.2 方法2:最简单,最明显

相对于检测发生了什么异常,定位异常发生位置显得更重要。

2.3 方法3:此方法和方法一大致相同

下面介绍怎么找出程序中的异常。

接下来在keil_MDK工程中,编译代码,并debug,之后全速运行,可以看到如下图所示程序进入HardFault异常。

可以发现异常代码就在uart_send_noackdata这个函数里,这个函数里我们定义了一个指针,没有给他分配空间便开始使用了。由此我们掌握了第一种查找异常的方法。只要记录栈里面第21~24以及25到28字节的内容即可方便的找到异常代码。下面介绍使用.map文件查找异常。.map文件在keil工程里面随着程序的编译会自动生成。

每一种处理器模式下都有一个专用的物理寄存器作为备份的程序状态寄存器SPSR , 当特定的异常发生时,这个物理寄存器负责保存CPSR当前程序状态寄存器的内容, 当异常处理程序返回时,再将内容恢复到当前程序状态器中,继续向下执行原来程序.

程序计数器,是用来计数的,指示指令在存储器的存放位置,也就是个地址信息.

}

我要回帖

更多关于 STM32F030RCT6 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信