介紹了美國Dallas公司推出的低功耗時鐘器件DS3231的結構和工作原理,DS3231能對年、月、日、時、分、秒計時,且具有溫度補償、閏年補償等多種功能。給出了AVR單片機ATmega8與DS3231的軟、硬件接口設計。
由單片機構成的測控系統或智能顯示屏經常需要用到實時日歷或時鐘信號。為節省CPU資源,本文節紹了串行時鐘器件DS3231的應用及其與AVR單片機ATmega8的接口,該系統具有抗干擾能力強,計時準確且不隨季節變化產生誤差的特點。
1.3231的組成及工作原理
如圖1所示,DS3231的主要組成部分有8個模塊,劃分為4個功能組:TCXO、電源控制、按鈕復位和RTC。
DS3231是低成本、高精度I2C實時時鐘(RTC)器件,具有集成的溫度補償晶體振蕩器(TCXO)。該器件包含電池輸入端,斷開主電源時仍可保持精確計時。集成的晶體振蕩器可提高器件的長期精確度。DS3231的寄存器能保存秒、分、時、星期、日期、月、年和鬧鐘設置等信息。少于31天的月份,可自動調整月末日期,包括閏年補償。DS3231提供兩個可編程日歷鬧鐘和一路可編程方波輸出。地址與數據通過I2C雙向串行總線傳輸。
時鐘和日歷 RTC
可以通過讀取適當的寄存器字節獲得時鐘和日歷信息。通過寫入適當的寄存器字節設定或者初始化時鐘和日歷數據。時鐘和日歷寄存器的內容采用二-十進制編碼(BCD)格式。DS3231運行于12小時或者24小時模式。小時寄存器的第6位定義為12或24小時模式選擇位。該位為高時,選擇12小時模式。在12小時模式下,第5位為AM/PM指示位,邏輯高時為PM。
32 kHz的TCXO
TCXO包括溫度傳感器、振蕩器和控制邏輯。控制器讀取片上溫度傳感器輸出,使用查表法確定所需的電容,加上AGE寄存器的老化修正。然后設置電容選擇寄存器。僅在溫度變化或者用戶啟動的溫度轉換完成時,才加載包括AGE寄存器變化的新值。VCC初次上電時就會讀取溫度值,然后每隔64 s讀取一次。
電源控制
電源控制功能由溫度補償電壓基準(VPF)和監視VCC電平的比較器電路提供。當VCC高于VPF時,DS3231由VCC供電,當VCC低于VPF但高于VBAT時,DS3231由VCC供電;當VCC低于VPF并低于VBAT時,DS3231由VBAT供電。為保護電池,VBAT首次加到器件時振蕩器并不啟動,除非加載VCC,或者向器件寫入一個有效的I2C地址。典型的振蕩器啟動時間在1 s以內。在VCC加電后或者有效的I2C地址寫入后大約2 s,器件會測量一次溫度,并使用計算的修正值校準振蕩器。一旦振蕩器運行,只要電源(VCC或者VBAT)有效就會一直保持工作狀態。器件每隔64 s進行一次溫度測量并校準振蕩器頻率。
按鈕復位
DS3231具有連接至RST輸出引腳的按鈕開關功能。若DS3231不在復位周期,會持續監視RST信號的下降沿。如果檢測到一個邊沿轉換,DS3231通過拉低RST完成開關去抖。內部定時器定時結束后,DS3231繼續監視RST信號。如果信號依舊保持低電平,DS3231持續監視信號線以檢測上升沿。一旦檢測到按鈕釋放,DS3231強制RST為低電平并保持tRST。RST還可用于指示電源故障報警情況。當VCC低于VPF時,產生內部電源故障報警信號,并強制拉低RST引腳。當VCC返回至超過VPF電平時。RST保持低電平大約250 ms(tREC),使供電電源達到穩定。如果在VCC加載時,振蕩器不工作,將跳過tREC,RST立刻變為高電平。
鬧鐘
DS3231包含2個定時/日期鬧鐘。鬧鐘1可通過寫入寄存器07h~0Ah設定。鬧鐘2可通過寫入寄存器0Bh~0Dh設定??蓪︳[鐘進行編程(通過控制寄存器的鬧鐘使能位和INTCN位),從而在鬧鐘匹配條件下觸發INT/SQW輸出。每個定時/日期鬧鐘寄存器的第7位是屏蔽位。當每個鬧鐘的屏蔽位均為邏輯0時,只有當計時寄存器中的值與存儲于定時/日期鬧鐘寄存器中的對應值相匹配時才會告警。鬧鐘也可以編程為每秒、分、時、星期或日期重復告警。當RTC寄存器值與鬧鐘寄存器的設定值相匹配時,相應的鬧鐘標志位A1F或A2F置為邏輯1。如果對應的鬧鐘中斷使能位A1IE或A2IE也置為邏輯1,并且INTCN位置為邏輯1,鬧鐘條件將會觸發INT/SQW信號。RTC在時間和日期寄存器每秒更新時都會檢測匹配情況。
2 DS3231的數據交換及其格式
DS3231通過I2C總線的雙向數據線SDA和時鐘線SCL與外界進行數據交換。DS3231在I2C總線上作為從器件。I2C主機通過執行START命令并且在驗證器件地址后才可以訪問DS3231,然后DS3231的寄存器可以被訪問直到執行一個STOP命令為止。DS3231有兩種操作方式:寫操作和讀操作。DS3231的地址固定為1101 000。
3. DS3231與AVR單片機的硬件接口
Atmega系列單片機片內集成2線制串行接口模塊,Atmel稱其為TWI接口。事實上,TWI與Philips的I2C總線是一回事。AVR硬件實現的TWI接口是面向字節和基于中斷的,相對軟件模擬I2C總線有更好的實時性和代碼效率,引腳輸入部分還具有毛刺抑制單元,可去除高頻干擾。圖3是DS3231與AVR單片機ATmega8的硬件接口電路原理圖。
軟件設計中,首先要對AVR單片機ATmega8與實時鐘器件DS3231進行初始化,給DS3231準確的日期和時間。不論主控模式還是被控模式,都應當將TWI控制寄存器TWCR的TWEN位置為1,從而使能TWI模塊。TWEN位被置位后,I/O引腳PC5和PC4轉換成SCL和SDA,對TWI控制寄存器TWCR的操作可在總線上產生START和STOP信號。對TWI模塊的操作均為寄存器的讀寫操作,Avr-libc沒有提供專門的API。
下面的程序是DS3231與AVR單片機接口部分代碼
#define SLA 0xD0
/*I2C總線主機模式錯誤處理*/
void error(unsigned char type) {
switch (type & 0xF8) {
case 0x20: /*址址寫失敗*/
/*stop 停止*/
TWCR = (1 《《 TWINT) | (1 《《 TWEN) | (1 《《 TWSTO);
break;
case 0x30: /*數據寫失敗*/
/*stop 停止*/
TWCR = (1 《《 TWINT) | (1 《《 TWEN) | (1 《《 TWSTO);
break;
case 0x38: /*仲裁失敗*/
TWCR=(1《《TWINT)|(1《《TWEN)|(1《《TWEA);
break;
case 0x48: /*址址讀失敗*/
/*stop 停止*/
TWCR = (1 《《 TWINT) | (1 《《 TWEN) | (1 《《 TWSTO);
break;
}
}
/*I2C總線多字節寫入
*n為需寫入字節數
*addr為DS3231的寄存器地址
*數組dd中為需寫入數據。
*注意,數組dd中的數據必須是BCD編碼格式
*/
unsigned char twi_ds_write(unsigned char addr,
unsigned char dd[],int n) {
int i;
TWBR = 2;
/*start 啟動*/
TWCR = (1 《《 TWINT)| (1 《《 TWSTA)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x08) {
error(TWSR);
return 0;
}
/*SLA_W芯片地址*/
TWDR = SLA;
TWCR = (1 《《 TWINT) | (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8) != 0x18) {
error(TWSR);
return 0;
}
/*addr 操作地址*/
TWDR = addr;
TWCR = (1 《《 TWINT) | (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8) != 0x28) {
error(TWSR);
return 0;
}
/*dd 寫入second,minute等數據*/
for(i=0;i《n;i++)
{
TWDR = dd[i];
TWCR = (1 《《 TWINT)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x28) {
error(TWSR);
return 0;
}
}
/*stop 停止*/
TWCR = (1 《《 TWINT) | (1《《TWEA)|(1 《《 TWEN) | (1 《《
TWSTO);
return 1;
}
/*I2C總線多字節讀取
*addr為DS3231寄存器起始地址,數組dd存放讀取的n字節數據
*/
unsigned char twi_ds_read(unsigned char addr, unsigned char dd[],int
n) {
int i;
TWBR = 2;
/*start 啟動*/
TWCR=(1《《TWINT)|(1《《TWSTA)|(1《《TWEN);
while(?。═WCR&(1《《TWINT)));
if ((TWSR & 0xF8) != 0x08) {
error(TWSR);
return 0;
}
/*SLA_W芯片地址*/
TWDR = SLA;
TWCR = (1 《《 TWINT) | (1 《《 TWEN);
while(?。═W R & ( 《《 TWINT)));
if((TWSR & xF ) != x ) {
error(TWSR);
return 0;
}
/*addr 操作地址*/
TWDR = addr;
TWCR = (1 《《 TWINT)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x28) {
error(TWSR);
return 0;
}
/*start 啟動*/
TWCR = (1 《《 TWINT)| (1 《《 TWSTA)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x10) {
error(TWSR);
return 0;
}
/*SLA_R 芯片地址*/
TWDR = SLA+1;
TWCR = (1 《《 TWINT)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x40) {
error(TWSR);
return 0;
}
/*讀取前n-1個數據*/
for(i=0;i《n-1;i++)
{
TWCR = (1 《《 TWINT)|(1《《TWEA)|(1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8) != 0x50) {
error(TWSR);
return 0;
}
dd[i] = TWDR;
}
/*讀取第n個數據*/
TWCR = (1 《《 TWINT)| (1 《《 TWEN);
while (?。═WCR & (1 《《 TWINT)));
if ((TWSR & 0xF8)!= 0x58) {
error(TWSR);
return 0;
}
dd[n-1] = TWDR;
/*stop 停止*/
TWCR = (1 《《 TWINT)|(1《《TWEA) | (1 《《 TWSTO) | (1 《《
TWEN);
return 1;
}
選用實時時鐘器件DS3 3 和 VR單片機 T 設計了一個日歷時鐘系統,該系統體積小,通用性強。DS3231具有集成的溫度補償晶體振蕩器(TCXO),計時準確且不隨季節的變化而產生誤差。該系統適用于智能顯示屏以及實時測控系統。
評論
查看更多