在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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>

            新聞中心

            uart 中斷 緩沖區(qū)

            作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
            在CVAVR系統(tǒng)提供的標(biāo)準(zhǔn)庫(kù)函數(shù)stdio.h中,提供了getchar()函數(shù),該函數(shù)是采用輪詢方式從USART接收數(shù)據(jù)的,輪詢方式不僅效率低,而且會(huì)丟失數(shù)據(jù),不能實(shí)現(xiàn)多任務(wù)的并行處理。

            CVAVR程序向?qū)е薪o出的采用中斷+緩沖的方式接受數(shù)據(jù),同PC的串口接受數(shù)據(jù)的方法一樣,充分利用了AVR的高速和RAM多的優(yōu)點(diǎn),體現(xiàn)出了如何才能充分發(fā)揮AVR的特點(diǎn)的程序設(shè)計(jì)思想,這種思路在32位系統(tǒng)中也是這樣的。

            使用AVR的話,對(duì)軟件的設(shè)計(jì)能力要求更高了,否則根本不能發(fā)揮和體現(xiàn)AVR的特點(diǎn)。許多人有了一點(diǎn)C的基礎(chǔ),就認(rèn)為采用C編寫(xiě)單片機(jī)程序沒(méi)問(wèn)題,很快就會(huì)掌握AVR了,對(duì)此我只能一笑了之??纯幢菊旧媳姸嗟拇a,再看看本貼的遭遇,能說(shuō)什么呢?

            回到本題:
            注1:
            如果在程序的開(kāi)頭部分加上語(yǔ)句
            #define_DEBUG_TERMINAL_IO_
            那么程序在編譯時(shí)仍使用系統(tǒng)自己的getchar()函數(shù),這樣在軟件模擬仿真時(shí),可以從模擬的終端讀取數(shù)據(jù),便于在軟件模擬環(huán)境中調(diào)試整個(gè)系統(tǒng),而需要正式運(yùn)行時(shí),則把該句注釋掉。
            注2:
            此處在正式應(yīng)用中應(yīng)根據(jù)實(shí)際情況做適當(dāng)?shù)男薷?。否則當(dāng)主程序調(diào)用getchar()時(shí),如果緩沖隊(duì)列中沒(méi)有數(shù)據(jù),同時(shí)對(duì)方也沒(méi)有發(fā)數(shù)據(jù)的情況時(shí),程序會(huì)在此死循環(huán)。
            比較簡(jiǎn)單的辦法是將這句刪掉,而在調(diào)用getchar()函數(shù)前先判斷rx_counter的值,為0的話就不調(diào)用了。
            或改為:
            signedintgetchar(void)
            {
            signedintdata;
            if(rx_counter==0)
            {
            data=-1;
            }
            else
            {
            data=rx_buffer[rx_rd_index];//讀取緩沖隊(duì)列中的數(shù)據(jù)
            if(++rx_rd_index==RX_BUFFER_SIZE)rx_rd_index=0;//讀取指針指向下一個(gè)未讀的數(shù)據(jù),如果指到了隊(duì)列尾部,則指回到隊(duì)列頭步
            #asm("cli")//關(guān)中斷!非常重要
            --rx_counter;//隊(duì)列中未讀數(shù)據(jù)個(gè)數(shù)減1。因?yàn)樵撟兞吭诮邮罩袛嘀幸淖兊?,為了防止沖突,所以改動(dòng)前臨時(shí)關(guān)閉中斷。程序相當(dāng)可靠了。
            #asm("sei")//開(kāi)中斷
            }
            returndata;
            }

            注3:
            有興趣希望深入實(shí)在學(xué)習(xí)的網(wǎng)友,可將CVAVR生成的USART發(fā)送代碼仔細(xì)分析以下。它的發(fā)送代碼非常完美,可以馬上使用。
            #include

            #defineRXB81
            #defineTXB80
            #defineUPE2
            #defineOVR3
            #defineFE4
            #defineUDRE5
            #defineRXC7

            #defineFRAMING_ERROR(1<
            #definePARITY_ERROR(1<
            #defineDATA_OVERRUN(1<
            #defineDATA_REGISTER_EMPTY(1<
            #defineRX_COMPLETE(1<

            //USARTTransmitterbuffer
            #defineTX_BUFFER_SIZE8
            chartx_buffer[TX_BUFFER_SIZE];

            #ifTX_BUFFER_SIZE<256
            unsignedchartx_wr_index,tx_rd_index,tx_counter;
            #else
            unsignedinttx_wr_index,tx_rd_index,tx_counter;
            #endif

            //USARTTransmitterinterruptserviceroutine
            interrupt[USART_TXC]voidusart_tx_isr(void)
            {
            if(tx_counter)
            {
            --tx_counter;
            UDR=tx_buffer[tx_rd_index];
            if(++tx_rd_index==TX_BUFFER_SIZE)tx_rd_index=0;
            };
            }

            #ifndef_DEBUG_TERMINAL_IO_
            //WriteacharactertotheUSARTTransmitterbuffer
            #define_ALTERNATE_PUTCHAR_
            #pragmaused+
            voidputchar(charc)
            {
            while(tx_counter==TX_BUFFER_SIZE);
            #asm("cli")
            if(tx_counter||((UCSRA&DATA_REGISTER_EMPTY)==0))
            {
            tx_buffer[tx_wr_index]=c;
            if(++tx_wr_index==TX_BUFFER_SIZE)tx_wr_index=0;
            ++tx_counter;
            }
            else
            UDR=c;
            #asm("sei")
            }
            #pragmaused-
            #endif

            //StandardInput/Outputfunctions
            #include

            //Declareyourglobalvariableshere

            voidmain(void)
            {
            //Declareyourlocalvariableshere

            //Input/OutputPortsinitialization
            //PortAinitialization
            //Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
            //State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
            PORTA=0x00;
            DDRA=0x00;

            //PortBinitialization
            //Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
            //State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
            PORTB=0x00;
            DDRB=0x00;

            //PortCinitialization
            //Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
            //State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
            PORTC=0x00;
            DDRC=0x00;

            //PortDinitialization
            //Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
            //State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
            PORTD=0x00;
            DDRD=0x00;

            //Timer/Counter0initialization
            //Clocksource:SystemClock
            //Clockvalue:Timer0Stopped
            //Mode:Normaltop=FFh
            //OC0output:Disconnected
            TCCR0=0x00;
            TCNT0=0x00;
            OCR0=0x00;

            //Timer/Counter1initialization
            //Clocksource:SystemClock
            //Clockvalue:Timer1Stopped
            //Mode:Normaltop=FFFFh
            //OC1Aoutput:Discon.
            //OC1Boutput:Discon.
            //NoiseCanceler:Off
            //InputCaptureonFallingEdge
            //Timer1OverflowInterrupt:Off
            //InputCaptureInterrupt:Off
            //CompareAMatchInterrupt:Off
            //CompareBMatchInterrupt:Off
            TCCR1A=0x00;
            TCCR1B=0x00;
            TCNT1H=0x00;
            TCNT1L=0x00;
            ICR1H=0x00;
            ICR1L=0x00;
            OCR1AH=0x00;
            OCR1AL=0x00;
            OCR1BH=0x00;
            OCR1BL=0x00;

            //Timer/Counter2initialization
            //Clocksource:SystemClock
            //Clockvalue:Timer2Stopped
            //Mode:Normaltop=FFh
            //OC2output:Disconnected
            ASSR=0x00;
            TCCR2=0x00;
            TCNT2=0x00;
            OCR2=0x00;

            //ExternalInterrupt(s)initialization
            //INT0:Off
            //INT1:Off
            //INT2:Off
            MCUCR=0x00;
            MCUCSR=0x00;

            //Timer(s)/Counter(s)Interrupt(s)initialization
            TIMSK=0x00;

            //USARTinitialization
            //CommunicationParameters:8Data,1Stop,NoParity
            //USARTReceiver:Off
            //USARTTransmitter:On
            //USARTMode:Asynchronous
            //USARTBaudrate:9600
            UCSRA=0x00;
            UCSRB=0x48;
            UCSRC=0x86;
            UBRRH=0x00;
            UBRRL=0x19;

            //AnalogComparatorinitialization
            //AnalogComparator:Off
            //AnalogComparatorInputCapturebyTimer/Counter1:Off
            ACSR=0x80;
            SFIOR=0x00;

            //Globalenableinterrupts
            #asm("sei")

            while(1)
            {
            //Placeyourcodehere
            putchar(0x55);
            };
            }

            思考分析:
            我在主程序的循環(huán)里僅有一句不停的發(fā)0X55,問(wèn)題是AVR的運(yùn)行速度非???,而USART串出的速度肯定明顯的慢(按9600bps計(jì)算,需要1秒多時(shí)間才能送出1000個(gè)字符),那么,假定主程序循環(huán)了1000次,發(fā)送1000個(gè)0x55,請(qǐng)判斷在UASRT口上能否正確的發(fā)出1000個(gè)0x55,有沒(méi)有丟失或溢出現(xiàn)象存在?


            關(guān)鍵詞: uart中斷緩沖

            評(píng)論


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

            關(guān)閉