<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=46&amp;t=19782&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2017-12-10T12:07:40+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=46&amp;t=19782&amp;mode</id>
<entry>
<author><name><![CDATA[sq8vps]]></name></author>
<updated>2017-12-10T12:07:40+01:00</updated>
<published>2017-12-10T12:07:40+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=19782&amp;p=200297#p200297</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=19782&amp;p=200297#p200297"/>
<title type="html"><![CDATA[[STM32] Przerwanie od RTC co sekundę nie działa]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=19782&amp;p=200297#p200297"><![CDATA[
Cześć.<br />Chciałbym zrobić tak, żeby przerwanie generowane z RTC było co sekundę (bit SECIE w RTC_CRH).<br />O ile samo RTC działa (licznik cały czas się zwiększa), to o tyle ani procedura obsługi przerwania nie jest wywoływana, ani flaga SECF w rejestrze RTC_CRL nie jest ustawiana.<br />Na testy w miejsca, które powinny być przetwarzane co sekundę, wstawiłem negację stanu diody na PA5.<br />Do testów używam Nucleo-F103RB (STM32F103RBT6).<br />Kod: <br />[syntax=c]#include &quot;stm32f10x.h&quot;<br /><br />    uint32_t rtc_count = 0;<br />    uint8_t sec, min, hour;<br />    uint8_t day, month;<br />    uint16_t year;<br /><br />    void RTC_IRQHandler(void) __attribute__ ((interrupt));<br />    void RTC_IRQHandler(void)<br />    {<br />        GPIOA-&gt;ODR ^= GPIO_ODR_ODR5;<br />        if(RTC-&gt;CRL &amp; RTC_CRL_SECF)<br />        {<br />            rtc_count = (RTC-&gt;CNTL | (RTC-&gt;CNTH &lt;&lt; 16)); //zapisujemy wartosc licznika rtc<br />            calendar_update:<br />            if(rtc_count &gt; 86399) //jesli minelo 86399 sekund, to uplynal juz conajmniej dzien (urzadzenie moglo lezec wylaczone dlugo)<br />            {<br />                if((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12)) //jesli miesiac ma 31 dni<br />                {<br />                    if(day &lt; 31) day++; //jesli minelo mniej niz 31 dni, to doliczamy dzien<br />                    else if(month == 12) //a jesli to byl 31 dzien i grudzien<br />                    {<br />                        month = 1; //NOWY ROK!<br />                        day = 1;<br />                        year++;<br />                    } else  //a jesli to nie grudzien, ale minal 31 dzien<br />                    {<br />                        month++; //nastpeny miesiac<br />                        day++;<br />                    }<br />                }<br />                else if(month == 2) //a jesli to luty<br />                {<br />                    if(day &lt; 28) day++; //i jesli jest przed 28 lutego to dzien nastepny<br />                    else if(day == 28) //a jesli jest 28<br />                    {<br />                        if((year % 400 == 0) || ((year % 100 != 0) &amp;&amp; (year % 4 == 0))) day++; //jesli to rok przestepny to dzien zwiekszamy<br />                        else<br />                        {<br />                            month++; //a jak nie to nastepny miesiac<br />                            day = 1;<br />                        }<br />                    } else //a jesli to 29 lutego (rok przestepny)<br />                    {<br />                        month++; //to nastepny miesiac<br />                        day = 1;<br />                    }<br />                } else //a jak miesiac ma 30 dni<br />                {<br />                    if(day &lt; 31) //i jesli minal 30 dzien<br />                    {<br />                        month++; //nastepny miesiac<br />                        day = 1;<br />                    }<br />                    else day++; //a jak nie minal 30 dzien<br />                }<br />            }<br />            rtc_count -= 86400; //odejmujemy ten dzien z licznika<br />            if(rtc_count &gt; 86399) goto calendar_update; //i jesli mimo to w liczniku mamy jeszcze jeden dzien (urzadzenie lezalo dlugo bez uruchomienia), to przetwarzamy i jego<br /><br />            hour = rtc_count / 3600; //zapisujemy godzine<br />            min = (rtc_count % 3600) / 60; //i minute<br />            sec = (rtc_count % 3600) % 60; //i sekunde<br /><br /><br />            RTC-&gt;CRL |= RTC_CRL_RTOFF; //wlaczamy mozliwosc zapisu do rejestrow RTC<br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_RSF;<br />            RTC-&gt;CNTL = (rtc_count &amp; 0xFFFF); //zapisujemy pozostale rtc_count<br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RSF) == 0);;<br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_RSF;<br />            RTC-&gt;CNTH = (rtc_count &amp; 0xFFFF0000);<br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RSF) == 0);;<br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_RTOFF; //wylaczamy mozliwosc zapisu do rejestrow RTC<br /><br />            PWR-&gt;CR |= PWR_CR_DBP; //wlaczamy mozliwosc zapisu do rejestrow BKP<br /><br />            BKP-&gt;DR1 = day; //zapisujemy dzien, rok i miesiac<br />            BKP-&gt;DR2 = month;<br />            BKP-&gt;DR3 = year;<br /><br />            PWR-&gt;CR &amp;= ~PWR_CR_DBP; //wlaczamy mozliwosc zapisu do rejestrow BKP<br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_SECF;<br />        }<br />    }<br /><br /><br />   <br />    int main(void)<br />    {<br /><br />            RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPAEN; //zegrad dla GPIOA<br />            RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPBEN; //zegrad dla GPIOA<br />            RCC-&gt;APB2ENR |= RCC_APB2ENR_IOPCEN; //zegar dla GPIOC<br />            RCC-&gt;APB2ENR |= RCC_APB2ENR_AFIOEN; //zegar dla AFIO<br />            //RCC-&gt;APB1ENR |= RCC_APB1ENR_TIM2EN; //zegar dla timera2<br />            //RCC-&gt;APB1ENR |= RCC_APB1ENR_USART2EN; //zegar dla usarta2<br />            //RCC-&gt;APB2ENR |= RCC_APB2ENR_ADC1EN; //zegar dla adc1<br />            //RCC-&gt;AHBENR |= RCC_AHBENR_DMA1EN; //zegar dla dma<br />            RCC-&gt;APB1ENR |= RCC_APB1ENR_PWREN; //zegar dla PWR<br />            RCC-&gt;APB1ENR |= RCC_APB1ENR_BKPEN; //zegar dla BKP<br />            //RCC-&gt;APB1ENR |= RCC_APB1ENR_I2C1EN; //wlaczamy I2C1<br /><br /><br />            GPIOA-&gt;CRL |= GPIO_CRL_MODE5_1; //ustawienie pinu PA5 jako wyjscia push pull 2mhz<br />            GPIOA-&gt;CRL &amp;= ~GPIO_CRL_MODE5_0;<br />            GPIOA-&gt;CRL &amp;= ~GPIO_CRL_CNF5;<br />            GPIOC-&gt;CRL |= GPIO_CRH_CNF13_1; //ustawienie pinu PC13 jako wejscia z podciagnieciem do zasilania<br />            GPIOA-&gt;CRL |= GPIO_CRL_MODE2_1; //usart2 wyjsce jako push pull<br />            GPIOA-&gt;CRL &amp;= ~GPIO_CRL_CNF2_0; //usart2 wyjscie jako alternatywna funkcja<br />            GPIOA-&gt;CRL |= GPIO_CRL_CNF2_1;<br />            GPIOA-&gt;CRL |= GPIO_CRL_CNF3_0; //usart2 wejsce jako floating<br />            GPIOA-&gt;CRL &amp;= ~GPIO_CRL_CNF3_1;<br /><br />            PWR-&gt;CR |= PWR_CR_DBP; //wlaczamy mozliwosc zapisu do rejestrow BKP<br /><br />            day = BKP-&gt;DR1; //odczytujemy ostanie dane kalendarza<br />            month = BKP-&gt;DR2;<br />            year = BKP-&gt;DR3;<br /><br />            PWR-&gt;CR &amp;= ~PWR_CR_DBP; //wylaczamy mozliwosc zapisu do rejestrow BKP<br /><br />            if((day == 0) || (month == 0) || (year == 0)) //jesli ktoras z wartosci w kalendarzu jest zerowa to ustawiamy domyslna<br />            {<br />                day = 1;<br />                month = 1;<br />                year = 1970;<br />            }<br /><br />         <br />            PWR-&gt;CR |= PWR_CR_DBP; //wlaczamy mozliwosc zapisu do rejestrow BKP<br />            RTC-&gt;CRL |= RTC_CRL_CNF; //wchodzimy w tryb konfiguracji RTC<br /><br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_RSF;<br /><br />            RCC-&gt;BDCR = 0;<br />            RCC-&gt;BDCR |= RCC_BDCR_LSEON; //i wlaczamy kwarc 32768khz<br /><br />            while((RCC-&gt;BDCR &amp; RCC_BDCR_LSERDY) == 0);; //czekamy na zainicjowanie LSE 32768khz<br /><br />            RCC-&gt;BDCR |= RCC_BDCR_RTCSEL_0; //ustwiamy zegar RTC z LSE<br />            RCC-&gt;BDCR &amp;= ~RCC_BDCR_RTCSEL_1;<br /><br />            RCC-&gt;BDCR |= RCC_BDCR_RTCEN; //wlaczamy RTC<br /><br />            PWR-&gt;CR &amp;= ~PWR_CR_DBP; //wylaczamy mozliwosc zapisu do rejestrow BKP<br /><br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RSF) == 0);;<br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RTOFF) == 0);; //czekamy, az ostatnia operacja zapisu do RTC zostanie ukonczona<br /><br />            RTC-&gt;PRLL = 32767; //ustawiamy preskaler zegara RTC<br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RTOFF) == 0);; //i czekamy, az ostatnia operacja zapisu do RTC zostanie ukonczona<br /><br />            RTC-&gt;CRH |= RTC_CRH_SECIE; //wlaczamy przerwanie sekundowe<br />            while ((RTC-&gt;CRL &amp; RTC_CRL_RTOFF) == 0);; //i czekamy, az ostatnia operacja zapisu do RTC zostanie ukonczona<br /><br /><br /><br />            RTC-&gt;CRL &amp;= ~RTC_CRL_CNF; //wychodzimy z trybu konfiguracji RTC<br /><br /><br />            NVIC_EnableIRQ(RTC_IRQn);<br /><br />            while(1)<br />            {<br />                if(RTC-&gt;CRL &amp; RTC_CRL_SECF) //tylko na testy, czy pojawia sie chociazby flaga, no i sie nie pojawia<br />                        {<br /><br />                    GPIOA-&gt;ODR ^= GPIO_ODR_ODR5;<br />                    RTC-&gt;CRL &amp;= ~RTC_CRL_SECF;<br />                        }<br />            }<br />    }[/syntax]<br /><br />Dziękuję za pomoc z góry.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14545">sq8vps</a> — 10 gru 2017, o 12:07</p><hr />
]]></content>
</entry>
</feed>