1.再遇多文件編程
因?yàn)?strong>定時(shí)器經(jīng)常在后面的教程中使用到,所以我們也把這部分功能代碼單獨(dú)使用文件封裝起來。
在第六章的教程中已經(jīng)教過大家多文件創(chuàng)建,這里點(diǎn)到為止。
創(chuàng)建好“timer.c”和“timer.h”
添加進(jìn)工程中
2.timer.c的代碼
#include <reg52.h> #include <function.h> //詳見第六章第8講 u8 T0RH,T0RL,T1RH,T1RL; void TIM0_Init(u32 us,int trim)//trim:微調(diào) { u32 tmp; //臨時(shí)變量 tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率 tmp = ( tmp * (us/100) )/10000; //計(jì)算所需的計(jì)數(shù)值 tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值 tmp = tmp+trim; //微調(diào)計(jì)數(shù)值使其定時(shí)更精確到我們想要的定時(shí)時(shí)間 T0RH = (unsigned char)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié) T0RL = (unsigned char)tmp; TMOD &= 0xF0; //清0低四位 TMOD |= 0x01; //設(shè)置定時(shí)器0為工作模式1 TH0 = T0RH; //加載T0重載值 TL0 = T0RL; ET0 = 1; //閉合定時(shí)器0中斷的開關(guān) TR0 = 1; //啟動(dòng)定時(shí)器0 } void TIM1_Init(u32 us,int trim)//trim:微調(diào) { u32 tmp; //臨時(shí)變量 tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率 tmp = ( tmp * (us/100) )/10000; //計(jì)算所需的計(jì)數(shù)值 tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值 tmp = tmp+trim; //微調(diào)計(jì)數(shù)值使其定時(shí)更精確到我們想要的定時(shí)時(shí)間 T1RH = (unsigned char)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié) T1RL = (unsigned char)tmp; TMOD&=0x0F;//清0高四位 TMOD|=0x10;//設(shè)置定時(shí)器1為工作模式1 TH1 = T1RH;//加載T1重載值 TL1 = T1RL; ET1 = 1; //閉合定時(shí)器1中斷的開關(guān) TR1 = 1; //啟動(dòng)定時(shí)器1 }
“TMOD&=0xF0;”的作用跟數(shù)碼管顯示小數(shù)點(diǎn)的代碼技巧一樣,保持前面4位的值不變,清0后四位,然后“TMOD|=0x01;”就是不改變?cè)瓉砀咚奈坏闹?,然后把低四位設(shè)成 0001。
如果在TIM0_Init()函數(shù)中只寫“TMOD=0x01;”
在TIM1_Init()函數(shù)中只寫“TMOD=0x10;”
然后初始化時(shí)像這樣按順序來寫
TIM0_Init(20000,20);//定時(shí)20ms,20微調(diào)使定時(shí)精度更高
TIM1_Init(50000,20);//定時(shí)50ms,20微調(diào)使定時(shí)精度更高
那么執(zhí)行TIM1_Init()的函數(shù)內(nèi)容時(shí)就會(huì)執(zhí)行“TMOD=0x10;”把人家低四位給清0了,原本想讓定時(shí)器0工作在模式1,現(xiàn)在低2位的值變了也就不是工作在模式1了。
所以“TMOD&=0x0F; TMOD|=0x10;”的寫法是不干涉互相的位。
我們定義了“T0RH,T0RL,T1RH,T1RL”四個(gè)8位的全局變量(R:reload)用來在中斷函數(shù)里重新賦值。
因?yàn)楣ぷ髂J?都是需要在中斷函數(shù)中重新賦初值,所以這四個(gè)變量是存取初始化時(shí)給THx和TLx的初值。
3.timer.h的代碼
#ifndef __TIMER_H__ #define __TIMER_H__ extern u8 T0RH,T0RL,T1RH,T1RL; void TIM0_Init(u32 us,int trim);//trim:微調(diào) void TIM1_Init(u32 us,int trim);//trim:微調(diào) #endif
4.main.c的代碼
這樣,實(shí)現(xiàn)間隔50ms的流水燈在書寫上就相當(dāng)簡(jiǎn)潔了
#include <reg52.h> #include <function.h> //詳見第六章第8講 #include <timer.h> void main() { LED_Init(); //初始化LED硬件模塊 EA = 1; //閉合總中斷開關(guān) TIM0_Init(50000,20);//用定時(shí)器0定時(shí)50ms,20是微調(diào)使中斷函數(shù)里的i均勻地50.00ms后自加,精度更高 while(1); } void TIM0_IRQHandler() interrupt 1 { static u8 i; TH0 = T0RH; //重新加載重載值 TL0 = T0RL; P0=~(0x01<<i); i++; if(i>=8)i=0; }
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個(gè)爬蟲的Python編程課程
只會(huì)語法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程