新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM學習《十》—關于STM32的RTC調試

        ARM學習《十》—關于STM32的RTC調試

        作者: 時間:2016-11-20 來源:網絡 收藏
        這兩天一直在調試STM32的RTC部分,本來打算弄一個萬年歷的,但是現在看來是暫時實現不了了。為什么這樣說,因為RTC對晶振的要求非常高,必須是6p負載電容的32768晶振,這種晶振很難買,而且還很貴。下面是摘自一位網友的話:

        今天到電子市場找了一下,幾乎都是12.5p負載電容的32768晶振,只有一家有少量,負載電容是6p,20ppm的晶振要價是12.5p晶振的5倍,而且從外觀上也看不出來,也沒有測試方法能測出負載電容是6p還是12.5p。賣晶振的老板在這行干了10幾年,一說到6p的32768晶振就笑了。這個要求以前就有多個公司中過招,特別是DALLAS的片子,讓一家公司吃盡了苦頭,焊上的許多高精度12.5p晶振被迫全部換掉,訂的數萬只晶振也只能委托賣掉。老板說這種方式是IC廠家和大的晶振廠家聯合的一個小陰謀,因為以前6p的晶振只有很少幾個大廠家能做好,這樣可以幫助大晶振廠家形成壟斷。DALLAS的東西不敢恭維,向來賣得很貴,一片增強型的51經常還要賣四五十。
        6p的晶振既昂貴又不好采購,而且也難以辨認和測試。STM32這樣設計實在是難以理喻。其它我們用過的所有涉及RTC的MCU和時鐘芯片都不存在這個問題,如三星的44B0,2410,2440,飛利浦的LPC213x,LP214x等等。
        STM32是高度強調性價比的芯片,但是卻在RTC晶振上給中小客戶帶來很大不必要的麻煩,既增加成本和采購難度,又留下致命的隱患(RTC啟動死機)。特別是試樣和試生產階段,量又不大,怎么去專門訂做?
        希望ST公司能正視這個問題,在以后的改進中修正這個問題,能支持12.5p的常規32768晶振。

        本文引用地址:http://www.104case.com/article/201611/318953.htm

        調試了好長時間,我說怎么沒有反應,原來是因為晶振的原因,而且電容必須接6PF,我用的是15P的電容,等待晶振起振的時間特別長(1分鐘左右),開始我還以為是程序死在哪了呢!

        后來程序是調通了,但是1S中斷特別不準,我相信一定是因為晶振和電容的原因,先不管準不準,至少程序是調通了。把設置RTC的過程和大家分享:

        還是將寄存器定義添加若頭文件:

        //*************************************************************

        //PWR-Register

        //*************************************************************

        #define PWR_CR(*((volatile unsigned long *)0x40007000))

        #define PWR_CSR(*((volatile unsigned long *)0x40007004))

        //*******************************************************************

        //

        // RTC-Register

        //

        //*******************************************************************

        #define RTC_CRH(*((volatile unsigned long *)0x40002800))

        #define RTC_CRL(*((volatile unsigned long *)0x40002804))

        #define RTC_PRLH(*((volatile unsigned long *)0x40002808))

        #define RTC_PRLL(*((volatile unsigned long *)0x4000280C))

        #define RTC_DIVH(*((volatile unsigned long *)0x40002810))

        #define RTC_DIVL(*((volatile unsigned long *)0x40002814))

        #define RTC_CNTH(*((volatile unsigned long *)0x40002818))

        #define RTC_CNTL(*((volatile unsigned long *)0x4000281C))

        #define RTC_ALRH(*((volatile unsigned long *)0x40002820))

        #define RTC_ALRL(*((volatile unsigned long *)0x40002824))

        接下來就是RTC的寄存器配置:

        void RTC_Configuration(void)

        {

        RCC_APB1ENR|=0x18000000;//電源接口時鐘使能,備份接口時鐘使能

        PWR_CR|=0x00000100;//位8,允許訪問RTC寄存器和備份寄存器

        RCC_APB1RSTR|=0x08000000;//位27 BKPRST備份接口復位

        RCC_BDCR|=0x00000001;//位0 LSEON外部低速振蕩器使能

        while(RCC_BDCR&0x00000002==0); //位1LSERDY外部低速振蕩器可用

        RCC_BDCR|=0x00000100; //選擇LSE位RTC時鐘

        RCC_BDCR|=0x00008000; //位15 RTCEN RTC時鐘使能

        RTC_CRL|=0x10;//位4配置標志,1:進入配置模式

        while(RTC_CRL&0x04==0);//位3 RSF:寄存器同步標志

        while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經完成

        RTC_CRH=0x01;//使能1S中斷

        while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經完成

        RTC_PRLL=0xFF;//(1S中斷應該是32767,但我的晶振不準,0xFF都是1S多)

        while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經完成

        RTC_CRL&=0xFFEF;//位4,退出配置模式(開始更新RTC寄存器).

        SETENA0|=0x00000008;//允許RTC中斷

        }

        RTC中斷處理函數:

        void RTC_IRQHandler(void)

        {

        if(RTC_CRL&0x01==1) //查詢1S中斷標志

        {

        RTC_CRL&=0xFFFE; // 1S中斷標志清除

        if(IO_flag==0)//1S,LED閃爍一次

        {

        GPIO_PORTB_ODR|=(1<<5);

        IO_flag=1; // IO_flag為自己設的一個全局變量,用于LED取反

        }

        else {GPIO_PORTB_ODR&=~(1<<5);

        IO_flag=0;

        }

        }

        }

        int main()

        {

        SystemInit0();//系統(時鐘)初始化

        stm32_GpioSetup (); //GPIO初始化

        RTC_Configuration();//RTC配置

        while(1)

        {

        }

        }

        又搞定了一部分……




        關鍵詞: ARM學習STM32RTC調

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 方正县| 巴林左旗| 若尔盖县| 灵川县| 富宁县| 四子王旗| 金川县| 行唐县| 襄城县| 巩留县| 清徐县| 盖州市| 建阳市| 重庆市| 弥渡县| 屯昌县| 安岳县| 始兴县| 孟津县| 富裕县| 柯坪县| 邛崃市| 商丘市| 吕梁市| 门源| 桃源县| 常熟市| 新巴尔虎右旗| 武穴市| 通化市| 洛隆县| 宁海县| 葵青区| 宁乡县| 内丘县| 卢氏县| 雷州市| 永登县| 嘉兴市| 余姚市| 滁州市|