久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3542|回復: 3
收起左側

基于pic16f1947的所有定時器 timer0/timer1/timer2/timer4/timer6驅動程序

[復制鏈接]
ID:511543 發表于 2020-12-25 11:23 | 顯示全部樓層 |閱讀模式
之所以把pic16f1947單片機的所有定時器發給大家,也是因為我在開發之前也找過這方面的資源,但是很少,所以只能去研究寄存器,最終都搭建成功,分享給大家,避免少走彎路。本人已經毫無保留分享給大家了。謝謝。

單片機源程序如下:
///////////////////// 頭文件///////////////////////
#ifndef     __TIMER_H
#define    __TIMER_H

#include   "datatype.h"
#include   "pic.h"                        //PIC16F IC寄存器定義文件

//#define   TIMER0        //如果不使用TIMER0,請用//注釋掉
#ifdef  TIMER0
extern  uint16_t   timer0_count  ;
void Timer0_Init(void);//定時器0初始化
#endif

//#define   TIMER1        //如果不使用TIMER1,請用//注釋掉
#ifdef  TIMER1
extern  uint16_t   timer1_count  ;
void Timer1_Init(void);//定時器1初始化
#endif

#define   TIMER2        //如果不使用TIMER2,請用//注釋掉
#ifdef  TIMER2
extern  uint16_t   timer2_count  ;
void Timer2_Init(void);//定時器2初始化
#endif

//#define   TIMER4        //如果不使用TIMER4,請用//注釋掉
#ifdef  TIMER4
extern  uint16_t   timer4_count  ;
void Timer4_Init(void);//定時器2初始化
#endif

//#define   TIMER6        //如果不使用TIMER6,請用//注釋掉
#ifdef  TIMER6
extern  uint16_t   timer6_count  ;
void Timer6_Init(void);//定時器2初始化
#endif

#endif


//////////////////////// 對應的.c 文件 ////////////////////////////////////
#include   "timer.h"

#ifdef  TIMER0
uint16_t   timer0_count = 0 ;
/*
*@brief                timer0初始化
*@prama        None
*@retval        Value
      預分頻器分頻
    PS2   PS1   PS0
     0        0      0     --2分頻
     0        0      1     --4分頻
     0        1      0     --8分頻
     0        1      1     --16分頻
     1        0      0     --32分頻
     1        0      1     --64分頻
     1        1      0     --128分頻
     1        1      1     --256分頻
     timer0 定時計算:
    如果FOSC = 16,內部指令周期時鐘 CLK =(FOSC /4)=4MHz,  1/CLK =0.25us
    如果FOSC = 64,內部指令周期時鐘 CLK =(FOSC /4)=16MHz, 1/CLK =0.0625us
    需要定時間=255*預分頻器分頻數*(1/CLK) us
    即是:        63.75us*                   15.9375us*
                      FOSC = 16               FOSC = 64  
      2分頻 ---    127.5us                   31.875us        
      4分頻 ---       255us                   63.75us
      8分頻 ---       510us                   127.5us
     16分頻 ---    1020us                    255us
     32分頻 ---    2040us                    510us
     64分頻 ---    4080us                    1020us   
   128分頻 ---    8160us                    2040us
   256分頻 ---  16320us                    4080us
   */
void Timer0_Init(void)
{
         //這里選擇2.04ms 周期
        TMR0CS=0;         //1-T0CKI 引腳上信號的跳變,0 = 內部指令周期時鐘(FOSC /4)
        TMR0SE=0;  //1 = 在 T0CKI 引腳電平發生由高到低的跳變時遞增,0 = 在 T0CKI 引腳電平發生由低到高的跳變時遞增
        //預分頻128
        if( SYSTEMCLK == 64 ) //64M-128分頻
        {
                PS2=1;                                
                PS1=1;
                PS0=0;
        }
        else//16M-32分頻
        {
              PS2=1;                                
                PS1=0;
                PS0=0;
        }
               
        PSA=0;                                //1 = 不將預分頻器分配給 Timer0 模塊,0 = 將預分頻器分配給 Timer0 模塊
        TMR0IF=0;                        //清除timer0中斷標志位
        TMR0IE=1;                        //開啟timer0中斷
        PEIE=1;                                //開啟外設中斷
        GIE=1;                                //開啟全局中斷
}
#endif



