OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4206|回复: 1

关于rtc时钟不能在SRAM区调试的疑问

[复制链接]

4

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2014-7-8
在线时间
0 小时
发表于 2014-11-4 09:25:14 | 显示全部楼层 |阅读模式
5金钱
原子哥,请问一下为什么把代码放在sram当中,rtc时钟实验的时候,就始终没有中断产生,在flash中调试就行了。代码一样,就是选择的调试区域不一样。请各位大虾指点。

最佳答案

查看完整内容[请看2#楼]

   因为stm32在flash区擦写的次数有限,所以我选择在sram中调试,SRAM擦除次数无限次,不过掉电代码就消失。代码放在SRAM中,对于我们调试是非常有帮助的。(我用的是原子的开发板)     最近这几天发现,在SRAM中调试,部分中断不响应的问题,比如RTC秒中断,明明使能了秒中断,可是总是卡在某个地方不动,然后怎么也进入不了中断。下面是我的代码。结合代码说明问题吧。   ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2014-7-8
在线时间
0 小时
 楼主| 发表于 2014-11-4 09:25:15 | 显示全部楼层

   因为stm32在flash区擦写的次数有限,所以我选择在sram中调试,SRAM擦除次数无限次,不过掉电代码就消失。代码放在SRAM中,对于我们调试是非常有帮助的。(我用的是原子的开发板)

    最近这几天发现,在SRAM中调试,部分中断不响应的问题,比如RTC秒中断,明明使能了秒中断,可是总是卡在某个地方不动,然后怎么也进入不了中断。下面是我的代码。结合代码说明问题吧。

 

rtc.h文件中代码

 

#ifndef __RTC_H
#define __RTC_H


typedef struct
{
 u8 m;
 u8 h;
 u8 s;
}calendar;
extern calendar rl;
extern u8 tim_bz;
u8 RTC_Init(void);

#endif


rtc.c文件中代码

#include "sys.h"
#include "delay.h"
#include "rtc.h"
u8 tim_bz=0;
calendar rl;
u8 RTC_Init(void)
{
 u8 temp = 0;
 if(BKP->DR1 != 0X5050)//检测是不是第一次配置,后面会有向BKP->DR1写数据的语句
 {
  //1,使能电源时钟和备份区域时钟
  RCC->APB1ENR |= 1<<28;//电源接口时钟使能
  RCC->APB1ENR |= 1<<27;//备份接口时钟使能

  //2,取消备份区域写保护,需要向备份区域写
  //一个字节来标记时钟已经配置过了,避免每次复位启动
  WR->CR |= 1<<8;//取消后备区域的写保护
  
  //3,复位备份区域,开启外部低速振荡器
  RCC->BDCR |= 1<<16;//备份域软件复位
  RCC->BDCR &= ~(1<<16);//备份域软件复位清,因为备份域软件复位要由软件清除,且不能一直复位。 
  RCC->BDCR |= 1<<0;//外部低速时钟使能
  while((!(RCC->BDCR&0X02))&&temp<250)//判断rtc外部低速振荡器是否就绪
  {
   temp++;
   delay_ms(10);
  }

  if(temp>=250)return 1;//初始化失败,外部晶振有问题

  //4,选择RTC时钟源并使能
  RCC->BDCR |= 1<<8;//LSE振荡器作为rtc时钟
  RCC->BDCR |= 1<<15;//RTC时钟使能
  while(!(RTC->CRL&(1<<5)));//等待rtc写操作完成
  while(!(RTC->CRL&(1<<3)));//等待RTC寄存器和APB1接口同步
  RTC->CRH |= 0x01;//允许秒中断
  while(!(RTC->CRL&(1<<5)));//等待rtc写操作完成
  RTC->CRL |= 1<<4;//允许配置RTC寄存器

  RTC->RLH = 0x0000;
  RTC->RLL |=32767;//设置RTC时钟频率为1hz
  RTC->CNTL = 0x0005;
  RTC->CNTH = 0X0000;
  RTC->CRL &= ~(1<<4);//配置更新
  while(!(RTC->CRL&(1<<5)));//等待rtc写操作完成
  RTC->CRL &= ~(1<<5);//rtc操作关闭
  BKP->DR1 = 0X5050;
 }
 else
 {
  while(!(RTC->CRL&(1<<3)));//等待RTC寄存器和APB1接口同步
  RTC->CRH |= 0x01;//允许秒中断
  while(!(RTC->CRL&(1<<5)));//等待rtc写操作完成  
 }
 MY_NVIC_Init(0,0,RTC_IRQn,2);//设置中断
 return 0;
}

void RTC_IRQHandler(void)
{
 if(RTC->CRL&0X01)
 {
  tim_bz = 1;//进入中断标志,等下判断是否发生中断
  RTC->CRL &= ~(1<<0);//清除秒标志
  while(!(RTC->CRL&(1<<5)));//等待rtc写操作完成   
 }
}

 

 

主函数代码

#include "sys.h"
#include "usart.h"  
#include "delay.h" 
#include "led.h"
#include "beep.h"   
#include "key.h"   
#include "exti.h"   
#include "wdg.h"  
#include "timer.h"    
#include "tpad.h"    
#include "lcd.h"
#include "rtc.h"    

int main(void)

 u32 TimeData=0;           
   Stm32_Clock_Init(9); //系统时钟设置
 uart_init(72,9600);   //串口初始化为9600
 delay_init(72);       //延时初始化
 LED_Init();      //初始化与LED连接的硬件接口
  LCD_Init();
 RTC_Init();
 LCD_ShowString(60,162,200,16,16,"  :  :  ");    
    while(1)
 {
  if(tim_bz==1)
  {
   tim_bz=0;/./进入中断后,清除中断标志
   TimeData = RTC->CNTH;
   TimeData <<=16;
   TimeData += RTC->CNTL;
   rl.h =TimeData/3600;
   rl.m =(TimeData600)/60;
   rl.s =TimeData`;
   LCD_ShowNum(60,162,rl.h,2,16);
   LCD_ShowNum(84,162,rl.m,2,16);
   LCD_ShowNum(108,162,rl.s,2,16);
   LED0 = ~LED0;
  }
 } 
}

 

在SRAM当中调试代码,标志位始终没有为1,这就说明没有进入中断函数。

 

问题在哪???

嘿嘿,查阅资料发现,原子哥的中断向量配置需要修改一下。

在sys.h文件中有个MYRCC_DeInit()函数,


修成这样,


也就是把中断向量表映射到SRAM区。这样的话就所有的中断响应都没问题了。

原因很简单,代码在哪个区,你的中断向量表就映射到哪个区去。

 

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 19:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表