AnsweredAssumed Answered

RTC not working correctly and also external interrupt has getting multiple triggering pulse when timer IRQ calls even if i am not providing any triggering pulse to external interrupt pin.

Question asked by pawar.sudeep on Feb 25, 2016
Latest reply on Mar 2, 2016 by kk
Hi !!..
  I am in STM coding platform. I am developing Autometer product which includes RTC, External interrupt and timer interrupt IRQ in code. I am getting two main issues. My RTC in not working properly. When I power on RTC is running from time value by which it configured. Means it its value is not saving in backup resister and also RTC not running in VBAT mode also. I am using LSI clock for it. And second issue is that I am timer IRQ for seven segment synchronization it is working properly but same time I am using external interrupt to sense rotation pulse. I am configured it for rising edge trigger. My issue is that when I am giving external pulse to this input pin it get rising edge triggered pulse and external interrupt IRQ comes but same time Timer IRQ also comes because it configured for every 1ms. and when control goes in timer IRQ external interrupt gets continuous triggering pulses even if I am giving any triggering pulse to it. Why I am getting this issues please give me suggestion if any one knows? I am giving here my code please refer and give suggestion to solve my issues.

#include "stm32f0xx.h"


#define BASIC_FAIR 25
#define MIN_DISTANCE 1900
#define MAX_PULSE 1400
#define MIN_PULSE 140
#define CHARGE 1.20
#define WAITING_CHARGE 1.0

unsigned int totalDistance=0, waitingTime=0,localfair;
float fair=0.0;
char fairDigit1=0, fairDigit2=0, fairDigit3=0, fairDigitDot1=0, fairDigitDot2=0;

unsigned char sevenSegData[16]={0x3F, 0x0C, 0x5B, 0x5E, 0x6C, 0x76, 0x77, 0x1C, 0x7F, 0x7E, 0xF1, 0x6D, 0x0C, 0x41, 0x73, 0x21};

unsigned long TimeToCompute=0x0F,DateToCompute=0X0F;
unsigned char SecLSB=0, SecMSB=0, MinLSB=0, MinMSB=0, HourLSB=0, HourLSB1=0;
unsigned char DateLSB, DateLSB1;

unsigned int pulse_count=0, SCNT=0, Digit1,Digit2,Digit3,Digit4,Digit5,Digit6,Digit7,Digit8,Digit9;
unsigned char oneKmFlag=0,mode2Flag=0, mode3Flag=0,hndmFlag=0;

int i=0, cnt=0;

void portcInit(){
    //RCC -> CFGR |= (1<<25);                    // select LSI Oscillator
    //RCC -> CIR |= (1<<16);                      // LSI Ready Flag Cleared
    //RCC -> CIR |= (1<<8);                       // LSI ready interrupt enable

    RCC -> AHBENR |= RCC_AHBENR_GPIOAEN;  //enable clock to port A
    RCC -> AHBENR |= RCC_AHBENR_GPIOBEN;

    GPIOA->MODER = 0x28015555; //PA-0,1,2:- output //PA9,10,11=input
    GPIOB->MODER = 0x55555555;

    GPIOB->PUPDR = 0x55555555;
    GPIOA->PUPDR = 0x55555555;
}

void Delay(){
    int i;
    for (i=0; i<10000; i++);
}

void SysInit()
{
    // Set up timer
    RCC -> APB1ENR |= (1<<0); // turn on clock for timer2
    TIM2->PSC=4999;
    TIM2->ARR=1;
    TIM2->CR1=0x0004;
    TIM2->DIER=0x0001;
    NVIC_EnableIRQ(TIM2_IRQn);
    NVIC_SetPriority(TIM2_IRQn,1);
    TIM2->CR1 |= (1<<0);
}

void rtcinit()
{
    /* Enable the PWR clock */
    RCC->APB1ENR |= (1<<28);

    /* Allow access to RTC */
    PWR->CR |= (1<<8);

    RCC -> CFGR |= (1<<25);      // select LSI Oscillator
    RCC -> CIR |= (1<<16);    // LSI Ready Flag Cleared
    RCC -> CIR |= (1<<8);     // LSI ready interrupt enable

    //enable lsi
    RCC->CSR = 0x00000001;                        // LSI On
    while( (RCC ->CSR & RCC_CSR_LSIRDY) == 0);     // Wait for LSI Ready ON

    RCC->BDCR = 0x00010000;                    // RTC Reset
    RCC->BDCR = 0x00008200;                        // RTCEN = 1,

    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;

    RTC->ISR |= (1<<7);                            //enter initialization mode  bit 7
    while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF)
    {}
    // Configure the RTC prescaler
    RTC->PRER = 0x007F0137;                      //set SynchPrediv to FF and AsynchPrediv to 7F
    RTC->TR = 0x00001505;                        //setting time to
    RTC->DR = 0x0016E117;                        //set date to
    //RTC->BKP1R=0x00120108;
    RTC->ISR &= ~(1<<7);                        //exit initialization mode

    RTC->ISR |= (1<<6);

    //lock write protection for RTC registers
    RTC->WPR = 0xFE;
    RTC->WPR = 0x64;
}