#ifdef   TIMER1
uint16_t   timer1_count = 0 ;
/*
*@brief                timer1始化
*@prama        None
*@retval        Value
      時鐘源選擇
   TMR1CS1      TMR1CS0       T1OSCEN
      0                   1                      x          ---系統時鐘 (FOSC )
      0                   0                      x          ---指令時鐘 (FOSC /4)
      1                   1                      x          ---電容觸摸傳感振蕩器
      1                   0                      0         ---T1CKI 引腳上的外部時鐘
      1                   0                      1         ---T1OSI/T1OSO 引腳上的振蕩器電路
      時鐘分頻因子                                         使能選擇
      T1CKPS1     T1CKPS0                          TMR1ON           TMR1GE
          1               1      --8分頻                      0                         0            --關閉
          1               0      --4分頻                      0                         1            --關閉
          0               1      --2分頻                      1                         0            --時鐘開啟
          0               0      --1分頻                      1                         1            --使能計數

     定時計算:
    如果FOSC = 16,內部指令周期時鐘 CLK =(FOSC /4)=4MHz,  1/CLK =0.25us
    如果FOSC = 64,內部指令周期時鐘 CLK =(FOSC /4)=16MHz, 1/CLK =0.0625us
    需要定時間=(count)*預分頻器分頻數*(1/CLK) us  1ms時,count=500,10ms時,cout=5000
    重轉載值 = 65535-count
    下面是定時1ms.
*/
void Timer1_Init(void)
{
        //時鐘源選擇:指令時鐘 (FOSC /4)
        TMR1CS1 = 0 ;
        TMR1CS0 = 0 ;        
       T1OSCEN =0 ;                        //禁止Timer1振蕩器電路

       //TIMER1 :時鐘開啟
        TMR1ON = 1 ;               
        TMR1GE  = 0 ;        
        
        //分頻因子:8分頻        
        T1CKPS1=1;
        T1CKPS0=1;        

       //重裝載值
       if( SYSTEMCLK == 64 ) //64M
       {
                TMR1H=0xF8;                        //0xF830
                TMR1L=0x30;
        }
        else
        {
                TMR1H=0xFE;                        //0xFE07
                TMR1L=0x0C;
        }
        
        TMR1IF=0;                        //清除TMR1計數溢出標志位清零
        TMR1IE=1;                        //使能TMR1中斷
        PEIE=1;                                //開啟外設中斷
        GIE=1;                                //開啟全局中斷
}

#endif


#ifdef   TIMER2
uint16_t   timer2_count = 0 ;
/*
*@brief                timer1始化
*@prama        None
*@retval        Value
T2CON:bit6~bit3                         bit1~bit0
                        1111 = 1:16 后分頻比      11 = 預分頻值為 64
                        1110 = 1:15 后分頻比      10 = 預分頻值為 16
                        1101 = 1:14 后分頻比      01 = 預分頻值為 4
                        1100 = 1:13 后分頻比      00 = 預分頻值為 1
                        1011 = 1:12 后分頻比
                        1010 = 1:11 后分頻比
                        1001 = 1:10 后分頻比
                        1000 = 1:9 后分頻比
                        0111 = 1:8 后分頻比
                        0110 = 1:7 后分頻比
                        0101 = 1:6 后分頻比
                        0100 = 1:5 后分頻比
                        0011 = 1:4 后分頻比
                        0010 = 1:3 后分頻比
                        0001 = 1:2 后分頻比
                        0000 = 1:1 后分頻比
    定時計算:
    如果FOSC = 16,內部指令周期時鐘 CLK =(FOSC /4)=4MHz,  1/CLK =0.25us
    如果FOSC = 64,內部指令周期時鐘 CLK =(FOSC /4)=16MHz, 1/CLK =0.0625us
    需要定時間=(count)*預分頻*后分頻*(1/CLK) us   100*4*10*0.25 =1ms   100*16*10*0.0625=1ms
*/
void Timer2_Init(void)
{
        
        if( SYSTEMCLK == 64 ) //64M
        {
                      T2CON=0b01001010;        //預分頻4,后分頻10
               PR2=100;
          }
          else
          {
                     T2CON=0b01001001;        //預分頻4,后分頻10
               PR2=100;
          }

        TMR2ON=1;             //使能TMR2定時器,開始計數        bit2
        TMR2IF=0;       //清空定時器2中斷標志位
        TMR2IE=1;       //開啟定時器2中斷
        PEIE=1;            //開啟外設中斷
        GIE=1;             //開啟總中斷
}
#endif

