蓝桥杯单片机555定时器频率测量 非常简单的教程 能直接运行
首先推薦B站小蜜蜂老師的視頻課程,講的蠻好,看完定時器前兩章再看555定時器模塊瞬間就悟了。
以上大概花費一個來小時,時間不夠或者是暫時比較急的話也可以將就看我下邊簡易版的內容.
原理簡介
原理其實非常簡單, 不過是把一個定時器配置成輸入捕獲模式, 這個模式每捕獲一個方波(通俗的說就是555定時器生成的方波通過線連到定時器上,定時器每收到一個上升沿或者下降沿之一,這個是看具體怎么配置的了)就會觸發一次中斷, 我們用一個變量(這里暫且叫它count)記錄中斷進去的次數,在中斷進入的時候計數值加1,即可知道收到了多少方波.
如果再使用一個定時器每一秒中斷一次,那么在中斷出來的時候看一下count的值,然后把它清零,下次再引入這里的時候,就知道1s內來了多少方波,進而知道了頻率.
再把它顯示在數碼管上,即可以看的到頻率了.
問題拆分
根據上述原理,問題大概分成下邊這么幾個.
1. 配置一個連接到NE555模塊的定時器使其為輸入捕獲模式.
2. 配置另一個定時器,使其能穩定在一段時間內產生中斷(如果是2毫秒中斷一次, 500次中斷的時間約為1秒).
3.?使用數碼管將結果展示.(想必大家學到NE555這里了也會用數碼管了,這里就不贅述數碼管的內容了)
問題解決
問題1解決:在下邊代碼的Timer0Init注釋中有簡單的解釋.
問題2解決: 在Timer0Init中有簡單的解釋
問題3解決: 在開始到set_tube函數前有簡單的解釋
#include <stc15f2k60s2.h> #define u8 unsigned char #define u16 unsigned int //作為一只菜鳥,顯然我是記不住那么多值的,所以把如何開關寫成了宏定義,這樣一般就不會忘了 #define led_ P2=(P2&0x1f)|0x80 //100|0 0000 #define select_duan_ P2=(P2&0x1f)|0xe0 //1110 #define select_wei_ P2=(P2&0x1f)|0xc0 //1100 #define y5_ P2=(P2&0x1f)|0xa0 #define close_ P2=(P2&0x1f) #define mie_ 10 //以下是共陽極數碼管0-9,滅對應的值 u8 code list[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; /*0 1 2 3 4 5 6 7 8 9 (mie_) */ //默認都是熄滅 u8 tube[]={mie_,mie_,mie_,mie_,mie_,mie_,mie_,mie_};u16 ne555,cnt,f=0;//這些是用得到的變量 f是頻率,ne555后邊會說到,cnt祖傳的計數用的值 //跟著學長學的祖傳的數碼管動態刷新的代碼, void digital_tube_display(){static u8 i=0;select_duan_;P0=0xff;close_;//消影select_duan_;P0=list[tube[i]];close_;//段選select_wei_;P0=1<<i;close_;//位選if(++i==8) i=0; } //這個函數用來改變每一個的值,因為我是菜鳥,所以我不會太花里胡哨的, //每次改哪個數值就set_tube(第幾個數碼管,要顯示的值),set_tube(第幾個數碼管,要顯示的值)... //這樣簡單也不怎么出錯,非常舒服 void set_tube(u8 idx,u8 num){tube[idx]=num; }//4+8=12 a b c d //這個定時器初始化是從軟件里復制的,要改的地方就兩個,空格空出來了 void Timer0Init(void) //100微秒@12.000MHz {AUXR |= 0x80; //定時器時鐘1T模式TMOD &= 0xF0; //設置定時器模式TMOD |=0x04; //可以是0x04 ,0x06 /*這個是讓他變成自動重裝載的計數的模式,作為一名菜鳥,我肯定不知道自動重裝載是啥,查了下 下邊有個TL0,TH0,他倆意思是time low 定時器0 time high 定時器0 很樸實, 就是定時器0的低八位,高八位,計數器模式下,來一個脈沖,低八位就加1,低八位加滿了高八位加, 都加滿了就溢出,進入中斷服務函數, 在很原始的時候,人類很難馴服野生的51單片機,這倆低八位高八位的加滿了就不知道咋辦了, 你看,這一次加滿了,得讓他回到初始值,才能一直只加這個數,不然就是亂加了,就不好用了 然后吧,原始的時候野生的單片機不會自己把那倆恢復到初始值,需要人類在他中斷進入中斷服務函數的時候 手動把那個恢復初始值,這個就是自動重裝載,字面意思。 */ //111111111 111111111 //000000000 000000000TL0 = 0xff; //設置定時初始值 TH0 = 0xff; //設置定時初始值 然后也可以這倆初值是0,直接算出高八位加第八位的值好像也許 /*設置成這樣給他兩個滿的,來一次脈沖他就溢出了,只要在中斷服務函數里邊讓他進一次就加1,等1秒鐘就知道他加了多少了*/TF0 = 0; //清除TF0標志TR0 = 1; //定時器0開始計時 }void Timer1Init(void) //1毫秒@12.000MHz {AUXR |= 0x40; //定時器時鐘1T模式TMOD &= 0x0F; //設置定時器模式TL1 = 0x20; //設置定時初始值TH1 = 0xD1; //設置定時初始值TF1 = 0; //清除TF1標志TR1 = 1; //定時器1開始計時 } /*set_up和loop是之前arduino里邊的老朋友了,作為一名菜鳥,我選擇最簡單的arduino入門, 這個還是對新手很友好的,推薦太極創客的教程,這個大家搜一下就搜得到了, setup就是初始化,loop就是主函數里的大循環*/ void set_up(){Timer0Init();Timer1Init();EA=1;ET1=1; ET0=1;//初始化定時器,打開各個中斷開關 } void loop(){if(cnt==1000){ // f=(TH0<<8)|TL0; // TL0=0;TH0=0;f=ne555;ne555=0;cnt=0;set_tube(3,f/10000%10);set_tube(4,f/1000%10);set_tube(5,f/100%10);set_tube(6,f/10%10);set_tube(7,f%10);} } //因為定時器0會打斷定時器1,為了盡力減少誤差,定時器里東西越少越好, //一般是放計數標志增加,還有就是一些很吃速度又跑得快的,比如說數碼管刷新 void time0() interrupt 1 { ne555++; } void time1() interrupt 3 {cnt++;digital_tube_display();}//錯把main寫成mian且沒看到,白白耽誤四小時,血虧,真的是血虧 //keil編輯器是不會提示主函數名字不對的,這對菜鳥就很不友好,像我就被這個折磨了四小時 void main(){set_up();while(1){loop();} }過去一年多自己回來留個言
這篇文章原本是基本上只有個代碼塊,啥都寫到注釋里去了.當時的我還是個歡樂的小菜鳥,這也是自己第一篇發出來的文章(雖然質量不怎么好).尤其記得當時發完博客高興了好久. 也就是從那個時候開始, 開始慢慢習慣用typora,開始配picgo圖床,開始積累自己的筆記. 這將近兩年磕磕絆絆走了不少路,一看到兩年前自己寫的內容,不免感慨萬千.感慨真要是寫下來大概能寫個半本書哈哈哈,這里就不啰嗦啦. 最后,祝各位前途似錦~
總結
以上是生活随笔為你收集整理的蓝桥杯单片机555定时器频率测量 非常简单的教程 能直接运行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS开发公开课总结
- 下一篇: OGC服务接口一张图