void externalInterruptConfiguration(){
    //RCC ->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    RCC ->APB2ENR |= (1<<0);
    SYSCFG->EXTICR[3]=0x0000;
    EXTI->RTSR |= (1<<11);
    //EXTI->EMR |= (1<<11);
    EXTI->IMR |= (1<<11);
    NVIC_EnableIRQ(EXTI4_15_IRQn);
    NVIC_SetPriority(EXTI4_15_IRQn,2);
}

void DisplayFHIeE()
{
    Digit1= 10;
    Digit2= 11;
    Digit3= 12;
    Digit4= 13;
    Digit5=    14;
}

void displayRTCTime()
{
    if((RTC->ISR & RTC_ISR_RSF) == RTC_ISR_RSF)
    {
        TimeToCompute = RTC->TR;
        DateToCompute = RTC->DR;

        MinLSB= (( TimeToCompute & 0x00000F00 )>> 8);
        Digit7 = MinLSB;   // RTC Minute LSB


        MinMSB= ((TimeToCompute& 0x0000F000) >>  12);
        Digit6 = MinMSB;   // RTC Minute MSB

        SecLSB= ((TimeToCompute & 0x0000000F));
        Digit9 = SecLSB;   // RTC Second LSB

        SecMSB= ((TimeToCompute& 0x0000000F0) >>4 );
        Digit8 = SecMSB;   // RTC Second MSB
    }
}

void EXTI4_15_IRQHandler(void)
{
    if (EXTI->PR & (1<<11))
    {
        pulse_count++;
        if(pulse_count==140)
        {
            hndmFlag=1;
            pulse_count=0;
        }
        EXTI->PR = (1<<11);
    }
}

void Calculate_Distance(){
    totalDistance=totalDistance+100;
}

void calculate_Fair()
{
    float localSfair=0;

    if(totalDistance <= MIN_DISTANCE)
    {
        fair=BASIC_FAIR;
    }
    else
    {
        fair=BASIC_FAIR + (((totalDistance - MIN_DISTANCE)/100)* CHARGE);
    }
    localfair=fair*100;
    fairDigit1=localfair/10000;
    fairDigit2=(localfair%10000)/1000;
    fairDigit3=((localfair%10000)%1000)/100;

    fairDigitDot1=(((localfair%10000)%1000)%100)/10;
    fairDigitDot2=localfair%10;
}

void displayDistance()
{
    int l1, l2, l3, l4;
    l1=totalDistance/100000;
    l2=(totalDistance%100000)/10000;
    l3=((totalDistance%100000)%10000)/1000;
    l4=(((totalDistance%100000)%10000)%1000)/100;

    Digit6 = l1;
    Digit7 = l2;
    Digit8 = l3;
    Digit9 = l4;
}

void displayFair()
{
    Digit1 = fairDigit1;
    Digit2 = fairDigit2;
    Digit3 = fairDigit3;
    Digit4 = fairDigitDot1;
    Digit5 = fairDigitDot2;
}

