/** File: timer0.c* Author: Sure*---------------系統功能:中斷 定時器0* Created on October 21, 2021, 7:48 PM*/// PIC16F15323 Configuration Bit Settings// -----------熔絲配置--------------// 'C' source line config statements// CONFIG1#pragmaconfig FEXTOSC = ECH // External Oscillator mode selection bits (EC above 8MHz; PFM set to high power)#pragmaconfig RSTOSC = EXT1X // Power-up default value for COSC bits (EXTOSC operating per FEXTOSC bits)#pragmaconfig CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)#pragmaconfig CSWEN = OFF // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)#pragmaconfig FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)// CONFIG2#pragmaconfig MCLRE = OFF // Master Clear Enable bit (MCLR pin is Master Clear function)#pragmaconfig PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)#pragmaconfig LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)#pragmaconfig BOREN = OFF // Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)#pragmaconfig BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)#pragmaconfig ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)#pragmaconfig PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)#pragmaconfig STVREN = OFF // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)// CONFIG3#pragmaconfig WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)#pragmaconfig WDTE = OFF // WDT operating mode (WDT enabled regardless of sleep; SWDTEN ignored)#pragmaconfig WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)#pragmaconfig WDTCCS = SC // WDT input clock selector (Software Control)// CONFIG4#pragmaconfig BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)#pragmaconfig BBEN = OFF // Boot Block Enable bit (Boot Block disabled)#pragmaconfig SAFEN = OFF // SAF Enable bit (SAF disabled)#pragmaconfig WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)#pragmaconfig WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)#pragmaconfig WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)#pragmaconfig WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)#pragmaconfig LVP = OFF // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)// CONFIG5#pragmaconfig CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#include<xc.h>//引用頭文件//#include"delay.h"//調用延時子函數/*-----------宏定義--------------*/#defineuintunsignedint#defineucharunsignedchar#defineV0RA0uint i;/*-----------子函數聲明--------------*//*-----------主函數--------------*/voidmain(void){// The corresponding data direction register is TRISA. // Setting a TRISA bit (= 1) will make the corresponding PORTA pi an input. // Clearing a TRISA bit (= 0) will make the corresponding PORTA pin an output. TRISA=0xfe;//設置數據方向 RA7-RA1為輸入,RA0為輸出// 1 = Port pin is > VIH,即高電平 ; 0 = Port pin is < VIL ,即低電平PORTA=0X00;//端口賦初值/********定時器TMR0初始化**********///The T0CS<2:0> bits of the T0CON1 register are used to select the clock source for Timer0. // Clock Source Selection: 010 = FOSC/4 T0CS2=0;//TMR0時鐘源選擇位,TMR0的時鐘源 選擇 內部指令周期(fosc/4)T0CS1=1;T0CS0=0;// There are 16 prescaler options for Timer0 ranging in powers of two from 1:1 to// 1:32768. The prescaler values are selected using the T0CKPS<3:0> bits of the T0CON1 register.T0CKPS3=0;// 預分頻 1:1 ,對應的編碼為0000T0CKPS2=0; T0CKPS1=0;T0CKPS0=0;// T0ASYNC: TMR0 Input Asynchronization Enable bit// 1 = The input to the TMR0 counter is not synchronized to system clocks// 0 = The input to the TMR0 counter is synchronized to FOSC/4T0ASYNC=0;// 同步時鐘模式// T016BIT : Timer0 Operating as 16-bit Timer Select bit// 1 = Timer0 is a 16-bit timer. 0 = Timer0 is an 8-bit timerT016BIT=1;// 計數寄存器16位// 2The Timer0 interrupt flag bit (TMR0IF) is set when either of the following conditions occur:// 8-bit TMR0L matches the TMR0H value. 16-bit TMR0 rolls over from ‘FFFFh’// The Timer1 module is a 16-bit timer/counter consisting of two 8-bit registers (TMR1H and TMR1L)// which are readable and writable. //16位計數寄存器給初值,在這里沒有考慮中斷所造成的時鐘延遲13個指令周期TMR0H=(65536-100)/256;// 定時100us*8(八分頻),計數寄存器就會溢出TMR0L=(65536-100)%256;// There are 16 postscaler options for Timer0 ranging from 1:1 to 1:16.// The postscaler values are selected using the T0OUTPS<3:0> bits of the T0CON0 register. T0OUTPS3=0;// 后分頻器 0000 = 1:1 PostscalerT0OUTPS2=0;T0OUTPS1=0;T0OUTPS0=0;// Timer0 Enable bit. 1 = The module is enabled and operating// 0 = The module is disabled and in the lowest power modeT0EN=1;// 打開定時器0// This overflow sets bit TMR0IF(T0IF). 通過T0IF=1,來說明計數寄存器溢出了TMR0IF=0;//TMR0的溢出中斷標志位 清零,從而計數寄存器滿的時候,T0IF產生一個上升沿。//If Timer0 interrupts are enabled (TMR0IE bit of the PIE0 register = 1), the CPU will be interrupted TMR0IE=1;// 打開定時器0的使能位//******************** 開全局中斷設置//定時器T0設置了中斷允許,此處要開全局中斷GIE=1;// 中斷總允許控制位 置一while(1)// 死循環,單片機初始化后,就一直運行這個死循環{}}/*************中斷服務程序***************/// void __interrupt(irq(TMR0,TMR1),base(0x100)) timerIsr(void)// 文檔里可以查到要用 void __interrupt() ISR(void) 的形式添加中斷程序//void interrupt ISR(void)//PIC單片機的所有中斷都是這樣一個入口void__interrupt()ISR(void)//PIC單片機的所有中斷都是這樣一個入口{// The TMR0 interrupt is generated(T0IF==1) when the TMR0 register overflows from FFFFh to 0000h.// 計數器寄存器由全1變為全0的時候,T0IF==1.if(TMR0IF==1)//需要進一步判斷是否為T0中斷 {//定時器中斷后,要重置初值,以備下次中斷TMR0H=(65536-100)/256; TMR0L=(65536-100)%256;// Bit TMR0IF must be cleared in software by the Timer0 module Interrupt Service Routine// before re-enabling this interrupt. 解釋了為什么要清零//溢出中斷標志位清零 只有T0IF出現上升沿,才會產生中斷,所以中斷發生之后要清零。 TMR0IF=0;// 執行中斷處理程序,也就是中斷產生了,我們想要執行什么功能if(++i>250)//2ms中斷一次,再計次250次后就是500ms{i=0;V0=!V0;// 取反 實現一秒的閃爍}}}