在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于AVR單片機(jī)的上下課自動(dòng)打鈴系統(tǒng)的實(shí)現(xiàn)

            基于AVR單片機(jī)的上下課自動(dòng)打鈴系統(tǒng)的實(shí)現(xiàn)

            作者: 時(shí)間:2016-11-30 來(lái)源:網(wǎng)絡(luò) 收藏
            簡(jiǎn)單說(shuō)明下:
            L1~L8對(duì)應(yīng)開發(fā)板上的8個(gè)LED;D2~D6對(duì)應(yīng)上面運(yùn)行圖上的那5個(gè)紅色“上課指示燈”;D1為一盞綠色的LED(運(yùn)行圖上注意點(diǎn)看,用透明膠包住的那個(gè)綠色LED),用于監(jiān)視程序是否在運(yùn)行(晶振是否起振,是否死機(jī));K1 K2用于選擇上午下午(上午有早讀,下午沒(méi)有)。繼電器不用說(shuō)了,控制門鈴開關(guān)用。
            下面放出源程序。(剛剛我已在程序中加入了很多注釋了,后面還是要做下解析):
            ————源程序(本程序版權(quán)歸李彥鋒所有)————
            #defineuchar unsigned char
            #defineuintunsigned int
            #defineulong unsigned long int
            volatile uint nowtime;//計(jì)時(shí)變量。然后下面的幾個(gè)變量是一些邏輯控制的
            volatile uint ledmode;
            volatile uint shangkeledmode;
            volatile uint shangkeledtime;
            volatile uint class;//上下課邏輯,上課為1,下課為0,見主函數(shù)

            #include
            #include

            void port_init(void)
            {
            DDRB=0xFF;
            PORTB=0x00;
            DDRC=0xFF;
            DDRA=0XFF;
            DDRD|=0XF0;
            //初始化IO口
            }


            void timer0_init(void)
            {

            TCCR0 = 0x00;
            TCNT0 = 0x06;
            OCR0= 0xFA;
            TCCR0 = 0x03;
            //初始化timer0
            }
            //timer0本系統(tǒng)中用于控制上下課指示燈閃爍
            #pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
            void timer0_ovf_isr(void)
            {
            tm0rsf();//別看漏
            TCNT0 = 0x06;
            }

            //TIMER1 initialize - prescale:256
            // WGM: 0) Normal, TOP=0xFFFF
            // desired value: 1Sec
            // actual value:1.000Sec (0.0%)
            void timer1_init(void)
            {
            TCCR1B = 0x00; //stop
            TCNT1H = 0x0B; //setup
            TCNT1L = 0xDC;
            OCR1AH = 0xF4;
            OCR1AL = 0x24;
            OCR1BH = 0xF4;
            OCR1BL = 0x24;
            ICR1H= 0xF4;
            ICR1L= 0x24;
            TCCR1A = 0x00;
            TCCR1B = 0x04;//start Timer
            //初始化timer1
            }

            //timer1本系統(tǒng)中用于上課時(shí)間和下課時(shí)間計(jì)時(shí)

            #pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
            void timer1_ovf_isr(void)
            {
            tm1rsf();//哈哈可能有人漏看了這里,回調(diào)函數(shù)執(zhí)行另一個(gè)函數(shù),這樣程序看起來(lái)更整潔,這是我的編程習(xí)慣^v^

            TCNT1H = 0x0B;
            TCNT1L = 0xDC;//重載高低值

            //timer1回調(diào)函數(shù)
            }


            void init_devices(void)
            {
            CLI();
            port_init();
            timer0_init();
            timer1_init();
            MCUCR = 0x00;
            GICR= 0x00;
            TIMSK = 0x05;
            SEI();
            }


            void delay(uint ms)//這個(gè)就不用說(shuō)了 死循環(huán)延遲
            {
            uint i,j;
            for(i=0;i {
            for (j=0;j<2300;j++);
            }
            }

            void tm0rsf()//控制上課指示燈閃爍的函數(shù),不喜歡寫在回調(diào)函數(shù)里,這樣程序看起來(lái)更工整。。。
            {

            if(class==1)//是否上下課,上課就閃,下課就不閃。
            {
            shangkeledtime++;
            if (shangkeledtime==150)//150ms閃一下。其他自己看吧。。。。
            {
            shangkeledtime=0;
            if(shangkeledmode==1)//開燈,相應(yīng)IO輸出高電平
            {
            PORTA|=0X54;
            PORTC|=0x02;
            PORTD|=0x20;
            shangkeledmode=0;
            }
            else//關(guān)燈,相應(yīng)IO輸出低電平(接地)
            {
            PORTA&=0X03;
            PORTC&=0xFC;
            PORTD&=0XDF;
            shangkeledmode=1;//邏輯自己看吧。。。。
            }
            }
            }
            else
            {
            PORTA&=0X03;
            PORTC&=0xFC;
            PORTD&=0XDF;
            }
            }

            void tm1rsf()//timer1回調(diào)函數(shù)執(zhí)行的函數(shù)
            {
            nowtime++;//計(jì)時(shí)變量自增
            if(ledmode==1)//嗯這個(gè)就是控制D0 LED閃爍的了,主要就是看timer1是不是在走。
            {
            ledmode=0;
            PORTA|=0x01;
            }
            else
            {
            ledmode=1;
            PORTA&=0XFE;
            }

            }

            void ring()//響鈴函數(shù),控制繼電器的。。(PC7輸出高電平)
            {
            PORTC=0xFF;//因?yàn)镻C口只有用到一個(gè)PC7所以不管這么多懶得算了直接全部輸出高電位
            delay(300);
            PORTC=0x00;
            delay(8300);
            PORTC=0xFF;
            delay(300);
            PORTC=0x00;
            delay(8300);
            }
            uchar key_press()//檢測(cè)K1K2是否按下。。
            {
            uchar j;
            DDRD|=0X0F;
            PORTD|=0X0F;

            DDRD&=0XF0;

            j=PIND;
            j=j&0X0F;
            if(j==0X0F)
            {
            return 0;
            }
            else
            {
            return 1;
            }

            }

            uchar key_scan()//檢測(cè)是K1還是K2按下。。
            {
            uchar key;
            delay(10);
            if(key_press())
            {
            key=PIND;
            key&=0X0F;
            switch(key)
            {
            case 0X0E:
            key=1;
            break;
            case 0X0D:
            key=2;
            break;
            default:
            key=0;
            }
            while(key_press());
            }
            else
            {
            key=16;
            }
            return key;
            }

            void main()//好了主函數(shù)開始了。。。
            {
            uchar i,j;
            uint k,mode;
            uint ledmode;
            init_devices();//初始化IO。。上面有。

            k=0;
            ledmode=1;//邏輯自己看,不用解釋。。。

            while(k==0)//注意了 這一段是上電后等待按下K1K2的。
            {
            if(ledmode==1)//上電后LED走馬燈在那狂閃(按下之前)
            {
            PORTB=0XF0;delay(80);
            ledmode=0;
            }
            else{PORTB=0X0F;delay(80);ledmode=1;}
            i=key_press();
            if(i)
            {//判斷按的哪個(gè)
            j=key_scan();
            if (j==1)
            {mode=1;k=1;}
            if (j==2)
            {mode=2;k=1;}
            }
            }


            if (mode==1)//如果按的K1,也就是早上用,有早讀的
            {
            uint overzaodu;
            uint canoverzaodu;
            overzaodu=0;
            canoverzaodu=0;
            PORTB=0XF3;//早讀上課時(shí)跑馬LED亮上面2盞(亮上面。。代表上午^v^)
            nowtime=0;
            class=1;
            while(canoverzaodu==0)
            {
            if (class==1)
            {
            if (nowtime==1200)//先上20分鐘的早讀
            {
            class=0;
            nowtime=0;
            overzaodu++;
            ring();//早讀下課打鈴
            }
            }
            else
            {

            if (nowtime==300)//早讀休息5分鐘,接下來(lái)自己看吧
            {


            class=1;
            nowtime=0;
            overzaodu++;
            ring();
            ring();
            PORTC=0xFF;
            delay(300);
            PORTC=0x00;
            }
            }
            if (overzaodu==1)

            {
            PORTB=0XF1;//早讀下課,LED多亮一盞
            }
            if (overzaodu==2)
            {
            canoverzaodu=1;
            PORTB=0XF0;//早讀結(jié)束,LED亮完上面4盞。。
            }//然后跳出早讀while,進(jìn)入到下面正常上課while--上課40分鐘,下課10分鐘,上課,下課…………無(wú)限循環(huán)。。。
            }
            }

            if (mode==2)//按下K2,也就是下午用的
            {
            PORTB=0X0F;
            class=1;//邏輯,上課為1下課為0
            ring();
            ring();
            PORTC=0xFF;
            delay(300);
            PORTC=0x00;//這都是打鈴用的。。上課比較吵,要打5遍。(一個(gè)ring打兩遍,兩個(gè)ring后直接在這里控制IO再打一遍)
            }

            nowtime=0;

            while(1)//正常上課while,這里就不解釋太多了,邏輯和上面早讀的差不多的

            {


            if (class==1)
            {
            if (nowtime==2400)//是否夠40分鐘
            {
            class=0;
            nowtime=0;//計(jì)時(shí)變量清零
            ring();//打鈴,下課打2遍就好了(一個(gè)ring兩遍,具體看上面ring函數(shù))
            }
            }
            else
            {
            if (nowtime==600)
            {


            class=1;
            nowtime=0;
            ring();
            ring();
            PORTC=0xFF;
            delay(300);
            PORTC=0x00;//上課打5遍鈴,其他就不解釋這么多了,邏輯一樣的自己看就行。
            }
            }
            }
            }
            ————源程序(本程序版權(quán)歸李彥鋒所有)————
            再簡(jiǎn)單說(shuō)下吧,程序中的邏輯就不說(shuō)了。
            1.點(diǎn)亮L1~L8為PB0~PB7輸出低電平(接地),因?yàn)槟穷^接的是VCC +5V的正電壓。
            2.PC7輸出高電位,繼電器B和C導(dǎo)通,接通門鈴,就響了。
            3.D1~D6我是直接把LED的正負(fù)接在IO口上的,所以輸出電位的時(shí)候一高一低。其實(shí)可以IO口上全接正然后統(tǒng)一接地,但是這樣麻煩,反正有足夠的IO口,就這么干了。
            附:最早是用內(nèi)部時(shí)鐘,然后后來(lái)跑不準(zhǔn),折騰了我一個(gè)星期,后來(lái)才發(fā)現(xiàn)是內(nèi)部時(shí)鐘的問(wèn)題,上了個(gè)晶振,解決問(wèn)題。。。
            好了就說(shuō)到這里,結(jié)束。
            上一頁(yè) 1 2 下一頁(yè)

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