stm8L152C6开发板两个诡异问题:1,RTC时钟,秒针走,分针不走;2,按键中断就死机。

weixin_44853268 2021-07-20 16:44:18

stm8L152C6开发板两个诡异问题:1,RTC时钟,秒针走,分针不走;2,按键中断就死机。

1、RTC时钟配置中,秒针走时正常,但是到60s,分钟不动?这是怎么回事?

2、设置了PB0作为按键中断,中断触发为下降沿和低电平触发。但是一按按键PB0,程序就不走了,也不会到main程序。在IAR程序中,一直处在__iar_unhandled_exception   008985  9D   008986     20FD  。

#include"iostm8l052c6.h"
#include"stdint.h"


#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
//typedef unsigned char  uint8_t;
//typedef unsigned short  uint16_t;
//typedef unsigned long   uint32_t;

#define KEY1  PB_IDR_IDR0

//==================定义常数=====================//
#define a 0x01
#define b 0x02
#define c 0x04
#define d 0x08
#define e 0x10
#define f 0x20
#define g 0x40
#define m 0x80

const uint16_t NumberMap[10]=
{
                a+b+c+d+e+f,        // Display "0"
                b+c,                // Display "1"
                a + b + m + g + e + d,                        // Displays "2"
                a + b + m + g + c + d,                        // Displays "3"
                f + g + m + b + c,                        // Displays "4"
                a + f + g + m + c +d,                        // Displays "5"
                a + f + e + d + c + g + m ,                // Displays "6"
                a + b + c,                                // Displays "7"
                a + b + c + d + e + f + g + m,                // Displays "8"
                a + b + c + d + f + g + m                // Displays "9"
};


 

void system_init(void);
void GPIO_Init(void);
void LCD_Config(void);
void RTC_Config(void);
void LCD_GLASS_Clear(void);
void LCD_GLASS_Confirm(void);
void LCD_DisplayNum(uint16_t Num);
void Delay(u16 Second);
 

void system_init(void)
{
  
   if(CLK_SCSR!=0x01)
  {
  
    CLK_SWCR |= 0x02;//使能自动时钟切换
    CLK_SWR = 0x01; //HSI为主时钟源
    while(!CLK_SWCR_SWIF);
    //CLK_CKDIVR = 0x00;//CPU时钟0分频,系统时钟0分频
    CLK_SWCR = 0;
    
  }
  CLK_CSSR = 0x01;//时钟安全监测使能
  
  CLK_PCKENR2_PCKEN20 = 1;     //打开ADC1时钟
  CLK_PCKENR2_PCKEN22 = 1;     //打开RTC时钟,LCD刷新频率与此有关
  CLK_PCKENR2_PCKEN23 = 1;     //打开LCD时钟,读写LCD寄存器用到此时钟
  
  CLK_CRTCR = 0x10;   //set RTC division favter[7:5] and clock source [4:1]
                           //CLK_CRTCR: Clock RTC register; 前3位为时钟分频值,后4位为时钟选择位,
                           //最后一位为系统忙标志位

}

void RTC_Config(void)
{
  
  RTC_WPR = 0xCA;      //disable write protection
  RTC_WPR = 0x53;
  
  RTC_ISR1_INIT = 1;   //initialize
  while(!RTC_ISR1_INITF);
  
  //初始化时间与日期
  RTC_TR1_ST=5;   //  second tens      RTC_TR1 (second)
  RTC_TR1_SU=5;   //  second units
  
  RTC_TR2_MNT=4;  //  minute tens      RTC_TR2  (minute)
  RTC_TR2_MNU=2;  //  minute units
  
  RTC_TR3_PM=0;   //  AM/PM
  RTC_TR3_HT=1;   //  Hour tens
  RTC_TR3_HU=1;   //  hour units
  
  RTC_DR1_DT=2;   //  date tens
  RTC_DR1_DU=6;   //  date units
  
  RTC_DR2_WDU=1;  //  week day units
  RTC_DR2_MT=0;   //  month tens
  RTC_DR2_MU=9;   //  month units
  
  RTC_DR3_YT=1;   //  year tens
  RTC_DR3_YU=6;   //  year units
  
  RTC_CR1 |=0x40;   //  24 hour
  //RTC_CR1_BYPSHAD=1;
  
 
  
  RTC_APRER=0x7F;     //保持默认值0x7F,异步RTC寄存器
  RTC_SPRERH=0x00;
  RTC_SPRERL=0xFF;    //保持默认值0xFF,同步RTC寄存器
  
  //以上两个RTC时钟分频值保持默认
  //最终提供给日历模块的时钟为32768Hz/((127+1)*(255+1))=1
  
  RTC_ISR1_INIT=0;   //退出初始化模式
  
  RTC_CR2_ALRAE=0;   //disable the alarm
  
  RTC_WPR=0x55;//使能写保护

  RTC_WPR=0x55;

}