#ifdef   TIMER4
uint16_t   timer4_count = 0 ;
/*
*@brief                timer1始化
*@prama        None
*@retval        Value
T2CON:bit6~bit3                         bit1~bit0
                        1111 = 1:16 后分頻比      11 = 預分頻值為 64
                        1110 = 1:15 后分頻比      10 = 預分頻值為 16
                        1101 = 1:14 后分頻比      01 = 預分頻值為 4
                        1100 = 1:13 后分頻比      00 = 預分頻值為 1
                        1011 = 1:12 后分頻比
                        1010 = 1:11 后分頻比
                        1001 = 1:10 后分頻比
                        1000 = 1:9 后分頻比
                        0111 = 1:8 后分頻比
                        0110 = 1:7 后分頻比
                        0101 = 1:6 后分頻比
                        0100 = 1:5 后分頻比
                        0011 = 1:4 后分頻比
                        0010 = 1:3 后分頻比
                        0001 = 1:2 后分頻比
                        0000 = 1:1 后分頻比
    定時計算:
    如果FOSC = 16,內部指令周期時鐘 CLK =(FOSC /4)=4MHz,  1/CLK =0.25us
    如果FOSC = 64,內部指令周期時鐘 CLK =(FOSC /4)=16MHz, 1/CLK =0.0625us
    需要定時間=(count)*預分頻*后分頻*(1/CLK) us   100*4*10*0.25 =1ms   100*16*10*0.0625=1ms
*/
void Timer4_Init(void)
{
        
        if( SYSTEMCLK == 64 ) //64M
        {
                      T4CON=0b01001010;        //預分頻4,后分頻10
               PR4=100;
          }
          else
          {
                     T4CON=0b01001001;        //預分頻4,后分頻10
               PR4=100;
          }

        TMR4ON=1;             //使能TMR2定時器,開始計數        bit2
        TMR4IF=0;       //清空定時器2中斷標志位
        TMR4IE=1;       //開啟定時器2中斷
        PEIE=1;            //開啟外設中斷
        GIE=1;             //開啟總中斷
}
#endif


#ifdef   TIMER6
uint16_t   timer6_count = 0 ;
/*
*@brief                timer1始化
*@prama        None
*@retval        Value
T2CON:bit6~bit3                         bit1~bit0
                        1111 = 1:16 后分頻比      11 = 預分頻值為 64
                        1110 = 1:15 后分頻比      10 = 預分頻值為 16
                        1101 = 1:14 后分頻比      01 = 預分頻值為 4
                        1100 = 1:13 后分頻比      00 = 預分頻值為 1
                        1011 = 1:12 后分頻比
                        1010 = 1:11 后分頻比
                        1001 = 1:10 后分頻比
                        1000 = 1:9 后分頻比
                        0111 = 1:8 后分頻比
                        0110 = 1:7 后分頻比
                        0101 = 1:6 后分頻比
                        0100 = 1:5 后分頻比
                        0011 = 1:4 后分頻比
                        0010 = 1:3 后分頻比
                        0001 = 1:2 后分頻比
                        0000 = 1:1 后分頻比
    定時計算:
    如果FOSC = 16,內部指令周期時鐘 CLK =(FOSC /4)=4MHz,  1/CLK =0.25us
    如果FOSC = 64,內部指令周期時鐘 CLK =(FOSC /4)=16MHz, 1/CLK =0.0625us
    需要定時間=(count)*預分頻*后分頻*(1/CLK) us   100*4*10*0.25 =1ms   100*16*10*0.0625=1ms
*/
void Timer6_Init(void)
{
        
        if( SYSTEMCLK == 64 ) //64M
        {
                      T6CON=0b01001010;        //預分頻4,后分頻10
               PR6=100;
          }
          else
          {
                     T6CON=0b01001001;        //預分頻4,后分頻10
               PR6=100;
          }

        TMR6ON=1;             //使能TMR2定時器,開始計數        bit2
        TMR6IF=0;       //清空定時器2中斷標志位
        TMR6IE=1;       //開啟定時器2中斷
        PEIE=1;            //開啟外設中斷
        GIE=1;             //開啟總中斷
}
#endif


//測試文件/////////////////////////////
//#define    PLLx4TO64M        //PLL*4 倍頻設置時鐘為64M,不需要倍頻為64M//注釋掉即可,這時為16M

#ifdef      PLLx4TO64M
#define   SYSTEMCLK    64
#else
#define   SYSTEMCLK    16
#endif


#ifdef   PLLx4TO64M
__CONFIG( FOSC_HS  & WDTE_OFF & BOREN_OFF );        //配置字一,選擇外部振蕩器,關閉看門狗,關閉低電壓復位
__CONFIG( VCAPEN_ON & LVP_OFF& PLLEN_ON );        //配置字二,使能RF0引腳穩壓電容,關閉低電壓編程,打開時鐘4倍頻
#else
__CONFIG( FOSC_HS  & WDTE_OFF & BOREN_OFF );        //配置字一,選擇外部振蕩器,關閉看門狗,關閉低電壓復位
__CONFIG( VCAPEN_ON & LVP_OFF& PLLEN_OFF );        //配置字二,使能RF0引腳穩壓電容,關閉低電壓編程,關閉時鐘4倍頻
#endif

