色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

51單片機定時器和中斷的介紹

科技綠洲 ? 來源:CSDN ? 作者:CSDN ? 2023-09-11 09:54 ? 次閱讀

最近在學習51單片機,學到了定時器這塊,由于自己的基礎不太扎實,在這方面花了很多時間,這里通過對定時器和中斷的介紹,用簡易時鐘這個例子來對學習的內容進行加深鞏固,把自己的經驗分享給大家,希望對大家能夠有幫助。

一、定時器的功能以及定時器的結構

定時器的功能

其實就是單片機的內部,通過系統時鐘的每一個機器周期產生一個記數脈沖,即每一個機器周期計數器加一。

比如,這里我的實驗板的晶振是12MHZ,1MHZ信號每個脈沖的持續時間為1us,如果定時器T0對1MHZ的信號進行計數,從0~65536us,當達到最大的65536us的時候,定時器計數達到最大值,會溢出,于是產生中斷信號,向中斷系統申請中斷,中斷系統接受中斷請求,執行中斷子程序。

定時器的結構

定時器的結構如下圖所示,主要包括

  • 兩個定時器/計數器。T0和T1,每個定時器/計數器都是由兩個8位的計數器所構成的16位計數器。
  • TCON 寄存器。TCON為控制寄存器,用來控制兩個定時器/計數器的啟動和停止。
  • TMOD寄存器。TMOD為工作方式控制寄存器,用來設置定時器/計數器的工作方式。

圖片

二、定時器的控制

工作模式寄存器TMOD

TMOD為工作方式控制寄存器,用來設置定時器/計數器的工作方式。如下圖所示。

通過配置TMOD寄存器來對定時器T0和T1的工作模式進行控制。

注意這里TMOD的地址為89H,不可位尋址。

TMOD的高四位用于T1,低四位用于T0。

其中主要各位的功能:

  • C/-T,定時器/計數器的選擇控制位。置0,為定時器模式,置1,為計數器模式。
  • M1和M0,模式選擇控制位,通過對兩位進行賦值,可以選擇定時器的4種模式。00,模式0,13位計數器。01,模式1,16位計數器。10,模式2,自動重裝8位計數器,11,模式3。
  • GATE,置1后,就可由TR0或TR1單獨控制定時器。

圖片

控制寄存器TCON

TCON寄存器,地址為88H,可以字節尋址,也可位尋址。寄存器各位如下圖所示。

其中各位的功能:

  • TF1(TF0)。定時器T1(T0)溢出標志位。當T1(T0)溢出時,硬件自動使TF1(TF0)置1,并且向cpu申請中斷。當Cpu響應中斷,進入中斷服務子程序后,TF1(TF0)由硬件自動清0,當然也可以用軟件寫代碼清0。
  • TR0(TR1)。定時器T1(T0)運行控制位,置1,定時器T1(T0)就開始運行,計數。
  • 后面幾個是外部中斷控制位。

圖片

寫代碼來初始化定時器

定時器的配置主要是通過對兩個寄存器TMOD和TCON進行配置,這里我通過配置定時器0,模式1引發中斷,配置其他的定時器或者是不同的模式都是大同小異。看看模式1的結構。

模式1的結構

圖片

好,我們首先來配置寄存器TMOD,根據圖來配置。

圖片

只需要配置定時器0,那么高四位就不管了,置0,而我們在控制定時器0的低四位中配置為0001。

GATE=0; //直接由TR0控制定時器0的開啟

C/-T=0; //選擇定時器模式

M1=0; //選擇模式1

M2=1;

繼續配置寄存器TCON。

圖片

只需要配置定時器0相關的部分就可以了,再一個,TCON寄存器是可位尋址的,所以只需要單獨對其中的某一位進行置值就可以了。

所以:

TF0=0; //定時器0溢出控制標志,當計數到溢出65536us時,就會置1。

TR0=1; //定時器0啟動,開啟計時。

配置中斷

當計數到溢出后,就會向cpu發出中斷請求,申請中斷,進入中斷子程序。然后出來,TF0由1->0,然后循環循環。

所以:

ET0=1; //中斷的配置

EA=1;

PT0=0;

三、定時器引發中斷

簡易時鐘

使用定時器,采用LCD1602,實現簡易時鐘,秒,分,時。

下面是源代碼:

主程序main.c

