一、前言
1.1 功能介紹
在許多工業(yè)應(yīng)用、機(jī)械控制以及實(shí)驗(yàn)設(shè)備中,準(zhǔn)確測(cè)量和監(jiān)控信號(hào)的頻率或轉(zhuǎn)速是確保系統(tǒng)正常運(yùn)行、提高生產(chǎn)效率以及實(shí)現(xiàn)精確控制的關(guān)鍵。頻率作為信號(hào)的基本參數(shù)之一,直接反映了信號(hào)的變化速率,而轉(zhuǎn)速則通常通過測(cè)量旋轉(zhuǎn)物體的頻率來間接獲得。
為了實(shí)現(xiàn)對(duì)頻率和轉(zhuǎn)速的精確測(cè)量,本項(xiàng)目采用了STC90C51微控制器,結(jié)合定時(shí)器和外部中斷技術(shù),檢測(cè)NE555脈沖發(fā)生器產(chǎn)生的脈沖信號(hào)頻率。NE555作為一種廣泛使用的模擬定時(shí)器芯片,能夠通過配置外部電阻和電容參數(shù)產(chǎn)生穩(wěn)定的脈沖信號(hào),其頻率可根據(jù)需要進(jìn)行調(diào)整。因此,利用NE555脈沖發(fā)生器可以模擬不同頻率的輸入信號(hào),用于測(cè)試STC90C51的頻率測(cè)量功能。
在項(xiàng)目中,STC90C51微控制器通過定時(shí)器設(shè)置合適的計(jì)時(shí)周期,并利用外部中斷捕捉NE555脈沖信號(hào)的上升沿或下降沿。通過記錄定時(shí)器計(jì)數(shù)值和中斷觸發(fā)次數(shù),可以計(jì)算出輸入信號(hào)的頻率。此外,根據(jù)項(xiàng)目需求,還可以進(jìn)一步將頻率信息轉(zhuǎn)換為轉(zhuǎn)速值,實(shí)現(xiàn)轉(zhuǎn)速的精確測(cè)量和監(jiān)控。
本項(xiàng)目的開發(fā)背景體現(xiàn)了對(duì)精確頻率測(cè)量和轉(zhuǎn)速監(jiān)控技術(shù)的迫切需求。通過結(jié)合STC90C51微控制器和NE555脈沖發(fā)生器的技術(shù)優(yōu)勢(shì),本項(xiàng)目實(shí)現(xiàn)一種高效、精確的頻率和轉(zhuǎn)速測(cè)量系統(tǒng)。該系統(tǒng)不僅可以用于工業(yè)生產(chǎn)和機(jī)械控制等領(lǐng)域,還可以為科學(xué)實(shí)驗(yàn)和教學(xué)提供有力的支持。同時(shí),本項(xiàng)目的實(shí)施還將促進(jìn)微控制器和定時(shí)器技術(shù)在信號(hào)處理和控制領(lǐng)域的應(yīng)用和發(fā)展。
1.2 NE555介紹
NE555是一款經(jīng)典的集成電路,屬于555系列定時(shí)器芯片的一種型號(hào),在1971年由Signetics Corporation發(fā)布。作為一款多功能的定時(shí)器芯片,NE555在電子領(lǐng)域有著廣泛的應(yīng)用,包括脈沖信號(hào)發(fā)生、定時(shí)控制、波形產(chǎn)生等場(chǎng)景。
- 基本功能
- NE555可以作為一個(gè)脈沖發(fā)生器,通過外部電阻和電容的配置,產(chǎn)生穩(wěn)定的脈沖信號(hào)。
- 它還廣泛應(yīng)用于定時(shí)器、頻率計(jì)、脈寬調(diào)制(PWM)等電子電路中。
- 主要特點(diǎn)
- 工作原理
- 引腳功能
- NE555是8腳時(shí)基集成電路,各引腳功能包括地線、觸發(fā)點(diǎn)、輸出、重置、控制、重置鎖定、放電和正電源電壓端。這些引腳允許用戶通過外部電路配置來實(shí)現(xiàn)各種功能。
- 市場(chǎng)應(yīng)用由于其穩(wěn)定度高、精度高、溫度穩(wěn)定性好等優(yōu)點(diǎn),NE555在市場(chǎng)上非常受歡迎。主流品牌如TI、ST等都有生產(chǎn),并且廣泛應(yīng)用于各種電子設(shè)備中。
NE555是一款功能強(qiáng)大、設(shè)計(jì)簡(jiǎn)單、穩(wěn)定可靠的集成電路芯片,其作為脈沖發(fā)生器在電子領(lǐng)域有著廣泛的應(yīng)用,特別是在需要精確控制時(shí)間、頻率和脈沖寬度的場(chǎng)景中。
二、代碼實(shí)現(xiàn)
2.1 main.c
#include <reg51.h>
#include <INTRINS.H>
#include "delay.h"
#include "type.h"
#include "uart.h"
#include "ds1302.h"
#include "pcf8591.h"
//#include "key.h"
//#include "led.h"
#include "timer.h"
//#include "exti.h"
//#include "infrared.h"
//#include "ds18b20.h"
//#include "at24c02.h"
u32 time1_cnt=0; //記錄計(jì)數(shù)器1收到的外部脈沖數(shù)量
u32 time0_cnt=0; //記錄定時(shí)器0的超時(shí)時(shí)間次數(shù)
u32 Freq=0;
int main()
{
Timer0_16bit_Init(50000); //初始化定時(shí)器0,定時(shí)50ms一次
Timer1_16bit_CntMode_Init(); //初始化計(jì)數(shù)器1
while(1)
{
if(TR0==0) //當(dāng)定時(shí)器0停止時(shí),表示1秒鐘時(shí)間到達(dá)
{
Freq=time1_cnt+(TH1<<8|TL1); //得到1秒鐘內(nèi)計(jì)算的脈沖數(shù)
time1_cnt=0;//清除脈沖計(jì)數(shù)
TH1=0; //將計(jì)數(shù)器的值清零
TL1=0;
TR0=1; //開啟定時(shí)器0
TR1=1; //開啟計(jì)數(shù)器1
}
LED_DisplayNumber(Freq);
}
}
2.2 timer.c
#include "timer.h"
/*
配置定時(shí)器0工作在16位定時(shí)器模式
51單片機(jī)標(biāo)準(zhǔn)架構(gòu)下一個(gè)機(jī)器周期是 12個(gè)時(shí)鐘周期,也就是12/11059200秒。(11.059200是晶振頻率)
定時(shí)器每過一個(gè)機(jī)器周期的時(shí)間,也就是12/11059200秒,計(jì)數(shù)器自動(dòng)加1。
通過計(jì)算得知,定時(shí)器+1的時(shí)間: 12/11.059200=1.085069us
如果定時(shí)器工作在16位模式下,最大值可以存放:0~65535
那么最大的定時(shí)時(shí)間就可以得知:65535*1.085069=71,109.996915us=71.109996915ms
如果要定時(shí)1000us,那么公式:x*1.085069=1000 ->1000/1.085069=921 ,
通過公式,計(jì)算出定時(shí)器需要+921次剛好得到1000us。
但是單片機(jī)工作在16位模式情況下,需要加滿65535才能溢出,所以需要給定時(shí)器賦初值。
65535-921=64614,這樣定時(shí)器就可以從64614開始計(jì)數(shù),當(dāng)計(jì)數(shù)到65535時(shí),定時(shí)器就會(huì)溢出,
TF0就會(huì)置1,這時(shí)剛好經(jīng)過1000us時(shí)間。
那么定時(shí)器就可以這樣賦值:
u16 t0_data=64614;
TH0=t0_data>>8;
TL0=t0_data;
*/
u16 T0_Update_data;//定時(shí)器0的初始值
void Timer0_16bit_Init(u16 us)
{
//當(dāng)前實(shí)驗(yàn)板上的晶振實(shí)際頻率為: 12MHZ
u16 val=us/(12/12); //得到計(jì)數(shù)的時(shí)間,只要整數(shù)部分
T0_Update_data=65535-val; //得到重裝載值
TMOD&=0xF0; //清除配置
TMOD|=0x01; //配置定時(shí)器0工作在16位定時(shí)器模式
TH0=T0_Update_data>>8; //定時(shí)器0高位重裝值
TL0=T0_Update_data; //定時(shí)器0低位重裝值
EA=1; //開啟總中斷
ET0=1; //開啟定時(shí)器0溢出中斷
TR0=1; //開啟定時(shí)器0
}
//定時(shí)器0的重裝值更新函數(shù)
void Timer0_Update(void)
{
TH0=T0_Update_data>>8; //定時(shí)器0高位重裝值
TL0=T0_Update_data; //定時(shí)器0低位重裝值
}
u16 T1_Update_data;//定時(shí)器1的初始值
void Timer1_16bit_Init(u16 us)
{
//當(dāng)前實(shí)驗(yàn)板上的晶振實(shí)際頻率為: 11.956MHZ
u16 val=us/(12/11.956); //得到計(jì)數(shù)的時(shí)間,只要整數(shù)部分
T1_Update_data=65535-val; //得到重裝載值
TMOD&=0x0F; //清除配置
TMOD|=0x10; //配置定時(shí)器1工作在16位定時(shí)器模式
TH1=T1_Update_data>>8; //定時(shí)器1高位重裝值
TL1=T1_Update_data; //定時(shí)器1低位重裝值
EA=1; //開啟總中斷
ET1=1; //開啟定時(shí)器1溢出中斷
TR1=1; //啟動(dòng)定時(shí)器1
}
//定時(shí)器1的重裝值更新函數(shù)
void Timer1_Update(void)
{
TH1=T1_Update_data>>8; //定時(shí)器1高位重裝值
TL1=T1_Update_data; //定時(shí)器1低位重裝值
}
/*
配置定時(shí)器0工作在8位自動(dòng)重裝載模式
注意,時(shí)間不能超過定時(shí)器最大時(shí)間
255*(12/11.059200)=276us
*/
void Timer0_8bit_Init(u16 us)
{
//當(dāng)前實(shí)驗(yàn)板上的晶振實(shí)際頻率為: 11.956MHZ
u16 val=us/(12/11.956); //得到計(jì)數(shù)的時(shí)間,只要整數(shù)部分
TMOD&=0xF0; //清除配置
TMOD|=0x02; //配置定時(shí)器0工作在8位自動(dòng)重載模式
TL0=TH0=255-val;//得到重裝載值;
EA=1; //開啟總中斷
ET0=1; //開啟定時(shí)器0溢出中斷
TR0=1; //啟動(dòng)定時(shí)器0
}
/*
配置定時(shí)器1初始化為16位計(jì)數(shù)器模式
*/
void Timer1_16bit_CntMode_Init(void)
{
//當(dāng)前實(shí)驗(yàn)板上的晶振實(shí)際頻率為: 12MHZ
TMOD&=0x0F; //清除配置
TMOD|=0x50; //配置定時(shí)器1工作在16位計(jì)數(shù)器模式
EA=1; //開啟總中斷
ET1=1; //開啟定時(shí)器1溢出中斷
TR1=1; //啟動(dòng)定時(shí)器1
}
extern u32 time1_cnt; //記錄計(jì)數(shù)器1收到的外部脈沖數(shù)量
extern u32 time0_cnt; //記錄定時(shí)器0的超時(shí)時(shí)間次數(shù)
/*
定時(shí)器0的中斷服務(wù)函數(shù)
*/
void TIM0_IRQHandler(void) interrupt 1
{
time0_cnt++;
//定時(shí)器0配置50ms超時(shí)一次,超時(shí)次數(shù)到達(dá)20次表示1秒鐘時(shí)間到達(dá)
if(time0_cnt==20)
{
time0_cnt=0;
TR0=0; //關(guān)閉定時(shí)器0
TR1=0; //關(guān)閉計(jì)數(shù)器1
}
Timer0_Update(); //定時(shí)器0的重裝載
}
/*
定時(shí)器1的中斷服務(wù)函數(shù)
*/
void TIM1_IRQHandler(void) interrupt 3 //定時(shí)器1
{
//當(dāng)前計(jì)數(shù)器配置為16位模式,進(jìn)入一次中斷就表示計(jì)數(shù)了65536次
time1_cnt+=65536;
}
2.3 timer.h
#ifndef TIMER_H
#define TIMER_H
#include <reg51.h>
#include "delay.h"
#include "key.h"
#include "type.h"
#include "led.h"
#include "uart.h"
void Timer0_16bit_Init(u16 us);
void Timer0_Update(void);
void Timer1_16bit_Init(u16 us);
void Timer1_Update(void);
void Timer0_8bit_Init(u16 us);
void Timer1_16bit_CntMode_Init(void);
#endif