打印

一执行FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2就HardFault了?

[复制链接]
7008|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ounie|  楼主 | 2010-9-1 23:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本想将程序在flash中调试,因为之前一直在内部sram运行。
跳线啊,一些ROM/RAM地址啊 其他设置都弄好后 开始调试啦。结果发现一执行到FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2就HardFault了
这句在system_stm32f10x.c文件的static void SetSysClockTo72(void)函数里面,我用的3.3的库。
后面我把这三句话FLASH->ACR |= FLASH_ACR_PRFTBE;
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
改为了FLASH->ACR= (uint32_t)(FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2);就没有任何fault了。程序完全正常了!我看了,上面写法不同,但寄存器最终结果还是一样的,但是库函数那种就fault了
MDK调试下看到,USG_FAULT那个寄存器里面UNDEFINSTR置位1了,HARD_FAULT里面FORCED置位1了
沙发
ounie|  楼主 | 2010-9-1 23:17 | 只看该作者
晕 可以上图片啊 之前不知道啊

1.jpg (55.75 KB )

1.jpg

使用特权

评论回复
板凳
lut1lut| | 2010-9-2 09:34 | 只看该作者
执行的这句话是设置flash的等待周期。
0:(0, 24MHz]
1: (24MHz, 48MHz]
2:(48Mhz, 72MHz]

如果你此时cpu本身的运算速度和设置后的不符合,就会hard fault。

使用特权

评论回复
地板
ounie|  楼主 | 2010-9-2 09:39 | 只看该作者
CPU系统时钟设置对的啊 这个时钟频率和等待周期的对应关系我知道的
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
改为了FLASH->ACR= (uint32_t)(FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2);
就好了 其实对ACR的设置值,两种方法最终是一样的,但是结果是库函数那样搞 第3句执行完就HardFault了。我自己写的就没有HardFault了

使用特权

评论回复
5
ounie|  楼主 | 2010-9-2 09:42 | 只看该作者
本帖最后由 ounie 于 2010-9-2 09:43 编辑

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
  /* Enable HSE */   
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
   


    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
   
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
.............以下函数内容省略

使用特权

评论回复
6
香水城| | 2010-9-2 09:50 | 只看该作者
请检查一下编译出来的汇编代码,是否有误。

使用特权

评论回复
7
ounie|  楼主 | 2010-9-2 13:07 | 只看该作者
按库函数的那三句话编译出来的
   904:     FLASH->ACR |= FLASH_ACR_PRFTBE;
   905:  
   906:     /* Flash 2 wait state */
0x08001370 4A4A      LDR      r2,[pc,#296]  ; @0x0800149C
0x08001372 6812      LDR      r2,[r2,#0x00]
0x08001374 F0420210  ORR      r2,r2,#0x10
0x08001378 4B48      LDR      r3,[pc,#288]  ; @0x0800149C
0x0800137A 601A      STR      r2,[r3,#0x00]
   907:     FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
0x0800137C 461A      MOV      r2,r3
0x0800137E 6812      LDR      r2,[r2,#0x00]
0x08001380 F0220203  BIC      r2,r2,#0x03
0x08001384 601A      STR      r2,[r3,#0x00]
   908:     FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
   909:  
   910:         /* HCLK = SYSCLK */
0x08001386 461A      MOV      r2,r3
0x08001388 6812      LDR      r2,[r2,#0x00]
0x0800138A F0420202  ORR      r2,r2,#0x02
0x0800138E 601A      STR      r2,[r3,#0x00]
/*------------------------------------------------------------------------------*/
我自己写的编译出来:
   903:     FLASH->ACR= (uint32_t)(FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2);
   904:  
   905:         /* HCLK = SYSCLK */
0x08001370 2212      MOVS     r2,#0x12
0x08001372 4B43      LDR      r3,[pc,#268]  ; @0x08001480
0x08001374 601A      STR      r2,[r3,#0x00]
/*----------------------------------------------------------------------------------*/
我自己写的编译出来似乎。。。。不过我自己写的就没有HardFault。库函数就HardFault了啊

使用特权

评论回复
8
香水城| | 2010-9-2 13:48 | 只看该作者
请在库函数编译出来代码的最后一行放一个断点,看看r2的内容:
    0x0800138E 601A      STR      r2,[r3,#0x00]

使用特权

评论回复
9
ounie|  楼主 | 2010-9-2 14:18 | 只看该作者
R2是0x00000012

使用特权

评论回复
10
ounie|  楼主 | 2010-9-2 14:25 | 只看该作者
R2的值此时对应ACR寄存器的值?似乎是FLASH的ACR寄存器PRFTBS置0了,就是说预取缓冲区关闭了?

使用特权

评论回复
11
ounie|  楼主 | 2010-9-2 14:26 | 只看该作者
呵呵 手头没的硬件现在 软件仿真看到的结果 不知道会不会和实际用J-LINK在板子上跑,数值由偏差

使用特权

评论回复
12
香水城| | 2010-9-2 16:42 | 只看该作者
呵呵 手头没的硬件现在 软件仿真看到的结果 不知道会不会和实际用J-LINK在板子上跑,数值由偏差
ounie 发表于 2010-9-2 14:26


软件仿真?早说呢!

使用特权

评论回复
13
ounie|  楼主 | 2010-9-2 20:08 | 只看该作者
硬件仿真 r2是0x00000032啊
执行完0x0800138E 601A      STR      r2,[r3,#0x00] 就HardFault了

使用特权

评论回复
14
ounie|  楼主 | 2010-9-2 20:12 | 只看该作者
额 我自己写的FLASH->ACR= (uint32_t)(FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2);
硬件仿真 r2是0x00000012
看来 快要知道为什么了

使用特权

评论回复
15
ounie|  楼主 | 2010-9-2 20:36 | 只看该作者
就是一个ACR寄存器里面,PRFTBS预取缓冲区状态 值不同。看文档,这是个只读寄存器啊??
参考的PM0042 即STM32F10XXX闪存编程中文版

使用特权

评论回复
16
ounie|  楼主 | 2010-9-3 10:39 | 只看该作者
:Q

使用特权

评论回复
17
香水城| | 2010-9-3 11:04 | 只看该作者
请不要用软件仿真,直接硬件上运行,我测试过,没有问题,别人也都没有发现这种问题。

使用特权

评论回复
18
ounie|  楼主 | 2010-9-3 11:38 | 只看该作者
是硬件啊 板子+JLINK
我也是很奇快怎么会有这个问题 所以发帖看其他人是不是有遇到过 共同探讨哈

使用特权

评论回复
19
panwenxiao| | 2014-4-23 16:16 | 只看该作者
FLASH->ACR= (uint32_t)(FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2)是什么个意思,没看太明白,求大神指教。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

41

帖子

1

粉丝