void GPIO_Init(void)
{
  //**********Key 输入***************//
  EXTI_CR1=0xE4;
  ITC_SPR2=0x73;
  
  
  PB_DDR_DDR0 = 0;       //PB[0:4]端口为输入端口
  PB_CR1_C10 = 1;       //上拉输入
  PB_CR2_C20 = 1;       //使能中断:1

}

 

void LCD_Config(void)
{
  
 
  
  
  LCD_FRQ = 0x00;           //Frequency selectrion register (PS and DIV)
  
  LCD_CR1 = 0x06;          // control register 1: set blink, blink frequency, 
                           // duty ratio, bias.
  
  LCD_CR2 = 0xFE;         // control register 2: set pulse on duation, 
                          // high drive enable, contrast control
  
  
  /*-----------Mask register----------------*/
  LCD_PM0 = 0xFF;   // Seg[7:0] enable
  //LCD_PM1 = 0x00;   // Seg[8:15] enable
  LCD_PM2 = 0xFF;   // Seg[16:23]  enable
  //LCD_PM3 = 0x00;   // Seg[24:31]  enable
   
  LCD_CR3 = 0x40;         // control register 3: set LCD enable, interrupt enable, 
                          // frame flag, SOD flag, Dead time enable
  
}


//********************LCD 清零**********************************//

void LCD_GLASS_Clear(void)
{
 
  
    LCD_RAM0 = 0x00;
    LCD_RAM1 = 0x00;
    LCD_RAM2 = 0x00;
    LCD_RAM3 = 0x00;
    LCD_RAM4 = 0x00;
    LCD_RAM5 = 0x00;
    LCD_RAM6 = 0x00;
    LCD_RAM7 = 0x00;
    LCD_RAM8 = 0x00;
    LCD_RAM9 = 0x00;
    LCD_RAM10 = 0x00;
    LCD_RAM11 = 0x00;
    LCD_RAM12 = 0x00;
    LCD_RAM13 = 0x00;
 
}

void LCD_GLASS_Confirm(void)
{
 
  
    LCD_RAM0 = 0xFF;
    LCD_RAM1 = 0xFF;
    LCD_RAM2 = 0xFF;
    LCD_RAM3 = 0xFF;
    LCD_RAM4 = 0xFF;
    LCD_RAM5 = 0xFF;
    LCD_RAM6 = 0xFF;
    LCD_RAM7 = 0xFF;
    LCD_RAM8 = 0xFF;
    LCD_RAM9 = 0xFF;
    LCD_RAM10 = 0xFF;
    LCD_RAM11 = 0xFF;
    LCD_RAM12 = 0xFF;
    LCD_RAM13 = 0xFF;
   
 
}

void LCD_DisplayNum(uint16_t Num)
{
  
  uint8_t tmp=0;
  //tmp=NumberMap[Num];
  uint8_t wei=4;
   switch(wei)
  {
  
       
    case 4: 
      tmp=NumberMap[Num%10000/1000]; 
      ((tmp&a)==0)?(LCD_RAM6 &= (~0x04)):(LCD_RAM6 |= 0x04);         //1A
      ((tmp&b)==0)?(LCD_RAM2 &= (~0x40)):(LCD_RAM2 |= 0x40);         //1B
      ((tmp&c)==0)?(LCD_RAM3 &= (~0x20)):(LCD_RAM3 |= 0x20);         //1C
      ((tmp&d)==0)?(LCD_RAM3 &= (~0x10)):(LCD_RAM3 |= 0x10);         //1D
      ((tmp&e)==0)?(LCD_RAM0 &= (~0x01)):(LCD_RAM0 |= 0x01);         //1E
      ((tmp&f)==0)?(LCD_RAM6 &= (~0x08)):(LCD_RAM6 |= 0x08);         //1F
      ((tmp&g)==0)?(LCD_RAM2 &= (~0x80)):(LCD_RAM2 |= 0x80);         //1G
      ((tmp&m)==0)?(LCD_RAM0 &= (~0x02)):(LCD_RAM0 |= 0x02);         //1M
 
  
  
  
 
         
    case 3:
      tmp=NumberMap[Num%1000/100];
      ((tmp&a)==0)?(LCD_RAM6 &= (~0x01)):(LCD_RAM6 |= 0x01);         //2A
      ((tmp&b)==0)?(LCD_RAM2 &= (~0x10)):(LCD_RAM2 |= 0x10);         //2B
      ((tmp&c)==0)?(LCD_RAM3 &= (~0x80)):(LCD_RAM3 |= 0x80);         //2C
      ((tmp&d)==0)?(LCD_RAM3 &= (~0x40)):(LCD_RAM3 |= 0x40);         //2D
      ((tmp&e)==0)?(LCD_RAM0 &= (~0x04)):(LCD_RAM0 |= 0x04);         //2E
      ((tmp&f)==0)?(LCD_RAM6 &= (~0x02)):(LCD_RAM6 |= 0x02);         //2F
      ((tmp&g)==0)?(LCD_RAM2 &= (~0x20)):(LCD_RAM2 |= 0x20);         //2G
      ((tmp&m)==0)?(LCD_RAM0 &= (~0x08)):(LCD_RAM0 |= 0x08);         //2M
      LCD_RAM7 |= 0x08;              //2colon
           
  
   case 2:
      tmp=NumberMap[Num%100/10];
      ((tmp&a)==0)?(LCD_RAM5&=~0x40):(LCD_RAM5 |=0x40) ;
      ((tmp&b)==0)?(LCD_RAM2&=~0x04):(LCD_RAM2 |=0x04) ;
      ((tmp&c)==0)?(LCD_RAM4&=~0x02):(LCD_RAM4 |=0x02) ;
      ((tmp&d)==0)?(LCD_RAM4&=~0x01):(LCD_RAM4 |=0x01) ; 
      ((tmp&e)==0)?(LCD_RAM0&=~0x10):(LCD_RAM0 |=0x10) ;
      ((tmp&f)==0)?(LCD_RAM5&=~0x80):(LCD_RAM5 |=0x80) ;
      ((tmp&g)==0)?(LCD_RAM2&=~0x08):(LCD_RAM2 |=0x08) ;
      ((tmp&m)==0)?(LCD_RAM0&=~0x20):(LCD_RAM0 |=0x20) ;
       
   case 1: 
      tmp=NumberMap[Num%10/1];
      ((tmp&a)==0)?(LCD_RAM5&=~0x10):(LCD_RAM5 |=0x10) ;
      ((tmp&b)==0)?(LCD_RAM2&=~0x01):(LCD_RAM2 |=0x01) ;    
      ((tmp&c)==0)?(LCD_RAM4&=~0x08):(LCD_RAM4 |=0x08) ;  
      ((tmp&d)==0)?(LCD_RAM4&=~0x04):(LCD_RAM4 |=0x04) ;
      ((tmp&e)==0)?(LCD_RAM0&=~0x40):(LCD_RAM0 |=0x40) ;
      ((tmp&f)==0)?(LCD_RAM5&=~0x20):(LCD_RAM5 |=0x20) ;
      ((tmp&g)==0)?(LCD_RAM2&=~0x02):(LCD_RAM2 |=0x02) ;
      ((tmp&m)==0)?(LCD_RAM0&=~0x80):(LCD_RAM0 |=0x80) ;
        
    break;
    default:break;
  }
}