void TIM2_IRQHandler()
{
    unsigned int i;
    if ((TIM2->SR & 0x0001) != 0)
    {
        switch(SCNT)
        {
            case 0:
                GPIOB-> ODR =(0<<13);
                GPIOB-> ODR =(1<<8);
                GPIOB-> ODR |= sevenSegData[Digit1];
                SCNT++;
                break;

            case 1:
                GPIOB-> ODR =(0<<8);
                GPIOB-> ODR =(1<<14);
                GPIOB-> ODR |= sevenSegData[Digit2];
                SCNT++;
                break;

            case 2:
                GPIOB-> ODR =(0<<14);
                GPIOB-> ODR =(1<<9);
                if((mode3Flag==1) || (mode2Flag==1))
                {
                GPIOB-> ODR |= sevenSegData[Digit3]  | 0x80;
                }
                else
                {
                GPIOB-> ODR |= sevenSegData[Digit3];
                }
                SCNT++;
                break;

            case 3:
                GPIOB-> ODR =(0<<9);
                GPIOB-> ODR =(1<<15);
                GPIOB-> ODR |= sevenSegData[Digit4];
                SCNT++;
                break;

            case(0x04):
                GPIOB-> ODR =(0<<15);
                GPIOB-> ODR =(1<<10);
                GPIOB-> ODR |= sevenSegData[Digit5];
                SCNT++;
                break;

            case 5:
                GPIOB-> ODR =(0<<10);
                GPIOA-> ODR =(1<<8);
                GPIOA-> ODR |=(1<<8);  //   Added extra for matching Synchronization
                GPIOA-> ODR |=(1<<8);  //   in switching Port A to Port B
                GPIOA-> ODR |=(1<<8);  //   when seven segment select Line Switching from Port A to Port B.
                  GPIOB-> ODR = sevenSegData[Digit6];
                SCNT++;
                break;

            case 6:
                GPIOA-> ODR =(0<<8);
                GPIOA-> ODR &=(0<<8);    //   Added extra for matching Synchronization
                GPIOA-> ODR &= (0<<8);   //   in switching Port A to Port B when seven segment select Line Switching.
                GPIOB-> ODR =(1<<11);
                GPIOB-> ODR |= sevenSegData[Digit7];
                SCNT++;
                break;

            case 7:
                GPIOB-> ODR =(0<<11);
                GPIOB-> ODR =(1<<12);
                if((mode3Flag==1) || (mode2Flag==1))
                {
                    GPIOB-> ODR |= sevenSegData[Digit8] | 0x80;
                }
                else
                {
                    GPIOB-> ODR |= sevenSegData[Digit8];
                }
                SCNT++;
                break;

            default:
                GPIOB-> ODR =(0<<12);
                GPIOB-> ODR =(1<<13);
                GPIOB-> ODR |= sevenSegData[Digit9];
                SCNT=0;
                break;
        }
        TIM2->SR &=~(1<<0) ;    // clear update interrupt flag
    }
}

int main(void)
{
    portcInit();
    rtcinit();
    externalInterruptConfiguration();
    SysInit();

    GPIOA-> ODR &= (0<<8);
    GPIOB-> ODR= 0x0000;

    while(1)
    {
        if ((mode2Flag==0) && (mode3Flag==0))
        {
            NVIC_DisableIRQ(EXTI4_15_IRQn);
            GPIOA-> ODR |= (1 << 0);    // LED 1 ON
            GPIOA-> ODR &= ~(1 << 1);    //LED 2 OFF
            GPIOA-> ODR &= ~(1 << 2);    //LED 3 OFF
            DisplayFHIeE();
            displayRTCTime();

            if ((GPIOA->IDR & GPIO_IDR_9))  //P1 Switch mode 2
            {
                mode2Flag=1;
                mode3Flag=0;
            }
        }

        if(mode2Flag==1)
        {
            GPIOA-> ODR &= ~(1 << 0);     // LED1 OFF
            GPIOA-> ODR |= (1 << 1);    //LED 2 ON
            GPIOA-> ODR &= ~(1 << 2);    //LED 3 OFF
            NVIC_EnableIRQ(EXTI4_15_IRQn);//enable interrupt

            if(hndmFlag==1)
            {
                Calculate_Distance();
                hndmFlag=0;
            }
            calculate_Fair();
            displayDistance();
            displayFair();

            if (GPIOA->IDR & GPIO_IDR_10)  //P2 Switch mode3 stop mode no pulses
            {
                mode3Flag=1;
                mode2Flag=0;
            }
        }
        if(mode3Flag==1)
        {
            //stop interrupt of pulses
            NVIC_DisableIRQ(EXTI4_15_IRQn);
            GPIOA-> ODR &= ~(1 << 0);     // LED1 OFF
            GPIOA-> ODR &= ~(1 << 1);    //LED 2 OFF
            GPIOA-> ODR |= (1 << 2);    //LED 3 ON

            if(hndmFlag==1)
            {
                Calculate_Distance();
                hndmFlag=0;
            }
            calculate_Fair();
            displayDistance();
            displayFair();

            if(GPIOA->IDR & GPIO_IDR_9)
            {
                mode3Flag=0;
                mode2Flag=1;
            }
        }
    }
}

 

Outcomes