AnsweredAssumed Answered

STM8S timer is working properly

Question asked by Chayan Roy on Feb 26, 2017
Latest reply on Feb 27, 2017 by Chayan Roy

Hello, I am completely new to stm8microcontroller, currently I am doing a project on  it. My  project is ir remote operated home automation. Now,for the programming ,I am  using two timers,TIMER4  for rc5 decoding and TIMER1 for some delay operation. TIMER 1 operation is continuous, i.e like main function. TIMER1 will be running continuously and TIMER4 will start whenever any RC5 decoding is required. As there is two timers running,I have set  timer software priority. TIMER4 has highest priority. The problem is,TIMER1 loses its clock, after  few minutes.or if it runs continuously..suddenly stops it environmental disturbance occurs.. At first I thought it may be EMC issue,so I took all the precautions guided by ST EMC guide line. But the problem persists . I have tried my level best to solve this but failed.Now I am totally in a dead point. Please  give me  some suggestion/help. I have attached the full  stdv project and code along  with . Pleasehelp if any one has any solution.

 

Here is the code:

 

#include "STM8S003F3P.h"

 

#define SHORT_MIN  444
#define SHORT_MAX  1211
#define LONG_MIN 1211
#define LONG_MAX 1600

 

#define STATE_START1  0
#define STATE_MID1    1
#define STATE_MID0    2
#define STATE_START0  3
#define STATE_BEGIN   4
#define STATE_ERROR   5

 


void InitialiseSystemClock(void);
void RC5_Init(void);
void commandapply(void);
void RC5reset(void);

 


unsigned int time=0,command,delay=0,t,previousbit,i;
unsigned char EdgeNumber=0,x;
 unsigned char trans[4] = {0x01, 0x91, 0x9b, 0xfb};
 volatile char state,newstate;
 unsigned char event=1,j;
 
 unsigned char counter=14;

 

void main(void){
 
InitialiseSystemClock();

 

PD_DDR &=~(1<<4);
PD_CR1 |=(1<<4);

 

PD_CR2 |=(1<<4);

 

PD_DDR |=(1<<5);
PD_CR1 |=(1<<5);
PD_CR2 |=(1<<5);
PD_DDR |=(1<<6);
PD_CR1 |=(1<<6);
PD_CR2 |=(1<<6);

 

PD_DDR |=(1<<1);
PD_CR1 |=(1<<1);
PD_CR2 |=(1<<1);

 

PA_DDR &=~(1<<3);
PA_CR2 |=(1<<3);

 

 

 

 

 

TIM1_PSCRH=0;
TIM1_PSCRL=16;
TIM1_ARRH=2;
TIM1_ARRL=255;
TIM1_IER=(1<<0);
TIM1_CR1=(1<<0);

 

 

 


TIM4_PSCR=16;
TIM4_ARR=0X01;
TIM4_IER=(1<<0);

 

 
 ITC_SPR3=(0<<7)|(1<<6);
 ITC_SPR4=(0<<3)|(0<<2);
 
EXTI_CR1=0XC3;

 

_asm("rim");
while(1){
    

 

}

 


}
@far @interrupt void TIMER4_INTERRUPT (void){
time++;

 


TIM4_SR &=~(1<<0);
return;

 

}
@far @interrupt void PortD_external_interrupts (void){

 

TIM1_IER &=~(1<<0);

 


TIM4_CR1=(1<<0);
delay=time;

 

if(state==STATE_BEGIN){

 


counter--;
command |=1<<counter;
state=STATE_MID1;
delay=0;
time=0;
TIM4_CR1=(1<<0);
return;

 

}

 

 

 


if((PD_IDR & (1<<4))){
event=2;
}else{
if(!(PD_IDR & (1<<4)))
event=0;
}

 

if(delay>LONG_MIN & delay<LONG_MAX){
    

 

event=event+4;

 

}
else if(delay < SHORT_MIN || delay > SHORT_MAX)
    {
        /* If delay wasn't long and isn't short then
         * it is erroneous so we need to reset but
         * we don't return from interrupt so we don't
         * loose the edge currently detected. */
        RC5reset();
                return;
            }

 

newstate = (trans[state]>>event) & 0x03;

 

state=newstate;

 

 if(state == STATE_MID0)
    {
        counter--;
}
else{
if(state==STATE_MID1){
counter--;
command |=1<<counter;

 

time=0;

 

}
}
if(counter==0 && (state==STATE_START1 || state==STATE_MID0)){
    PD_CR2 &=~(1<<4);
commandapply();

 

}

 


time=0;
delay=0;

 

return;

 


}

 


