<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        AVR atmega16協議的制定

        作者:未知   來源:網上一位高手   點擊數:  更新時間:2014年06月01日   【字體:

         此規定的協議時通過上位機發送指令,使單片機在不同的時間內發送讀取的溫度值

         
        #define F_CPU 8000000UL
        #include
        #include
        #include
        #define BAUD 9600  //定義波特率
        #define uchar unsigned char
        #define uint unsigned int
        #define FRAMING_ERROR  _BV(FE)  //接收幀出錯
        #define PARITY_ERROR   _BV(PE)  //校驗出錯
        #define DATA_OVERRUN  _BV(DOR)  //數據溢出
        #define DATA_REGISTER_EMPTY _BV(UDRE) //數據寄存器為空,當寫入UDR(TXB)的字符被傳送到移位寄存器中時,該位置1, 表示UDR可以寫入新的數據。
        #define RX_COMPLETE  _BV(RXC)  //接收器接收一個完整的數據幀后,接收到的數據駐留在接收緩沖器中,此時RXC標志。會置1(產生接收完成中斷),
                //表示接收器收到一個數據在接收緩沖器中,未被讀取。當RXC為“0”時,表示數據接收器為空。
        #define TX_BUFFER_SIZE 6  //發送緩沖器大小      
        //USART接收緩沖區
        #define RX_BUFFER_SIZE 5   //接收緩沖器大小
           
        uchar rx_buffer[RX_BUFFER_SIZE]={0,0,1,0,0};  //定義接收緩沖區
         
        //定義接收緩沖區環形隊列的控制指針,rx_wr_index為寫指針,rx_rd_index為讀指針,rx_counter為存放在隊列中的已接受到字符數
        #if RX_BUFFER_SIZE <256
        uchar rx_wr_index,rx_rd_index,rx_counter;
        #else
        uint rx_wr_index,rx_rd_index,rx_counter;
        #endif
        //端口狀態初始化設置函數
        //void Port_Init()
        //{
         //PORTD = 0X00;          //USART 的發送接收端口分別為 PD0 和 PD1
         //DDRD |= (1 << PD1);   //PD0 為接收端口,置為輸入口;PD1 為發送端口,置為輸出口
        //}
        void Usart_Init()
        {
         UCSRA = 0X00;
         UCSRC |= (1<<URSEL) | (1 << UCSZ1) | (1 << UCSZ0);  //異步,數據格式 8,N,1
         //UCSRC 寄存器與 UBRRH 寄存器共用相同的 I/O 地址,寫 UCSRC 時, URSEL 應設置為 1。
         UBRRL = (F_CPU / BAUD / 16 - 1) % 256;            //波特率設置
         UBRRH = (F_CPU / BAUD / 16 - 1) / 256;
         UCSRB |= (1 << TXEN)|(1<<RXEN)|(1<<RXCIE)|(1<<TXCIE);       //接收發送接收使能,并使能發送接收標志中斷,
        }
         
        uchar rx_buffer_overflow; //接收緩沖區溢出標志
        uchar recvFlag;
        //接收中斷服務
        ISR(USART_RXC_vect)
        {
         uchar status,data;
         status=UCSRA;  //讀取接收狀態標志位,必須先讀,當讀了UDR以后,UCSRA便自動清零了
         data=UDR;     //讀取USART數據寄存器
         if(!recvFlag)
         {
          if ((status &(FRAMING_ERROR|PARITY_ERROR|DATA_OVERRUN)) ==0)
         {
          rx_buffer[rx_counter]=data;  //將字符填充到接收緩沖區隊列中
          rx_counter++;
          //Putchar(recvFlag);
          //Putchar(data);
          //
          //if((rx_counter++)==5)
          //{
           //rx_counter=0;
           //recvFlag=1;
          //}
          
          //Putchar(rx_counter);
          //制訂協議:第一位起始位:BBH;第二位命令字:0AH代表控制數據傳送的時間,0BH代表控制溫度上下限值,
          //第三位參數字,第四位校驗碼:命令字與參數字的異或,最后一位結束位:EEH
          switch(rx_counter)
          {
           case 1:        //檢驗起始位
            if(data!=0XBB) rx_counter=0;break;
           case 4:        //校驗校驗字
            if(data != rx_buffer[1]^rx_buffer[2])
            
            //Putchar("FF");
            rx_counter=0; 
            
            
            //Putchar(rx_buffer[0]);
            //Putchar(rx_buffer[1]);
            //Putchar(rx_buffer[2]);
            //Putchar(rx_buffer[3]);
            //Putchar(rx_buffer[4]);  
            break;
           case 5: //校驗結束字
               
            rx_counter=0;
            if(data ==0xEE) recvFlag=1;break; //recvFlag=1表示正確接收一個數據包 
          }
         }
         } 
         
        }
         
         
        //從接收隊列中讀取一個數據
         
        uchar Getchar(void)
        {
         uchar data;
         while(rx_counter==0);  //接收緩沖區中沒有數據可以讀取,等待。
         data=rx_buffer[rx_rd_index];  //讀取緩沖隊列中的數據
         if(++rx_rd_index==RX_BUFFER_SIZE)
         rx_rd_index=0;
         cli();     //禁止中斷,這一步非常重要
         --rx_counter;  //隊列未讀數據個數減1.因為該變量會在接收中斷中改變,為了防止沖突,所以改動前應臨時禁止中斷。程序相當可靠
         sei();  //使能中斷
         return data;
        }
         
        //發送緩沖區
        uchar tx_buffer[TX_BUFFER_SIZE];  //定義發送緩沖區
        //定義發送緩沖區環形隊列的控制指針,tx_wr_index為寫指針,tx_rd_index為讀指針,tx_counter為存放在隊列中的已接受到字符數
        uchar tx_wr_index,tx_rd_index,tx_counter;
         
        //向USART發送緩沖區寫一個字符
        void Putchar(unsigned char c)
        {
         
         while(tx_counter==TX_BUFFER_SIZE);  //如果發送隊列滿,等待
         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;
            sei();
        }
         
        ISR(USART_TXC_vect)
        {
         if(tx_counter)     //發送隊列中還未發送的數據
         {
          --tx_counter;  //未發送數據減1。
          
          UDR = tx_buffer[tx_rd_index]; //發送一個數據。
           
          if(++tx_rd_index==TX_BUFFER_SIZE)
          
           tx_rd_index=0;    //讀指針指向下一個未發送的數據,如果指到了隊列尾部,則回到隊列頭部。
         } 
        }
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