新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > AVR單片機(學習ing)-ATMEGA16的定時/計數器

        AVR單片機(學習ing)-ATMEGA16的定時/計數器

        作者: 時間:2016-11-27 來源:網絡 收藏
        初始化:


        然后是按下INT0:


        最后是按下S1:


        基本上就這點吧~~這里邊比較難理解的就是那個去取反的重定義!!!!再IAR工具的應用里會有介紹(就是持續更新的那個~~畢竟有很多要更新的~~)
        然后就是程序了~~
        //------------------------------------------------------------------------------
        //4位顯示秒表試驗
        //使用INT0鍵進行計時的開始和停止,使用S1鍵作為計時值得清除。定時器T0被用作掃描4
        //位數碼管(1ms),定時器T1則用來計時(10ms)
        #include"ioavr.h"
        #include"intrinsics.h"
        typedef unsigned char uchar;
        typedef unsigned intuint;
        __flash uchar seg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
        0x7c,0x39,0x5e,0x79,0x71};//共陰極數碼管
        __flash uchar act[4]={0xfe,0xfd,0xfb,0xf7};
        uintcnt;// 全局變量,計時值
        uchar flag_start;//全局變量,秒表啟動標志
        uchar i;//每次進入T0,對第i個數碼管刷新
        #define CPL_BIT(x,y)(x^=(1<//就是將x所對應的第y位取反
        #define s1(PIND&0X10)//對S1進行按鍵檢測的時候用到,如果檢測到,對cnt清0,你懂得why~~
        #define xtal8//由于這里用到的是8MHz的,所以定義為8,寫延時函數的時候會用到,回頭我會把IAR for AVR的精確延時寫到博客上~~
        //------------------------------------------------------------------------------
        //延時1ms的函數,沒有參數傳遞
        voiddelay_1ms()
        {
        uint i;
        for(i=1;i<(uint)(xtal*143-2);i++)
        ;
        }
        //------------------------------------------------------------------------------
        //延時nms的函數,有參數傳遞
        voiddelay_nms(uint n)
        {
        uint i=0;
        while(i {
        delay_1ms();
        i++;
        }
        }
        //------------------------------------------------------------------------------
        //端口定義函數,用來定義ABCD四個端口的輸入輸出
        voidport_init()
        {
        DDRA=0XFF;
        PORTA=0X00;
        DDRC=0XFF;
        PORTC=0XFF;
        DDRD=0X00;
        PORTD=0XFF;
        }
        //------------------------------------------------------------------------------
        //T0的初始化定義
        voidtimer0_init()
        {
        TCNT0=0X83;//1ms的定時初值
        TCCR0=0X03;//T0的計數預分頻取64,這就打開了T0的計數功能
        }
        //------------------------------------------------------------------------------
        //T1的初始化函數
        voidtimer1_init()
        {
        TCNT1H=0XD8;//10ms的定時初值
        TCNT1L=0XF0;
        }
        //------------------------------------------------------------------------------
        //按鍵檢測函數
        voidscan_s1()
        {
        if(s1==0)
        {
        delay_nms(10);
        if(s1==0)
        cnt=0;
        }
        }
        //------------------------------------------------------------------------------
        //芯片初始化函數,包含上面的所有初始化,以及沒有涉及的
        void device_init()
        {
        __disable_interrupt();//disable all interrupts,呵呵,不解釋都知道,SREG?這個我不知道在不在里面,從下面的來看應該在,回頭會具體分析的~~哈
        port_init();
        timer0_init();
        timer1_init();
        MCUCR=0X00;//INT0為低電平時產生中斷請求
        GICR=0X40;//使能INT0
        TIMSK=0X05;//使能T0和T1溢出中斷
        __enable_interrupt();//re-enable interrupts
        }
        //------------------------------------------------------------------------------
        //main
        voidmain()
        {
        device_init();
        while(1)
        {
        if(flag_start==0x01)
        TCCR1B=0X02;//如果啟動標志位為1,則啟動T1,計數預分頻取8
        if(flag_start==0x00)
        {
        TCCR1B=0X00;//相反,定時器標志位為0,則關閉T1,停止計數,檢測S1,如果按下,對cnt清0
        scan_s1();
        }
        }
        }
        //------------------------------------------------------------------------------
        //INT0
        #pragma vector=INT0_vect
        __interrupt voidint0()
        {
        CPL_BIT(flag_start,0);//取反啟動標志,這里對第0位取反
        delay_nms(10);
        }
        //------------------------------------------------------------------------------
        //TIMER0_OVF
        #pragma vector=TIMER0_OVF_vect
        __interrupt voidtimer0_ovf()
        {
        SREG=0X80;
        TCNT0=0X83;
        if(++i>3)
        i=0;
        switch(i)
        {
        case 0: PORTA=seg[cnt];PORTC=act[i];break;
        case 1: PORTA=seg[cnt0/10];PORTC=act[i];break;
        case 2: PORTA=seg[cnt00/100];PORTC=act[i];break;
        case 3: PORTA=seg[cnt/1000];PORTC=act[i];break;
        default: break;
        }
        }
        //------------------------------------------------------------------------------
        //TIMER1_OVF
        #pragma vector=TIMER1_OVF_vect
        __interrupt voidtimer1_ovf()
        {
        TCNT1H=0XD8;
        TCNT1L=0XF0;
        if(++cnt>999)
        cnt=0;
        }


        上一頁 1 2 3 4 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 炉霍县| 宁德市| 肇东市| 丹阳市| 嫩江县| 都安| 诏安县| 江西省| 鹤山市| 博乐市| 柳河县| 大足县| 利川市| 开江县| 洱源县| 区。| 柳河县| 汾阳市| 林芝县| 阳山县| 邵武市| 合作市| 江孜县| 大新县| 高邮市| 贺兰县| 莱阳市| 南和县| 临高县| 淳安县| 渝中区| 昌乐县| 礼泉县| 延吉市| 武鸣县| 阳西县| 志丹县| 南木林县| 泉州市| 来安县| 井冈山市|