找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1741|回復(fù): 12
收起左側(cè)

單片機(jī)中斷定時(shí)為什么會(huì)晚?

[復(fù)制鏈接]
ID:1095802 發(fā)表于 2023-11-6 14:40 | 顯示全部樓層 |閱讀模式
11.0592的晶振定時(shí)10ms不是沒有誤差嗎,為什么寫的鐘表一天會(huì)慢幾分鐘,是因?yàn)橹袛喑绦蜻\(yùn)行時(shí)間過久,中斷時(shí)間到了前一個(gè)中斷還未出去而延遲嗎
單片機(jī)源程序如下:
#include <reg52.h>
#include <intrins.h>
#define Fosc 11.0592 //晶振頻率
#define FTime 10000  //中斷定時(shí)以us計(jì)
void main(void)
{
while(1);
}
void T0_Init(void)
{
        TMOD|=0x01;
        EA=1;
        ET0=1;
        TR0=1;
        TH0=(65536-FTime*Fosc/12)/256;
        TL0=(char)(65536-FTime*Fosc/12)%256;
}
void T0_Timer(void) interrupt 1
{
        TH0=(65536-FTime*Fosc/12)/256;
        TL0=(char)(65536-FTime*Fosc/12)%256;
}


回復(fù)

使用道具 舉報(bào)

ID:712097 發(fā)表于 2023-11-6 16:13 | 顯示全部樓層
單片機(jī)精度沒那么高,精度要求高的時(shí)鐘應(yīng)用,用專門的時(shí)鐘芯片如DS1302,PCF8563,DS3231等。
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2023-11-6 16:24 | 顯示全部樓層
chxelc 發(fā)表于 2023-11-6 16:13
單片機(jī)精度沒那么高,精度要求高的時(shí)鐘應(yīng)用,用專門的時(shí)鐘芯片如DS1302,PCF8563,DS3231等。

單片機(jī)內(nèi)部RC振蕩器穩(wěn)定性不行,但是11MHz AT-cut quartz精度要比DS1302、PCF8563用的fork quartz好太多了,這些RTC芯片優(yōu)點(diǎn)在于功耗低,掉電依然可以用電池來運(yùn)行,他們的精度根本不行,在高頻晶體面前就是個(gè)笑話。樓主如果用的是高頻晶體,可以修改軟件。當(dāng)然DS3231屬于TCXO,精度最高。
回復(fù)

使用道具 舉報(bào)

ID:220661 發(fā)表于 2023-11-6 16:27 | 顯示全部樓層
11.0592晶體做定時(shí)器生成1ms沒有誤差?記錯(cuò)了吧,那是做串口波特率沒有誤差,你用12M晶體試試吧?
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2023-11-6 17:15 | 顯示全部樓層
這種時(shí)鐘想要提高精度需要采取一點(diǎn)措施。改換12M或24M高品質(zhì)晶振,定時(shí)器采用自動(dòng)重裝模式,定時(shí)中斷周期盡可能短,建議不超過100uS。添加修正系數(shù)補(bǔ)償誤差。采取以上措施后可以將日誤差控制在1秒左右。
回復(fù)

使用道具 舉報(bào)

ID:1095802 發(fā)表于 2023-11-6 23:13 | 顯示全部樓層
gongnn 發(fā)表于 2023-11-6 16:27
11.0592晶體做定時(shí)器生成1ms沒有誤差?記錯(cuò)了吧,那是做串口波特率沒有誤差,你用12M晶體試試吧?

10ms寫錯(cuò)了,程序里是10000us
回復(fù)

使用道具 舉報(bào)

ID:277550 發(fā)表于 2023-11-7 09:51 | 顯示全部樓層

DS3231 還可以,只是比較貴
回復(fù)

使用道具 舉報(bào)

ID:485350 發(fā)表于 2023-11-29 11:51 | 顯示全部樓層
晶振誤差多少,中斷跳轉(zhuǎn),定時(shí)時(shí)間重載這些考慮進(jìn)去沒
回復(fù)