#include < REGX52.H >
#include "Delay.h"
#include "Timer0.h"
#include "LCD1602.h"
unsigned char sec=55,min=59,hour=23;
void main()
{
  LCD_Init();  //LCD初始化
  LCD_ShowString(1,1,"COLCK:");
  Timer0Init();  //定時器0初始化
  while(1)
  {
    LCD_ShowNum(2,1,hour,2); 
    LCD_ShowString(2,3,":");
    LCD_ShowNum(2,4,min,2);
    LCD_ShowString(2,6,":");
    LCD_ShowNum(2,7,sec,2);
  }
}




void TimerRoutine() interrupt 1
{
  static unsigned int T0Count;
  //當觸發中斷后,每次中斷結束后,初始值還是為64535 即1ms
  TL0 = 0x66;    //設置定時初值
  TH0 = 0xFC;    //設置定時初值
  T0Count++;
  if(T0Count >=1000)  //一次是1ms,*1000就是一秒    
  {
    T0Count=0;
    sec++;
    if(sec >=60)
    {
      sec=0;
      min++;
      if(min >=60)
      {
        min=0;
        hour++;
        if(hour >=24)
        {
          hour=0;
          sec=0;
          min=0;
        }
      }
    }
  }
}

延時函數Delay.c

//延時
void Delay(unsigned char xms)    //@11.0592MHz
{
  unsigned char i, j;


  while(xms--)
  {
    //_nop_();
  i = 2;
  j = 199;
  do
  {
    while (--j);
  } while (--i);
  }
}

控制LCD162模塊LCD1602.c

雖然還不怎么懂這個模塊,但是可以直接用,模塊都寫好了的。后面應該會弄懂各個函數功能如何實現。

#include < REGX52.H >


//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0


//函數定義:
/**
  * @brief  LCD1602延時函數,12MHz調用可延時1ms
  * @param  無
  * @retval 無
  */
void LCD_Delay()
{
  unsigned char i, j;


  i = 2;
  j = 239;
  do
  {
    while (--j);
  } while (--i);
}


/**
  * @brief  LCD1602寫命令
  * @param  Command 要寫入的命令
  * @retval 無
  */
void LCD_WriteCommand(unsigned char Command)
{
  LCD_RS=0;
  LCD_RW=0;
  LCD_DataPort=Command;
  LCD_EN=1;
  LCD_Delay();
  LCD_EN=0;
  LCD_Delay();
}


/**
  * @brief  LCD1602寫數據
  * @param  Data 要寫入的數據
  * @retval 無
  */
void LCD_WriteData(unsigned char Data)
{
  LCD_RS=1;
  LCD_RW=0;
  LCD_DataPort=Data;
  LCD_EN=1;
  LCD_Delay();
  LCD_EN=0;
  LCD_Delay();
}


/**
  * @brief  LCD1602設置光標位置
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @retval 無
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
  if(Line==1)
  {
    LCD_WriteCommand(0x80|(Column-1));
  }
  else if(Line==2)
  {
    LCD_WriteCommand(0x80|(Column-1+0x40));
  }
}


/**
  * @brief  LCD1602初始化函數
  * @param  無
  * @retval 無
  */
void LCD_Init()
{
  LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣
  LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關
  LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動
  LCD_WriteCommand(0x01);//光標復位,清屏
}


