你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm8s的halt模式问题

[复制链接]
saefra 提问时间:2015-4-20 10:29 /
本帖最后由 saefra 于 2015-4-22 14:50 编辑

新手做stm8的小东西,芯片是stm8s103f3,做的糊里糊涂的,问题如下:
用到了halt模式,仿照网上已有的一些资料写了点东西,但进入halt关掉的一些东西(time,adc等),在外部中断进来唤醒后,其他的大概还正常但time和adc是没有工作了的。
有关程序如下:
中断部分,我直接从中断进halt也不知道行不行,下板子上cheshi
#pragma vector=8
__interrupt void EXTI_PORTD_IRQHandler(void)
{
        BitStatus bit_status;
        bit_status = GPIO_ReadInputPin(GPIOD, ggm);
        if (bit_status == RESET)  //SET or RESET
        {
           CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
      Buttom_Init();  
    ADC_Init();
    Tim1_Init();
    LED_Init();
               tal=0;
                GPIO_WriteHigh(GPIOA, abcd);
                GPIO_WriteHigh(GPIOD, led);
        }
else
        {
                  ADC2_DeInit();
                   TIM1_DeInit();
                    GPIO_DeInit(GPIOA);
                GPIO_DeInit(GPIOB);
                GPIO_DeInit(GPIOC);
                GPIO_DeInit(GPIOD);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1,DISABLE);
  GPIO_Init(GPIOD, led, GPIO_MODE_OUT_PP_LOW_FAST);
  GPIO_Init(GPIOD, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);
  GPIO_Init(GPIOA, abcd, GPIO_MODE_OUT_PP_LOW_FAST);  
  GPIO_Init(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_SLOW);
  GPIO_Init(GPIOB,GPIO_PIN_4|GPIO_PIN_5,GPIO_MODE_IN_PU_NO_IT);  
  GPIO_Init(GPIOC,GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_IN_PU_NO_IT);


  Buttom_Init();
  enableInterrupts();
  halt() ;
        }
        
        ;
}
应该是没说清楚的,望大牛们指导···



收藏 1 评论14 发布时间:2015-4-20 10:29

举报

14个回答
废鱼 回答时间:2015-4-20 16:45:05
在while(1)之前调用halt() ;
中断中不要增加太多的处理,只处理中断事件就可以了。
while(1)里面加LED闪烁。
理论在while(1)之前进入休眠,外部中断唤醒以后,直接执行后面的代码。

点评

那该如何再次进入低功耗状态呢  发表于 2017-3-6 10:05
saefra 回答时间:2015-4-20 20:55:54
本帖最后由 saefra 于 2015-4-21 10:28 编辑

没改出来
还有一个问题就是adc转换出来,调电位器最多只能1分钟的样子有效,超过后就会一直延时。。。
附上工程~~~
废鱼 回答时间:2015-4-21 09:05:15
你按照我说的改,不要在中断里面加休眠。
saefra 回答时间:2015-4-21 09:21:29
额。。。传错工程了,这个是没加休眠的
saefra 回答时间:2015-4-21 11:19:58
本帖最后由 saefra 于 2015-4-21 20:08 编辑

int main(void)
{
   /*设置内部时钟16M为主时钟*/
   CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
          ADC_Init();
       Tim1_Init();
    LED_Init();  
         ADC1_DeInit();
                   TIM1_DeInit();
                   /* GPIO_DeInit(GPIOA);*/
                GPIO_DeInit(GPIOB);
                GPIO_DeInit(GPIOC);
                GPIO_DeInit(GPIOD);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C,DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1,DISABLE);
   //  |GPIO_PIN_5     
  GPIO_Init(GPIOD, led, GPIO_MODE_OUT_PP_LOW_FAST);
  GPIO_Init(GPIOD, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);

  GPIO_Init(GPIOA, abcd, GPIO_MODE_OUT_PP_LOW_FAST);   
  
  GPIO_Init(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_SLOW);  

  GPIO_Init(GPIOB,GPIO_PIN_4|GPIO_PIN_5,GPIO_MODE_IN_PU_NO_IT);  

  GPIO_Init(GPIOC,GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_IN_PU_NO_IT);  

    enableInterrupts();
  halt() ;//进入停机
