加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

关于STM8S的halt状态及唤醒

(2013-01-24 00:10:43)
标签:

stm8s

halt

杂谈

分类: STM8

    有个项目用了STM8S103F3,因是电池供电,需要进入halt状态并使用GPIO外部唤醒,因是初次使用STM8S,走了不少弯路,将过程记录下来,好让和我一样的初次接触STM8S的人有个启发。

 

    现象:进不了HALT状态

    硬件环境:使用PA1、PA2、PD2、PD5作为外部中断输入,来唤醒MCU。使用PD4作为输出,使用PD3作为AD转换口。

    编程思路:

            1、初始化系统(时钟、gpio)部分代码如下:

void JG_GPIO_Init(void)
{
 PA_DDR = 0xf9;  

 PA_CR1 = 0x00;  

 PA_CR2 = 0x06;  //pa1、pa2中断

 PB_DDR = 0xff;  //PB浮空输入
 PB_CR1 = 0x00;
 PB_CR2 = 0x00;

 PC_DDR = 0x00;  //
 PC_CR1 = 0x00;
 PC_CR2 = 0x00;

 PD_DDR = 0xdb;  //1101 1011
 PD_CR1 = 0xdb;  //1101 1011
 PD_CR2 = 0x24;  //0010 0100 //PD2\PD5中断

 PD_ODR_ODR4 = 0;

 
 EXTI_CR1_PDIS = 3; //PD口中断上下降沿触发
 EXTI_CR1_PAIS = 3; //PA口中断上下降沿触发
}

    2、开中断

asm("rim");

    3、进入halt

asm("halt");

 

    4、在PA口和PD口外部中断服务函数中处理问题

#pragma vector = 5
__interrupt void PA_Intrsvr(void)
{

...

}

#pragma vector = 8    
__interrupt void PD_Intrsvr(void)
{

...

}

     结果发现根本不进入halt模式,百思不得其解。

 

     问题分析过程:

     首先怀疑端口被误触发,使得进入了HALT模式的mcu被唤醒了。用示波器查看PA1、PA2、PD2、PD5波形,均为高电平,没有触发的条件。

  

     接着怀疑电源干扰,加大了电路的滤波电容,故障依旧。

    

     开始从代码入手查问题,修改代码如下:

#define led PD_ODR_ODR4

void main(void)
{
 PD_DDR_DDR4 = 1;
 PD_CR1_C14  = 1;
 PD_CR2_C24  = 0;
 led = 1;
 PA_DDR_DDR1 = 0;
 PA_CR1_C11  = 0;
 PA_CR2_C21  = 1;
 EXTI_CR1_PAIS = 3;
 asm("rim");
 
 asm("halt");
 led = 0;
  

 
 while(1);

}

    在PD4上经1k电阻接了一个LED到电源正极,这样,当PD4为0时,led被点亮。配置PD4为推挽输出,配置PA1为带中断浮空输入,然后开中断,进入halt状态,接着在halt语句之后拉低PD4,以点亮led。如果mcu正常进入halt状态,led不亮。

 

    在IAR下编译、下载并调试,程序无编译错误,正常下载到MCU,全速运行,led没有被点亮。哦噢,成功了...慢着,stop debuging,让程序在MCU上跑一下看看,...led亮了!!发克!

   这个什么状况

 

    看PDF、看STM8S参考手册,没有找到明显的提示,晕!问度娘,度娘给了我一些不相干的东西,晕菜,在q群里吼吼,高手们都很忙,没空理我。

 

    怎么办?

 

    自己琢磨,瞎琢磨,这个问题折磨我好多天了,领导天天过来问我,搞定了没有。下午的时候老大过来问我好了没有,我说有点问题,老大说,听老二(二老板)说这个项目很简单的。。。言下之意,是不是我的水平问题,没办法,气也没用。

 

    随手把代码改成下面的样子:

#define led PD_ODR_ODR4

void main(void)
{
 PD_DDR_DDR4 = 1;
 PD_CR1_C14  = 1;
 PD_CR2_C24  = 0;
 led = 1;
 PA_DDR_DDR2 = 0;
 PA_CR1_C12  = 0;
 PA_CR2_C22  = 1;
 EXTI_CR1_PAIS = 3;
 asm("rim");
 
 asm("halt");
 led = 0;
  

 
 while(1);

}

    有什么不同?换了一个口,用PA2口来触发唤醒,编译、下载并调试,全速没问题,led没亮。点一下stop debuging,让MCU跑,led没亮!!!哦哦哦,貌似ok了?!拉低一下PA2,led点亮了,成功了!

 

    赶紧看产品手册,PA1口是外部晶振的输入口,手册上有这么一句话:

 关于STM8S的halt状态及唤醒

    不知道是不是这个原因引起的,有待考证。请知道的高手指点我一下。

 

    并且在问度娘的时候,知道了另外一件事,就是在进入halt的时候,MCU会自动asm("rim");也就是说,如果要进入halt状态,则可以省掉asm("rim");语句。对于偷懒的我,这个很受用。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有