void main(void)
{

        //Timer0_Init();                   //定時器0初始化
        //Timer1_Init();                   //定時器1初始化
        //Timer2_Init();                   //定時器2初始化
        //Timer4_Init();                   //定時器4初始化
        //Timer6_Init();                   //定時器4初始化
        while(1)
      {

   ;}
}

中斷處理函數
void interrupt  ISR(void)        
{

            //定時器0中斷測試
        #ifdef TIMER0
        {
             if(  TMR0IE && TMR0IF )
             {
                      TMR0IF=0;
                      timer0_count ++;
                      if(timer0_count%300==0)        //2.04ms*300=612ms到
                    {
                                LED^=1;                              //LED1狀態取反
                      }
              }
        }
        #endif      
        
        //定時器1中斷測試
        #ifdef TIMER1
        {
                if(TMR1IE&&TMR1IF)
                {
                        TMR1IF=0;
                        TMR1ON=0;
                        //重裝載值
                       if( SYSTEMCLK == 64 ) //64M
                       {
                                 TMR1H=0xF8;                        //0xF830
                               TMR1L=0x30;
                        }
                        else
                        {
                                TMR1H=0xFE;                        //0xFE07
                                TMR1L=0x0C;
                        }
                        TMR1ON=1;
                        
                        timer1_count++;
                        if(timer1_count%1000==0)                //500ms到
                        {
                         printf("1\r\n");
                                LED^=1;                        //LED1狀態取反
                        }
                }
        }
        #endif        
        
        //定時器2中斷測試
        #ifdef TIMER2
        {
                  if(TMR2IE&&TMR2IF)
                 {
                        TMR2IF=0;        
                        timer2_count++;
                        if(timer2_count%200==0)                //50ms到
                        {
                                 printf("1\r\n");
                                        LED^=1;                        //LED1狀態取反
                        }
                 }
        }
        #endif
        
        //定時器4中斷測試
        #ifdef TIMER4
        {
                  if(TMR4IE&&TMR4IF)
                 {
                        TMR4IF=0;        
                        timer4_count++;
                        if(timer4_count%1000==0)                //500ms到
                        {
                                 printf("1\r\n");
                                        LED^=1;                        //LED1狀態取反
                        }
                 }
        }
        #endif
        
        //定時器6中斷測試
        #ifdef TIMER6
        {
                  if(TMR6IE&&TMR6IF)
                 {
                        TMR6IF=0;        
                        timer6_count++;
                        if(timer6_count%1000==0)                //500ms到
                        {
                                 printf("1\r\n");
                                        LED^=1;                        //LED1狀態取反
                        }
                 }
        }
        #endif
}


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:759020 發表于 2021-1-20 16:54 | 顯示全部樓層
很受用,謝謝
回復

使用道具 舉報

ID:385637 發表于 2021-3-26 14:10 | 顯示全部樓層
很實用的好資料
回復

使用道具 舉報

ID:635055 發表于 2024-11-20 15:51 | 顯示全部樓層
很實用的好資料
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲女人天堂成人av在线 | 华人黄网站大全 | 日本不卡视频在线播放 | 中文字幕视频在线看5 | 国产精品视频网址 | www.三级| 亚洲 中文 欧美 日韩 在线观看 | 日韩电影在线一区 | 夜夜爽99久久国产综合精品女不卡 | 国产免费一区二区三区 | 超碰婷婷| 国产成人高清视频 | 欧美日韩视频在线第一区 | 国产精品不卡一区二区三区 | av电影一区二区 | 国产在线视频一区 | 99热这里| 91在线视频观看免费 | 亚洲综合日韩精品欧美综合区 | 午夜精品一区 | 日韩av中文 | 国产色| a在线观看 | 久久一区二区三区四区 | 亚洲免费大片 | 亚洲欧洲精品成人久久奇米网 | 成人在线视频免费看 | www.99热这里只有精品 | 视频一区二区中文字幕日韩 | xx视频在线观看 | 国产精品久久久久久久久久久久久 | 久久激情视频 | 成人激情视频免费观看 | 日韩精品久久久久 | 久操伊人| 在线播放国产一区二区三区 | 国产一区在线免费 | 久久性色| 亚洲福利 | 国产一级免费视频 | 亚洲精品在线看 |