/**
  * @brief  在LCD1602指定位置上顯示一個字符
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @param  Char 要顯示的字符
  * @retval 無
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
  LCD_SetCursor(Line,Column);
  LCD_WriteData(Char);
}


/**
  * @brief  在LCD1602指定位置開始顯示所給字符串
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串
  * @retval 無
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
  unsigned char i;
  LCD_SetCursor(Line,Column);
  for(i=0;String[i]!='?';i++)
  {
    LCD_WriteData(String[i]);
  }
}


/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
  unsigned char i;
  int Result=1;
  for(i=0;i< Y;i++)
  {
    Result*=X;
  }
  return Result;
}


/**
  * @brief  在LCD1602指定位置開始顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~65535
  * @param  Length 要顯示數字的長度,范圍:1~5
  * @retval 無
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
  unsigned char i;
  LCD_SetCursor(Line,Column);
  for(i=Length;i >0;i--)
  {
    LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
  }
}


/**
  * @brief  在LCD1602指定位置開始以有符號十進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:-32768~32767
  * @param  Length 要顯示數字的長度,范圍:1~5
  * @retval 無
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
  unsigned char i;
  unsigned int Number1;
  LCD_SetCursor(Line,Column);
  if(Number >=0)
  {
    LCD_WriteData('+');
    Number1=Number;
  }
  else
  {
    LCD_WriteData('-');
    Number1=-Number;
  }
  for(i=Length;i >0;i--)
  {
    LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
  }
}


/**
  * @brief  在LCD1602指定位置開始以十六進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~0xFFFF
  * @param  Length 要顯示數字的長度,范圍:1~4
  * @retval 無
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
  unsigned char i,SingleNumber;
  LCD_SetCursor(Line,Column);
  for(i=Length;i >0;i--)
  {
    SingleNumber=Number/LCD_Pow(16,i-1)%16;
    if(SingleNumber< 10)
    {
      LCD_WriteData(SingleNumber+'0');
    }
    else
    {
      LCD_WriteData(SingleNumber-10+'A');
    }
  }
}


/**
  * @brief  在LCD1602指定位置開始以二進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~1111 1111 1111 1111
  * @param  Length 要顯示數字的長度,范圍:1~16
  * @retval 無
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
  unsigned char i;
  LCD_SetCursor(Line,Column);
  for(i=Length;i >0;i--)
  {
    LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
  }
}

定時器0模塊Timer0.c

主要是對定時器進行配置,看了視頻第一遍沒有聽懂,之后回頭再去看這個定時器,發現其實也沒有很難,只是自己的畏難情緒罷了。

別放棄,你可以弄明白的,只是心理在作祟。

#include < REGX52.H >


/**
  * @brief 定時器0初始化
  * @param  
  * @retval 
  */
void Timer0Init()
{
  TMOD&=0xF0;  //高四位不變
  TMOD|=0x01;  //設置定時器模式1 以及設置為定時方式 0
  
  TL0 = 0x66;    //設置定時初值
  TH0 = 0xFC;    //設置定時初值
  
  TF0=0;  //定時器0溢出標志位
  TR0=1;  //定時器0運行控制位
  
  TF0=1;  //設置外部中斷
  ET0=1;
  EA=1;
  PT0=0;
}

實現效果

如下圖。

圖片

自己卡著時間哈哈,還是慢了一秒。

圖片

總結

定時器的配置主要是通過配置,兩個寄存器TMOD和TCON。

在配置時,只要明確要配置的要求,一步一步來,也不難的喔!

明確要配置的是定時器還是計數器,是模式1還是模式幾。TCON寄存器TR0(TR1)置1,定時器啟動開始運行,和TF0(TF1),一般都是置0。

然后如果要配置中斷的話,根據外部中斷查看手冊來進行配置,一般也只需要配置幾個就可以了。

再者,一步一步好好學,沒有什么難的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 51單片機
    +關注

    關注

    274

    文章

    5705

    瀏覽量

    124059
  • 計數器
    +關注

    關注

    32

    文章

    2259

    瀏覽量

    94870
  • 中斷
    +關注

    關注

    5

    文章

    900

    瀏覽量

    41644
  • 定時器
    +關注

    關注

    23

    文章

    3255

    瀏覽量

    115169