使用道具 舉報(bào)

ID:57657 發(fā)表于 2023-11-29 13:20 | 顯示全部樓層
仿真誤差大是程序有問題,實(shí)物誤差與晶振精度有關(guān),定時(shí)器要設(shè)置成自動(dòng)重載模式。
回復(fù)

使用道具 舉報(bào)

ID:397054 發(fā)表于 2023-11-29 14:47 | 顯示全部樓層
這是中斷模式1的工作機(jī)理引起的——從中斷申請的發(fā)出,到CPU響應(yīng),再到計(jì)算賦值完畢(主要是向TL賦值完畢),這是有時(shí)間的,這段時(shí)間遠(yuǎn)不為0,每個(gè)中斷都插入了這樣一段時(shí)間所以就慢了,這絕不是精度問題,因?yàn)?天要慢好幾分鐘的。尤其是你在中斷程序里還進(jìn)行了計(jì)算,這也很消耗時(shí)間,并且還把對TL的賦值放在了TH后,更增加了延時(shí)。解決這一問題的常規(guī)手法是在對TL賦值前讀出它的值,加在新值上賦給TL,并再加上2-5個(gè)修正值(可由實(shí)驗(yàn)確定),因?yàn)橘x值也要消耗時(shí)間的并且C是怎么編譯的我們也不知道。另一個(gè)更好的辦法是,調(diào)整中斷周期,使TL=0,這樣在中斷程序中可以不給TL賦值,只給TH賦值,使得計(jì)數(shù)不間斷,類似于中斷模式2,也就沒有了延時(shí)的產(chǎn)生。11.0592的晶振可以直接做到這點(diǎn)的,比如TH=180(即B4H),在中斷程序中刪掉TL的賦值語句,這樣的中斷計(jì)20次就是1秒。12兆的晶體做不到這點(diǎn)——算術(shù)問題,當(dāng)然非要這么做也可以,增加了程序的復(fù)雜性。
回復(fù)

使用道具 舉報(bào)

ID:397054 發(fā)表于 2023-11-29 15:02 | 顯示全部樓層
實(shí)際上你的這個(gè)程序已經(jīng)滿足了上貼的條件,即TL=0,所以在中斷程序中直接刪除賦值語句【TL0=(char)(65536-FTime*Fosc/12)%256;】即可,其他哪里都不用變,這個(gè)幾分鐘的誤差即可徹底消除,非常簡單的事。再有的誤差那就是元器件的精度引起的了,遠(yuǎn)不會(huì)超過1秒/天。那些說什么時(shí)鐘芯片的,都是想當(dāng)然。
回復(fù)

使用道具 舉報(bào)

ID:57657 發(fā)表于 2023-11-29 15:02 | 顯示全部樓層
鵜鶘 發(fā)表于 2023-11-29 14:47
這是中斷模式1的工作機(jī)理引起的——從中斷申請的發(fā)出,到CPU響應(yīng),再到計(jì)算賦值完畢(主要是向TL賦值完畢) ...

定時(shí)器設(shè)置為自動(dòng)重載初值模式,這段時(shí)間就為0,你設(shè)置10ms的定時(shí)器,定時(shí)器中斷內(nèi)停留不得超過10ms
回復(fù)

使用道具 舉報(bào)

ID:1073939 發(fā)表于 2023-11-29 17:20 | 顯示全部樓層
void T0_Timer(void) interrupt 1
{
        TH0=(65536-FTime*Fosc/12)/256;
        //TL0=(char)(65536-FTime*Fosc/12)%256;
}

代碼改成這樣能顯著提高走時(shí)精度。樓主這行畫蛇添足。
在早期沒有自動(dòng)重裝模式的單片機(jī),想要走時(shí)準(zhǔn)確,只能使用類似11.0592的晶振,這樣TL0的重裝值為0,也算間接實(shí)現(xiàn)了自動(dòng)重裝。
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表