AnsweredAssumed Answered

TIMER4 PRESCALAR PROBLEM(STM8S)

Question asked by Chayan Roy on Mar 4, 2017
Latest reply on Mar 20, 2017 by Chayan Roy

Hello,

Here is my code :  TIMER1 and TIMER2 works fine,but TIMER4 is not working properly. Problem is what ever value is written  to TIM4_PSCR ,it is not taking any value, prescalar register always shows 0X00. TIMER4 is used for 100us delay, TIMER4 starts when TIMER1 interrupt occurs.May be I am making some silly mistake. Here is the code below:

 

#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;
unsigned char EdgeNumber=0,x;
 unsigned char trans[4] = {0x01, 0x91, 0x9b, 0xfb};
 volatile char state,newstate;
 unsigned char event=1;
 unsigned char duty[5]={25,24,22,18,15};
 unsigned char counter=14,k;

 

void main(void){

 

                   InitialiseSystemClock();
                 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<<2);
                                 PD_CR1 |=(1<<2);
                                 PD_CR2 |=(1<<2);
                                
                                 PD_DDR |=(1<<1);
                                 PD_CR1 |=(1<<1);
                                 PD_CR2 |=(1<<1);
                                
                                 PA_DDR &=~(1<<3);
                                 PA_CR1 |=(1<<3);
                                 TIM4_PSCR=16;

                                    TIM4_ARR=100;

                                       TIM4_IER=(1<<0);
                                
                                
                                 TIM1_PSCRH=0;
                                 TIM1_PSCRL=16;
                                
                 
                                 TIM1_IER=(1<<0);
                                

 

                   RC5_Init();

 

                    EXTI_CR1=0b11000011;

 


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

 


}

 

            @far @interrupt void TIMER4_INTERRUPT (void){
                PD_ODR  &=~(1<<1);

               TIM4_CR1 &=~(1<<0);

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

        PD_ODR  |=(1<<1);

TIM4_CR1=(1<<0);
     TIM1_CR1 &=~(1<<0);
     TIM1_SR1 =~(1<<0);
  TIM1_ARRH=duty[k];
      TIM1_ARRL=255;
 
 return;
 
 }
               @far @interrupt void TIMER2_INTERRUPT (void){
                  
                                    time++;

 

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

 

}
           
                                 @far @interrupt void PortA_external_interrupts (void){
                                    
                                     TIM1_CR1 &=~(1<<0);
                                 PD_ODR &=~(1<<1);
                                
                                 TIM1_CR1=(1<<0);
                                 return;
                                 }
                    @far @interrupt void PortD_external_interrupts (void){

 

                      TIM2_CR1=(1<<0);

 

                           delay=time;

 

                      
                                             if(state==STATE_BEGIN){

 


                       counter--;
                    command |=1<<counter;
                  
                                    state=STATE_MID1;

 

                     delay=0;

 

                    time=0;
               
                                  TIM2_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){
                                             PD_ODR^=(1<<5);
                                             PA_CR2^=(1<<3);
                                            
                      TIM1_CR1^=(1<<0);

 

                        }
                if(command==0b11101101101001){
                                    PD_ODR^=(1<<5);
                                    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){
                
                                
if(k<4){

 

k++;

 

}
else{
    if(k>4){

 

k=4;
}

 


}

 


        }
          if(command==0b11101101011110){

 


         if(k<4){

 

k++;

 

}
else{
    if(k>4){

 

k=4;
}

 


}
                
                
                
                
                
                

 


     }
/* F-- */
             if(command==0b11001101001111){
                 
                                                     
if(k>0){

 


k--;

 

}        
else{
    
k=0;

 


}

 


              }
                 if(command==0b11101101001111){

 

                  
                                    if(k>0){

 


k--;

 

}        
else{
    
k=0;

 


}

 

                                    
                                    
                                    
                                    

 


             }
                 previousbit=t;
}

 

                 TIM2_CR1 &=~(1<<0);
                    
                                        RC5reset();
}
void RC5_Init(void){

 


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

 

 

 

                         TIM2_PSCR=16;
                          TIM2_ARRH=0X00;
                         TIM2_ARRL=0X01;
                              TIM2_IER=(1<<0);

 

                                counter=14;

 

                                  command=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 = 0xff;                 //  Enable all peripheral clocks.
                                   CLK_PCKENR2 = 0xff;                 //  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.
                                    }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

/*    BASIC INTERRUPT VECTOR TABLE FOR STM8 devices

 */

 

typedef void @far (*interrupt_handler_t)(void);

 

struct interrupt_vector {
    unsigned char interrupt_instruction;
    interrupt_handler_t interrupt_handler;
};

 

@far @interrupt void NonHandledInterrupt (void)
{
    /* in order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction
    */
    return;
}
extern @far @interrupt void PortD_external_interrupts (void);
extern @far @interrupt void PortA_external_interrupts (void);
extern @far @interrupt void TIMER2_INTERRUPT (void);
extern @far @interrupt void TIMER1_INTERRUPT (void);
extern @far @interrupt void TIMER4_INTERRUPT (void);
extern void _stext();     /* startup routine */

 

struct interrupt_vector const _vectab[] = {
    {0x82, (interrupt_handler_t)_stext}, /* reset */
    {0x82, NonHandledInterrupt}, /* trap  */
    {0x82, NonHandledInterrupt}, /* irq0  */
    {0x82, NonHandledInterrupt}, /* irq1  */
    {0x82, NonHandledInterrupt}, /* irq2  */
    {0x82,PortA_external_interrupts }, /* irq3  */
    {0x82, NonHandledInterrupt}, /* irq4  */
    {0x82, NonHandledInterrupt}, /* irq5  */
    {0x82,PortD_external_interrupts}, /* irq6  */
    {0x82, NonHandledInterrupt}, /* irq7  */
    {0x82, NonHandledInterrupt}, /* irq8  */
    {0x82, NonHandledInterrupt}, /* irq9  */
    {0x82, NonHandledInterrupt}, /* irq10 */
    {0x82, TIMER1_INTERRUPT }, /* irq11 */
    {0x82, NonHandledInterrupt}, /* irq12 */
    {0x82, TIMER2_INTERRUPT}, /* irq13 */
    {0x82, NonHandledInterrupt}, /* irq14 */
    {0x82, NonHandledInterrupt}, /* irq15 */
    {0x82, NonHandledInterrupt}, /* irq16 */
    {0x82, NonHandledInterrupt}, /* irq17 */
    {0x82, NonHandledInterrupt}, /* irq18 */
    {0x82, NonHandledInterrupt}, /* irq19 */
    {0x82, NonHandledInterrupt}, /* irq20 */
    {0x82, NonHandledInterrupt}, /* irq21 */
    {0x82, NonHandledInterrupt}, /* irq22 */
    {0x82, TIMER4_INTERRUPT }, /* irq23 */
    {0x82, NonHandledInterrupt}, /* irq24 */
    {0x82, NonHandledInterrupt}, /* irq25 */
    {0x82, NonHandledInterrupt}, /* irq26 */
    {0x82, NonHandledInterrupt}, /* irq27 */
    {0x82, NonHandledInterrupt}, /* irq28 */
    {0x82, NonHandledInterrupt}, /* irq29 */
};

 

ANY suggestion  will be very help-full for me.Thanx in advance

Outcomes