收藏 人收藏

    評論

    相關推薦

    單片機定時器中斷應用案例

    定時器中斷,顧名思義就是在規定的時間內發送中斷請求,要實現定時器中斷單片機需要能夠正確地計算時
    發表于 10-31 14:49 ?2122次閱讀
    <b class='flag-5'>單片機</b><b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>應用案例

    基于51單片機定時器2的操作與實現

    基于51單片機定時器2的操作與實現,51單片機定時器2的使用!
    發表于 02-22 17:53 ?14次下載

    51單片機定時器T0的中斷使用法詳細說明

    本文檔的主要內容詳細介紹的是51單片機定時器T0的中斷使用法詳細說明程序免費下載。
    發表于 08-22 17:30 ?0次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>定時器</b>T0的<b class='flag-5'>中斷</b>使用法詳細說明

    STC51單片機中斷定時器進行配置的參考資料免費下載

    本文檔的主要內容詳細介紹的是STC51單片機中斷定時器進行配置的參考資料免費下載。
    發表于 08-19 17:31 ?5次下載
    STC<b class='flag-5'>51</b><b class='flag-5'>單片機</b>的<b class='flag-5'>中斷</b>與<b class='flag-5'>定時器</b>進行配置的參考資料免費下載

    51單片機的定義端口和定時器中斷與蜂鳴器報警程序等函數合集

    本文檔的主要內容詳細介紹的是51單片機的定義端口和全局變量及定時器中斷與蜂鳴器報警程序等函數合集免費下載。
    發表于 07-10 17:40 ?11次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>的定義端口和<b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>與蜂鳴器報警程序等函數合集

    51單片機中斷號和定時器的工作方式詳細說明

    本文檔的主要內容詳細介紹的是51單片機中斷號和定時器的工作方式詳細說明。
    發表于 06-28 17:42 ?5次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>的<b class='flag-5'>中斷</b>號和<b class='flag-5'>定時器</b>的工作方式詳細說明

    51單片機入門教程(5)——定時器中斷

    51單片機入門教程(5)——定時器中斷一、中斷的概念二、定時器
    發表于 11-11 14:51 ?11次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>入門教程(5)——<b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>

    51單片機——定時器

    51單片機——定時器為什么使用定時器定時器原理?定時器設置
    發表于 11-11 16:36 ?40次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>——<b class='flag-5'>定時器</b>

    51單片機定時器中斷

    定時器介紹:51單片機定時器屬于單片機的內部資源,其電路連接和運轉均在
    發表于 11-11 19:36 ?7次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>

    51單片機定時器中斷(數碼管讀秒+LED閃爍)

    51單片機兩種不同的定時器中斷程序實例關于51單片機定時器
    發表于 11-12 09:21 ?88次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>的<b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>(數碼管讀秒+LED閃爍)

    51單片機 中斷定時器

    51單片機,擁有兩個定時器,用來中斷計數,分別是T0和T1。而52單片機51
    發表于 11-12 10:51 ?14次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b> <b class='flag-5'>中斷</b>與<b class='flag-5'>定時器</b>

    51MCU】51單片機定時器中斷寫MIDI音樂(按鍵可切換音樂)

    51單片機定時器中斷寫MIDI音樂(按鍵可切換)
    發表于 11-12 13:36 ?21次下載
    【<b class='flag-5'>51</b>MCU】<b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>寫MIDI音樂(按鍵可切換音樂)

    51單片機定時器中斷

    定時器介紹:51單片機定時器屬于單片機的內部資源,其電路連接和運轉均在
    發表于 11-20 20:36 ?15次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>定時器</b><b class='flag-5'>中斷</b>

    51單片機:開啟中斷定時器

    51單片機:開啟中斷定時器關于中斷,需要用到中斷允許寄存
    發表于 11-22 12:06 ?12次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>:開啟<b class='flag-5'>中斷</b>和<b class='flag-5'>定時器</b>

    定時器中斷是什么意思,定時器中斷的工作原理

    定時器中斷是由單片機中的定時器溢出而申請的中斷51單片機
    的頭像 發表于 07-23 09:45 ?6306次閱讀
    主站蜘蛛池模板: 国产成人在线小视频| 日本调教网站| 中文无码热在线视频| 棉袜足j吐奶视频| 伧理片午夜伧理片| 亚洲国产精品免费观看| 美国caopo超碰在线视频| 丁香美女社区| 中文字幕亚洲无限码| 日韩一区二区三区精品| 亚洲精品国产拍在线观看 | 最近的2019中文字幕国语版| 日本19xxxx撤尿| 解开美女胸衣2破解版| 久久re6热在线视频精品| 中文字幕亚洲无线码高清不卡| 开心成人社区| 99久久国产露脸国语对白| 无码内射成人免费喷射| 蜜饯1V1高H-| 国产亚洲精品黑人粗大精选| 97成人精品视频在线播放| 午夜精品久久久久久影视riav| 捆绑调教网站| 国产色婷婷亚洲99精品| 手机在线观看mv网址| 久久这里只有精品国产精品99| 国产白浆视频在线播放| 91视频夜色| 夜月视频直播免费观看| 我的家庭女教师| 欧美亚洲天堂网| 久久久国产精品免费A片蜜臀| 国产国产乱老熟视频网站| 97视频久久| 孕妇泬出白浆18P| 亚洲AV无码一区二区三区乱子伦| 欧美一级做a爰片免费| 巨胸美女狂喷奶水www网麻豆| 国产亚洲精品AAAAAAA片| 大香伊蕉在人线国产97|