void Delay(u16 Second)
{
  u8 i,j;
  while(Second--)
  {
    for(i=0;i<50;i++)
      for(j=0;j<50;j++);
  }
}

void main(void)
{
  u16 H_shi=0,H_ge=0,M_shi=0,M_ge=0,S_shi=0,S_ge=0;
  u8 count=0,count_shi=0,count_bai=0,count_qian=0;
  
  asm("sim");
  system_init();
  
  GPIO_Init();
  LCD_Config();
  RTC_Config();
  
  
  LCD_GLASS_Clear();
  LCD_GLASS_Confirm();

  LCD_GLASS_Clear();

asm("rim");
/*************************************************************/
  while(1)
  {
        
         LED3 = 1;
         while(!RTC_ISR1_RSF);
    
    
         S_ge = (u16)RTC_TR1_SU;
         S_shi = (u16)RTC_TR1_ST;
         M_ge = (u16)RTC_TR2_MNU;
         M_shi = (u16)RTC_TR2_MNT;
         H_ge = (u16)RTC_TR3_HU; 
         H_shi = (u16)RTC_TR3_HT; 
    
         RTC_ISR1_RSF=0;
        LCD_DisplayNum(M_shi*1000+M_ge*100+S_shi*10+S_ge);
  }

#pragma vector=0x06
__interrupt void EXTI_PORTB_IRQHandler(void)
{
  
  LCD_DisplayNum(100); 
  LED_Discovery1=!LED_Discovery1;
  //EXTI_SR1=0xFF;
  //EXTI_SR2=0xFF;
  //return;
}

 

 

...全文
1235 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_64873809 2023-04-18
  • 打赏
  • 举报
回复

请问可以加个联系方式嘛大佬,有不懂的问题想咨询

weixin_44853268 2021-07-27
  • 打赏
  • 举报
回复

第二个问题也解决了。需要读取RTC_DR3_YT和RTC_DR3_HU的数据,然后计时就正常了。

weixin_44853268 2021-07-21
  • 打赏
  • 举报
回复

第二个问题解决了,是中断向量写错了。
出现这个问题的主要原因是参考的书本(stm8单片机入门、进阶与应用实例)和STM8L152C4TDatasheet,RM0031_stm8l050文档的中断向量定义不一致。书本中PB IO端口的外部中断#pramga vector = 0x06。但是Datasheet上的Interrupt mapping给出的Px0引脚的中断向量应为(8+2)EXTI0,其中x代表A,B,C,D端口。
RM0031没有给出中断向量图,需要到STM8L152Datasheet中找。
书本给出的是STM8S207、208系列单片机,我的开发板是8L152的单片机,两者有很大的差别。
但是时钟问题还是没有解决,为什么分钟不走呢?诡异的是,我设定分钟初始值为42,程序跑时偶尔会出现分钟变为43,但是接着就不会再改变了。

27,377

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