因为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区。这样的话就所有的中断响应都没问题了。
原因很简单,代码在哪个区,你的中断向量表就映射到哪个区去。
|