今天到電子市場找了一下,幾乎都是12.5p負(fù)載電容的32768晶振,只有一家有少量,負(fù)載電容是6p,20ppm的晶振要價(jià)是12.5p晶振的5倍,而且從外觀上也看不出來,也沒有測試方法能測出負(fù)載電容是6p還是12.5p。賣晶振的老板在這行干了10幾年,一說到6p的32768晶振就笑了。這個(gè)要求以前就有多個(gè)公司中過招,特別是DALLAS的片子,讓一家公司吃盡了苦頭,焊上的許多高精度12.5p晶振被迫全部換掉,訂的數(shù)萬只晶振也只能委托賣掉。老板說這種方式是IC廠家和大的晶振廠家聯(lián)合的一個(gè)小陰謀,因?yàn)橐郧?p的晶振只有很少幾個(gè)大廠家能做好,這樣可以幫助大晶振廠家形成壟斷。DALLAS的東西不敢恭維,向來賣得很貴,一片增強(qiáng)型的51經(jīng)常還要賣四五十。
6p的晶振既昂貴又不好采購,而且也難以辨認(rèn)和測試。STM32這樣設(shè)計(jì)實(shí)在是難以理喻。其它我們用過的所有涉及RTC的MCU和時(shí)鐘芯片都不存在這個(gè)問題,如三星的44B0,2410,2440,飛利浦的LPC213x,LP214x等等。
STM32是高度強(qiáng)調(diào)性價(jià)比的芯片,但是卻在RTC晶振上給中小客戶帶來很大不必要的麻煩,既增加成本和采購難度,又留下致命的隱患(RTC啟動(dòng)死機(jī))。特別是試樣和試生產(chǎn)階段,量又不大,怎么去專門訂做?
希望ST公司能正視這個(gè)問題,在以后的改進(jìn)中修正這個(gè)問題,能支持12.5p的常規(guī)32768晶振。
本文引用地址:
http://butianyuan.cn/article/201611/318953.htm調(diào)試了好長時(shí)間,我說怎么沒有反應(yīng),原來是因?yàn)榫д竦脑颍译娙荼仨毥?PF,我用的是15P的電容,等待晶振起振的時(shí)間特別長(1分鐘左右),開始我還以為是程序死在哪了呢!
后來程序是調(diào)通了,但是1S中斷特別不準(zhǔn),我相信一定是因?yàn)榫д窈碗娙莸脑?,先不管?zhǔn)不準(zhǔn),至少程序是調(diào)通了。把設(shè)置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;//電源接口時(shí)鐘使能,備份接口時(shí)鐘使能
PWR_CR|=0x00000100;//位8,允許訪問RTC寄存器和備份寄存器
RCC_APB1RSTR|=0x08000000;//位27 BKPRST備份接口復(fù)位
RCC_BDCR|=0x00000001;//位0 LSEON外部低速振蕩器使能
while(RCC_BDCR&0x00000002==0); //位1LSERDY外部低速振蕩器可用
RCC_BDCR|=0x00000100; //選擇LSE位RTC時(shí)鐘
RCC_BDCR|=0x00008000; //位15 RTCEN RTC時(shí)鐘使能
RTC_CRL|=0x10;//位4配置標(biāo)志,1:進(jìn)入配置模式
while(RTC_CRL&0x04==0);//位3 RSF:寄存器同步標(biāo)志
while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經(jīng)完成
RTC_CRH=0x01;//使能1S中斷
while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經(jīng)完成
RTC_PRLL=0xFF;//(1S中斷應(yīng)該是32767,但我的晶振不準(zhǔn),0xFF都是1S多)
while(RTC_CRL&0x20==0);//位5,在RTC寄存器上最近一次寫操作已經(jīng)完成
RTC_CRL&=0xFFEF;//位4,退出配置模式(開始更新RTC寄存器).
SETENA0|=0x00000008;//允許RTC中斷
}
RTC中斷處理函數(shù):
void RTC_IRQHandler(void)
{
if(RTC_CRL&0x01==1) //查詢1S中斷標(biāo)志
{
RTC_CRL&=0xFFFE; // 1S中斷標(biāo)志清除
if(IO_flag==0)//1S,LED閃爍一次
{
GPIO_PORTB_ODR|=(1<<5);
IO_flag=1; // IO_flag為自己設(shè)的一個(gè)全局變量,用于LED取反
}
else {GPIO_PORTB_ODR&=~(1<<5);
IO_flag=0;
}
}
}
int main()
{
SystemInit0();//系統(tǒng)(時(shí)鐘)初始化
stm32_GpioSetup (); //GPIO初始化
RTC_Configuration();//RTC配置
while(1)
{
}
}
又搞定了一部分……
評論