1.計數(shù)器的用途
直流有刷的電機,后面兩個一正一負的電接上,電機就可以轉
到底是轉子個幾個圈呢?
我們就可以在背后加裝這么一個碼盤,我們假設這里是有60個這個光電的一個孔對吧
那我們轉一圈是不是就可以一個軸上輸出60個這樣的脈沖,有遮擋就輸出1,無遮擋輸出0,
兩路交替,如果說這圈有60個脈沖,60個高低電平(總共幾個脈沖除60就是轉的圈數(shù))
本節(jié)利用開關,模擬計數(shù)器的功能。
編碼器也可以實現(xiàn)脈沖輸出,輸出波形:方波
流過了多少液體,中間有個比例變化。一高一低算一個脈沖。
只要輸出信號帶這種高低電平變化的,想要計算個數(shù)的就可以用計數(shù)器的功能
2.計數(shù)器的配置
當GATE=O(TMOD.7)時,如TR1=1,則定時器計數(shù)。GATE=1時,允許由外部輸入INT1控制定時器1,
這樣可實現(xiàn)脈寬測量。TR1為TCON寄存器內的控制位,TCON寄存器各位的具體功能描述見上節(jié)TCON寄存器的介紹。
當c/T=0時,多路開關連接到系統(tǒng)時鐘的分頻輸出,Tl對內部系統(tǒng)時鐘計數(shù),T1工作在定時方式
當C/T=1時,多路開關連接到外部脈沖輸入P3.5/T1,即 T1工作在計數(shù)方式。
STC單片機的定時器1有兩種計數(shù)速率:一種是12T模式,每12個時鐘加1,與傳統(tǒng)8051單片機相同;另外一種是1T模式,每個時鐘加1,速度是傳統(tǒng)8051單片機的12倍。T1的速率由特殊功能寄存器AUXR中的T1x12決定,如果T1x12=0,T1則工作在12T模式;如果T1x12=1,T1則工作在1T模式定時器1有兩個隱藏的寄存器RL_TH1和RL_TL1。RL_TH1與TH1共有同一個地址,RL_TL1與TL1共有同一個地址。當TRI=0即定時器/計數(shù)器Ⅰ被禁止工作時,對TLl寫入的內容會同時寫入RL_TLl,對
TH1寫入的內容也會同時寫入RL_TH1。當TR1=1即定時器/計數(shù)器Ⅰ被允許工作時,對TLl寫入內容,實際上不是寫入當前寄存器TL1中,而是寫入隱藏的寄存器RL_TL1中,對THl 寫入內容,實際上也不是寫入當前寄存器TH1中,而是寫入隱藏的寄存器RL_THl,這樣可以巧妙地實現(xiàn)16位重裝載定時器。當讀THl和TL1的內容時,所讀的內容就是TH1和TL1的內容,而不是RL_TH1和RL_TLl的內容。
當定時器1工作在模式1(TMOD[5:4][M1.MO]=00B)時,[THl,TL1l]的溢出不僅置位TF1,而且會自動將[RL_TH1,RL_TL1]的內容重新裝入[TH1,TL1]。
當T1CLKO/INT_CLKO.1=1時,P3.4/TO管腳配置為定時器1的時鐘輸出T1CLKO。輸出時鐘頻率為T1溢出率/2。
如果C/T=0,定時器/計數(shù)器T1對內部系統(tǒng)時鐘計數(shù),則:
T1工作在1T模式(AUXR.6/T1x12=1)時的輸出時鐘頻率=(SYsclk)(TM1PS+1)(65536-[RL_TH1,RL_TL1])/2T1工作在12T模式(AUXR.6/TIx12=0)時的輸出時鐘頻率=(SYSclk)(TM1PS+1)/12/(65536-[RL_TH1,RL_TLI])/2如果C/T=1,定時器/計數(shù)器T1是對外部脈沖輸入(P3.5/Tl)計數(shù),則:輸出時鐘頻率=(Tl_Pin_CLK)/(65536-[RL_TH1,RL_TL1])/2
Tl_C/T:Tl_C/T位寫1,控制定時器1用作定時器或計數(shù)器,清0則用作定時器(對內部系統(tǒng)時鐘進行計數(shù)),置1用作計數(shù)器(對引腳T1/P3.5外部脈沖進行計數(shù))。
Tl_GATE:控制定時器1,置1時只有在INT1腳為高及TRI控制位置1時才可打開定時器/計數(shù)器1。此處僅需要TR1計數(shù),故可以將Tl_GATE置0.
官方例程
設置TMOD = 0X40 =0100 0000 ,即Tl_C/T置1,用作計數(shù)。16位自動重載。
TL1 = 0xff; //1111 1111,65535,相當于再來1個脈沖,就可以進一下中斷,給引腳取反。每來一個脈沖,取反一次。
TH1 = 0xff;
開始
用按鈕模擬,松開是高電平,然后不斷的按下松開按下松開。
選用例程作為參考:
需要打開內部4K的上拉電阻打開,用到端口上拉電阻控制寄存器(PxPU):
STC-ISP軟件中有這個IO口的一個配置工具:
利用上一節(jié)的例程,改名為8.計數(shù)器,可以用T1來實現(xiàn)。
將void Timer0_Isr(void) interrupt 1屏蔽,調用T0中斷屏蔽,本節(jié)不需要。
按手冊上的例程順序編寫。
Tips:編譯時提示錯誤FILE DOES NOT EXIST:
C251 FATAL-ERROR -
ACTION: OPENING INPUT-FILE
FILE: \STC32\8.計勢鱘COMM\stc32g.h
ERROR: FILE DOES NOT EXIST
C251 TERMINATED.
這里涉及“附錄I關于Keil軟件中 0xFD問題的說明”。
Keil項目路徑名的字符中也不能含有帶OxFD編碼的漢字,否則Keil軟件會無法正確編譯此項目。故需要修改本工程的目錄名:
改為英文名:8.Count_T1,編譯正常通過,按鍵led循環(huán)亮滅。
課后可以試驗一下通過改變H1跟TL1的值,實現(xiàn)2下亮滅。
這個值的確定可以使用STC-ISP中的I/O口配置工具,高級配置,設置條件:
得到設置代碼: P3PU = 0x20;
3.計數(shù)器的應用
見2017年全國大學生電子設計競賽試題 ——直流電動機測速裝置(O題),題目如下
解題思路如下:
M法測速:又叫做頻率測量法。這種方法是在一個固定的定時時間內(以秒為單位),統(tǒng)計這段時間的編碼器脈沖數(shù),計算速度值。設編碼器單圈總脈沖數(shù)為C, 時間T0內,統(tǒng)計到的編碼器脈沖數(shù)為M0,則轉速n的計算公式為:
首先我們定義一個變量叫u16 Count_T1 = 0;初值設置為0。
改寫中斷處理函數(shù):void Timer0_Isr(void) interrupt 1:
void Timer0_Isr(void) interrupt 1 //1ms進來執(zhí)行一次,無需其他延時,重復賦值
{
TimCount++; //計算2000次=2s,可以一直運行
if(TimCount>= 2000)
{
TimCount = 0;
Count_T1 = (TH1 * 256) + TL1; //單位:轉/s,
TH1 = 0;
TL1 = 0;
Show_Tab[4] = TimCount/1000%10;
Show_Tab[5] = TimCount/100%10+10;
Show_Tab[6] = TimCount/10%10;
Show_Tab[7] = TimCount/1%10; //取10位
}
SEG_Fre(); //計算得到結果后,數(shù)碼管刷新
}
本例完整代碼:
#include "COMM/stc.h" //調用頭文件
#include "COMM/usb.h"
#define KEY1 P32 //定義一個按鍵 引腳選擇P32
#define KEY2 P33 //定義一個按鍵 引腳選擇P33
#define BEEP P54 //定義一個按鍵 引腳選擇P54
#define SEG_Delay 1 //延時多少ms
#define MAIN_Fosc 24000000UL //定義主時鐘
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff}; //0-9段碼,0-9帶小數(shù)點
u8 COM_Tab[8] = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe }; //0-7的位碼數(shù)組
u8 Show_Tab[8] = {20,20,20,20,0,0,0,0};
u32 TimCount = 0; //計數(shù)單位1ms
bit RUN_State = 0; //開始運行/結束運行
u8 num = 0;
u16 Count_T1 = 0;
void sys_init(); //函數(shù)聲明
void delay_ms(u16 ms); //unsigned int
void SEG_Fre( void )
{
//位碼選擇第一位,段碼選擇0
P7 = COM_Tab[num]; //位碼的選擇
P6 = SEG_Tab[Show_Tab[num]];//需要顯示的數(shù)字的內碼 賦給 P6 NUM =0 -> Show_Tab[num]] = 1 -> p6 = oxF9
//delay_ms(SEG_Delay);
num++;
if( num >7 )
num = 0;
}
//========================================================================
// 函數(shù)名稱: Timer0_Init
// 函數(shù)功能: 定時器0初始化
// 入口參數(shù): 無
// 函數(shù)返回: 無
// 當前版本: VER1.0
// 修改日期: 2023
// 當前作者:
// 其他備注:
//========================================================================
void Timer0_Init(void) //1毫秒@24.000MHz
{
AUXR &= 0x7F; //定時器時鐘12T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0x30; //設置定時初始值
TH0 = 0xF8; //設置定時初始值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
ET0 = 1; //使能定時器0中斷
}
void main() //程序開始運行的入口
{
sys_init(); //USB功能+IO口初始化
usb_init(); //usb庫初始化
TMOD = 0x50; //設置計數(shù)器模式
TL1 = 0x00; //設置計數(shù)初始值
TH1 = 0x00; //設置計數(shù)初始值
TF1 = 0; //清除TF1標志
TR1 = 1; //定時器1開始計時
ET1 = 1; //使能定時器1中斷
P3PU = 0x20; //打開內部上拉4.1K
Timer0_Init();
EA = 1; //CPU開放中斷,打開總中斷。
while(1) //死循環(huán)
{
if( DeviceState != DEVSTATE_CONFIGURED ) //
continue;
if( bUsbOutReady )
{
usb_OUT_done();
}
}
}
void Timer0_Isr(void) interrupt 1
{
TimCount++; //每隔1ms+1 // 計數(shù)到2000 = 2s
if( TimCount>=2000 ) //2秒定時時間到了
{
TimCount = 0;
Count_T1 = (TH1 *256 )+ TL1; // 轉/2s 轉/min
TH1 = 0;
TL1 = 0;
Show_Tab[4] = Count_T1/1000%10;
Show_Tab[5] = Count_T1/100%10;
Show_Tab[6] = Count_T1/10%10;
Show_Tab[7] = Count_T1/1%10; //取10位
}
SEG_Fre(); //數(shù)碼管刷新的
}
void Timer1_Isr(void) interrupt 3
{
}
/*
11111110 0XFE
11111101 0XFD
11111011 0XFB
11110111 0XF7
11101111 0XEF
11011111 0XDF
10111111 0XBF
01111111 0X7F
*/
void sys_init() //函數(shù)定義
{
WTST = 0; //設置程序指令延時參數(shù),賦值為0可將CPU執(zhí)行指令的速度設置為最快
EAXFR = 1; //擴展寄存器(XFR)訪問使能
CKCON = 0; //提高訪問XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //設置為準雙向口
P1M1 = 0x00; P1M0 = 0x00; //設置為準雙向口
P2M1 = 0x00; P2M0 = 0x00; //設置為準雙向口
P3M1 = 0x00; P3M0 = 0x00; //設置為準雙向口
P4M1 = 0x00; P4M0 = 0x00; //設置為準雙向口
P5M1 = 0x00; P5M0 = 0x00; //設置為準雙向口
P6M1 = 0x00; P6M0 = 0x00; //設置為準雙向口
P7M1 = 0x00; P7M0 = 0x00; //設置為準雙向口
P3M0 = 0x00;
P3M1 = 0x00;
P3M0 &= ~0x03;
P3M1 |= 0x03;
//設置USB使用的時鐘源
IRC48MCR = 0x80; //使能內部48M高速IRC
while (!(IRC48MCR & 0x01)); //等待時鐘穩(wěn)定
USBCLK = 0x00; //使用CDC功能需要使用這兩行,HID功能禁用這兩行。
USBCON = 0x90;
}
void delay_ms(u16 ms) //unsigned int
{
u16 i;
do
{
i = MAIN_Fosc/6000;
while(--i);
}while(--ms);
}
總結
了解計數(shù)器的使用方法和應用場景文章來源:http://www.zghlxwxcb.cn/news/detail-697197.html
課后練習:
嘗試實現(xiàn)T法測速:又叫做周期測量法。這種方法是建立一個已知頻率的高頻脈沖并對其計數(shù),計數(shù)時間由捕獲到的編碼器相鄰兩個脈沖的間隔時間TE決定, 計數(shù)值為M1。設編碼器單圈總脈沖數(shù)為C,高頻脈沖的頻率為F0,則轉速n的計算公式為:文章來源地址http://www.zghlxwxcb.cn/news/detail-697197.html
到了這里,關于學習筆記|計數(shù)器|Keil軟件中 0xFD問題|I/O口配置|STC32G單片機視頻開發(fā)教程(沖哥)|第十二集:計數(shù)器的作用和意義的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!