while (1)
saefra 回答时间:2015-4-21 11:23:04
我把程序改成这个样子以后,while里面加了led闪烁,唤醒以后会进入while,但是单步调试发现没再进过adc和time1,估计还有其他东西也没唤醒也不一定
saefra 回答时间:2015-4-21 11:33:58
好吧,彻底迷糊了···单步的时候是中断唤醒后进while正常的,但是程序下进板子去给感应中断唤醒以后led就常亮(不管delay写什么或者屏蔽掉delay也好都常亮)
while (1)
   {
    GPIO_WriteHigh(GPIOD, GPIO_PIN_4);
    // Delay(101);
     GPIO_WriteLow(GPIOD, GPIO_PIN_4);
      Delay(101);
   }
废鱼 回答时间:2015-4-21 15:12:44
// Delay(101);
说明这个时间太短了。其实发生变化了。指示你看不到。去掉就更看不到了。
你delay的函数怎么写的?
唤醒以后重新初始化一下ADC和TIMER。
saefra 回答时间:2015-4-21 15:30:01
好的,我再改改
其实:唤醒以后重新初始化一下ADC和TIMER。我以前改过,没什么改进,不过我再试试
然后那个delay的话就是这个
void Delay(u16 nCount)
{
  /* Decrement nCount value */
  while (nCount != 0)
  {
    nCount--;
  }
}
如果是时间太短的话,写低也是一样的延时啊。。。
saefra 回答时间:2015-4-21 15:39:35
本帖最后由 saefra 于 2015-4-21 20:07 编辑

改完后没什么用,不知道改的对不对
枫天123 回答时间:2015-4-21 16:03:59
额也新手发表一下个人看法。楼主想按键唤醒后启动定时器和ADC采样。中断函数只要清标记就行了,其他置于主函数里面。定时器中断是不能唤醒HALT的哦。ADC只要初始化不管halt还是全速运行都不会影响,除非halt前你关闭了(不关闭也不怎耗电)。附代码,运行ok的:

main()
{
     WORD j=0;
    INT_GLOBAL_DISABLE();/* Disable interrupts */
    CLK_Init();
    GPIO_Init();


    ADC_Init();

    AWU_Config(AWU_TIMEBASE_512MS);

    INT_GLOBAL_ENABLE();
    while(1)
   {
        CLK->ICKR |= CLK_ICKR_FHWU;
        FLASH->CR1 |= FLASH_CR1_AHALT;//active halt mode
        //FLASH->CR1 |= FLASH_CR1_HALT;//halt mode
        halt();


                                if(GetAdcValue() < ADC_POWER_THREOLD)
                                {
                                        ADC_count ++;
                                        if(ADC_count >= ADC_POWER_NUM)
                                        {
                                                ADC_count = 0;
                                                low_power_flag = 1;
                                        }                                                                               
                                }
                                else
                                {
                                        ADC_count = 0;
                                        low_power_flag = 0;
                                }      

   }
}///////

void ADC_Init(void)
{
    ADC_CR2  = 0x00;
    ADC_CR1  = 0x00;
    ADC_CSR  = 0x03;
    //ADC_TDRL = 0x04;//
        ADC_CLK_EN = 1;////CLK ENABLE
}
u16 GetAdcValue(void)//8bits
{
    u8   i;                          
    u16    accValue,value;          /*Variable of accumulate temperature ADC value*/


    accValue = 0;

    /* Sample AIN voltage in ADC single mode */
    ADC_CR1 |= 0x01;         /* First set ADON to power on the ADC module.    */
    i = 26;                   /* Wait >7us to ensure the ADC power on finished.*/
    while(i--);

    /* Store ADC value to AD_Value */
    //AD_Value = ((((unsigned int)ADC_DRH)<<2)+ADC_DRL);
    for( i = 0; i < 4; i++ )      
    {
                ADC_CR1 |= 0x01;                 /* Set ADON again to start AD convert.                   */
                while(!(ADC_CSR & 0x80));/* Waiting for AD convert finished (EOP=1).          */

        value =  ADC_DRH << 2;             /*Remove four invalid bits*/
        value |= ADC_DRL;            /*Combine with four valid bits*/

        accValue += value;              /*Accumulate sampling value twice*/
    }
       
        return (accValue>>2);       
}




废鱼 回答时间:2015-4-21 16:23:26
你在while1里面加休眠,不是一直在休眠唤醒,休眠唤醒啊。要做一个判断,需要的时候休眠。唤醒以后就别休眠了。
枫天123 回答时间:2015-4-21 16:46:46
嗯,例程而已。自己根据实际情况调整拜。实际我也是有条件的,只是代码复杂没发上来,呵呵

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版