void commandapply(void){
    t=command &0x800;
if(x==0){

 

previousbit=t;
x=1;
}
if(t !=previousbit){
/*F ON/OFF */
if(command==0b11001101101001){
    
PA_CR2^=(1<<3);

 

TIM1_CR1^=(1<<0);
}
if(command==0b11101101101001){
    PA_CR2 ^=(1<<3);
TIM1_CR1^=(1<<0);

 

}
/* L1 ON?OFF */
if(command==0b11001101100010){
PD_ODR ^=(1<<6);

 


}
if(command==0b11101101100010){
PD_ODR ^=(1<<6);

 


}
/* F++ */
if(command==0b11001101011110){
PD_ODR &=~(1<<6);

 


}
if(command==0b11101101011110){
PD_ODR &=~(1<<6);

 


}
/* F-- */
if(command==0b11001101001111){
PD_ODR |=(1<<6);

 


}
if(command==0b11101101001111){
PD_ODR |=(1<<6);

 


}
previousbit=t;
}
TIM4_CR1 &=~(1<<0);

 

TIM1_IER=(1<<0);
RC5reset();
}
void RC5_Init(void){

 


PD_DDR &=~(1<<4);
PD_CR1 |=(1<<4);
PD_CR2 |=(1<<4);

 

 

 

TIM4_PSCR=0;
TIM4_ARR=0X01;
TIM4_IER=(1<<0);

 

counter=14;
command=0;

 


PD_ODR |=(1<<0);

 

state=STATE_BEGIN;
}

 

void RC5reset(void){
PD_CR2=(1<<4);

 

command=0;
state=STATE_BEGIN;
counter=14;

 


}
void InitialiseSystemClock(void)
        {
        CLK_ICKR = 0;                       //  Reset the Internal Clock Register.
        CLK_ICKR = (1<<0);;                 //  Enable the HSI.
        CLK_ECKR = 0;                       //  Disable the external clock.
        while (!(CLK_ICKR & (1<<1)));       //  Wait for the HSI to be ready for use.
        CLK_CKDIVR = 0;                     //  Ensure the clocks are running at full speed.
        CLK_PCKENR1 = 0x90;                 //  Enable all peripheral clocks.
        CLK_PCKENR2 = 0x00;                 //  Ditto.
        CLK_CCOR = 0;                       //  Turn off CCO.
        CLK_HSITRIMR = 0;                   //  Turn off any HSIU trimming.
        CLK_SWIMCCR = 0;                    //  Set SWIM to run at clock / 2.
        CLK_SWR = 0xe1;                     //  Use HSI as the clock source.
        CLK_SWCR = 0;                       //  Reset the clock switch control register.
        CLK_SWCR = (1<<1);                  //  Enable switching.
        while (CLK_SWCR & (1<<0));        //  Pause while the clock switch is busy.
        }
        
        
    @far @interrupt void PortA_external_interrupts (void){

 

TIM1_CR1=(1<<0);

 

    
    
return;
    
    
    }
    
@far @interrupt void TIMER2_INTERRUPT (void){

 


TIM2_SR1 &=~(1<<0);
}
@far @interrupt void TIMER1_INTERRUPT (void){

 

 

 

PD_ODR |=(1<<5);
for(i=0;i<=255;i++);
PD_ODR &=~(1<<5);

 

TIM1_SR1 &=~(1<<0);

 

}

Attachments

Outcomes