AVR UART 接收数据损坏

AVR UART Received Data corruption

我在 AVR (Atmega16) 和 GSM 模块之间有一个 UART 通信。通常,一切似乎都正常工作。问题是当我向 GSM 模块发送 SMS(例如 SMS:"H=0,95")时,在程序中每次收到 SMS 后都会有 SMS 响应。响应 (SMS) 已正确发送到手机 phone,但发生了用其他变量的随机数覆盖的情况。当我尝试使用终端调试它时,我想这是由于在 UART 中接收到大量字节引起的(变量 ser_rec 可能已损坏),但我无法在程序中找到它可能发生的位置。在 ISR 处理过程中,有一个条件可以避免这个问题,当最大字节数写入缓冲区时,缓冲区将被清除。



#include<avr/io.h>       // Header file for basic avr input/output
//#define F_CPU 8000000UL
#include<util/delay.h>   // header file for delay generation    
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <util/atomic.h> 



#include "rf22.h"
#include "lcd.h"


# define USART_BAUDRATE 9600
# define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 16UL))) - 1)



volatile unsigned char INTERRUPT=0;
volatile unsigned char DECODE_SMS=0;

uint16_t EEMEM HumidityLowRange=0;
uint16_t EEMEM HumidityHighRange=100;
int16_t EEMEM TemperatureLowRange=-40;
int16_t EEMEM TemperatureHighRange=80;
uint8_t EEMEM SMS_tel_number[14]="+421911243160";

unsigned char sms_index=0;
volatile int out=0;
int Temperature_low_range=-40;
int Temperature_high_range=80;
int Humidity_low_range=0;
int Humidity_high_range=100;
char tel_num[14];
//debugging tel num changing
unsigned char SMS_alert=0; //shows if SMS has been already sent


typedef struct
{
   int Humidity_value;
   int Temperature_value;
} BH;

   BH BeeHive[5]; //for all BeeHives, ambient sensor included (considered as BeeHive without Heater)

   void UART_Transmit_char( unsigned char data )
   {
   /* Wait for empty transmit buffer */
   while ( !( UCSRA & (1<<UDRE)) );
   /* Put data into buffer, sends the data */
   UDR = data;
   }



   void UART_Transmit_string( char string[] )
   {
   int i=0;
   while ( string[i] > 0)
   {
   UART_Transmit_char(string[i]);
   i++;        
   }
   }

   unsigned char rx_tmp[40];   


   volatile char ser_rec[95]="";
   volatile unsigned char a=0;

   void clear_sec_rec()
   {
   int i=0;
   while(i<sizeof(ser_rec))
   { 
   ser_rec[i]=0;
   i++;
   }
   i=0;
   a=0;
   }

   char sms_index1()
   {
       int i=0;
       char index=0;
       while( i<(sizeof(ser_rec)-4))
       {
           i++; //check if gsm sends SM",
           if(ser_rec[i]==((char) 'S'))
           {
           i++; 
               if(ser_rec[i]==((char) 'M'))
               {
                   i++;
                 if(ser_rec[i]==((char) '"'))
                 {
                        i++;
                   if(ser_rec[i]==((char) ','))
                   {
                           i++; 
                           index=ser_rec[i]; //return index  
                   }
                  }
               }
           }
           }//returns it
           if(index) clear_sec_rec();  //clears the ser_rec buffer if there was index
           return index;
   }

   void sms_decode()
   {
       int i=0;
       char TemporaryString[95];
       int Humidity_low_range_temp;
       int Humidity_high_range_temp;
       int Temperature_low_range_temp;
       int Temperature_high_range_temp;
       char SMS_text[80];

       //clear buffers
       strcpy(SMS_text, "");
       strcpy(TemporaryString, "");
       while( i<sizeof(ser_rec))
       {
       if(ser_rec[i]==((char) 'H'))
           {
           if(i<(sizeof(ser_rec)-4)) i++; //go forward only when there is a place for numbers =x,y, therefore number 4
               if(ser_rec[i]==((char) '='))
               {
                   i++;    
                   memcpy(TemporaryString, &ser_rec[i], ((strlen(ser_rec))-i));
                   TemporaryString[(strlen(ser_rec)-i)]='[=10=]';  
                   if((sscanf(TemporaryString,"%d,%d",&Humidity_low_range_temp,&Humidity_high_range_temp)==2))
                       {
                           if(Humidity_low_range_temp<Humidity_high_range_temp)
                           {
                               if((Humidity_low_range_temp>=0)&&(Humidity_high_range_temp<=100))
                               {
                               Humidity_high_range=Humidity_high_range_temp;
                               Humidity_low_range=Humidity_low_range_temp; 
                               //and finally send the notification about changed limits
                               clear_sec_rec();                
                               UART_Transmit_string("AT+CMGS=");
                               _delay_ms(50);
                               UART_Transmit_char(34);
                               _delay_ms(50);
                               UART_Transmit_string(tel_num);//the phone number
                               _delay_ms(50);
                               UART_Transmit_char(34);
                               _delay_ms(50);                          
                               UART_Transmit_string("\r");
                               _delay_ms(50);
                               clear_sec_rec(); //clears the buffer                        
                               sprintf(SMS_text,"Humidity range is set: Low=%d%% High=%d%%\r",Humidity_low_range, Humidity_high_range);
                               UART_Transmit_string(SMS_text);
                               _delay_ms(50);
                               UART_Transmit_char(0x1A);
                               _delay_ms(50);
                               clear_sec_rec();                        
                               _delay_ms(1000); //wait until response about credit will come
                               eeprom_update_word(&HumidityHighRange,Humidity_high_range);
                               eeprom_update_word(&HumidityLowRange,Humidity_low_range);
                               }
                           }
                       }
               }
           }
           i++;
       }
           //clear buffers
           strcpy(SMS_text, "");
           strcpy(TemporaryString, "");            
           i=0;
           //Temperature range set     
           while( i<(sizeof(ser_rec)-4))
               {
                   if(ser_rec[i]==((char) 'T'))
                   {
                        i++; 
                       if(ser_rec[i]==((char) '='))
                       {
                           if(i<(sizeof(ser_rec)-1)) i++;
                           memcpy(TemporaryString, &ser_rec[i], ((strlen(ser_rec))-i));
                           if((sscanf(TemporaryString,"%d,%d",&Temperature_low_range_temp,&Temperature_high_range_temp))==2)
                               {
                                   if(Temperature_low_range_temp<Temperature_high_range_temp)
                                   {
                                       if((Temperature_low_range_temp>=-40)&&(Temperature_high_range_temp<=80))
                                       {
                                       Temperature_high_range=Temperature_high_range_temp;
                                       Temperature_low_range=Temperature_low_range_temp;
                                       //and finally send the notification about changed limits
                                       clear_sec_rec();//clears the buffer
                                       UART_Transmit_string("AT+CMGS=");
                                       UART_Transmit_char(34);
                                       _delay_ms(50);                                  
                                       UART_Transmit_string(tel_num);//the phone number
                                       UART_Transmit_char(34);
                                       UART_Transmit_string("\r");
                                       _delay_ms(50);
                                       clear_sec_rec();//clears the buffer
                                       sprintf(SMS_text,"Temperature range is set: Low=%d C High=%d C\r",Temperature_low_range, Temperature_high_range);
                                       UART_Transmit_string(SMS_text);
                                       _delay_ms(50);
                                       UART_Transmit_char(0x1A);
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(1000); //wait until response about credit will come
                                       eeprom_update_word(&TemperatureHighRange,Temperature_high_range);
                                       eeprom_update_word(&TemperatureLowRange,Temperature_low_range);                                     
                                       }
                                   }
                               }
                           }

                   }
               i++;
               }
               //clear buffers
           strcpy(SMS_text, "");
           strcpy(TemporaryString, "");
                   i=0;
               //Info SMS  
               while( i<(sizeof(ser_rec)-2)) //go forward only when there is a place for at least 3 characters
               {
                   if(ser_rec[i]==((char) 'I'))
                   {
                       i++; 
//                      b1=1;
                       if(ser_rec[i]==((char) 'N'))
                       {
                           i++;
//                          b1=2;
                           if(ser_rec[i]==((char) 'F'))
                           {
//                              b1=3;
                           i++;
                               if(ser_rec[i]==((char) 'O'))
                               {
                                   //send info about all sensor values
                                   clear_sec_rec();
                                   _delay_ms(200);//clears the buffer
                                   UART_Transmit_string("AT+CMGS=");
                                   UART_Transmit_char(34);
                                   UART_Transmit_string(tel_num);//the phone number
                                   UART_Transmit_char(34);
                                   UART_Transmit_char('\r');
                                   _delay_ms(500);
                                   clear_sec_rec();
                                   _delay_ms(200);//clear the buffer
                                   //T2=%dC H0=%d%%\nH3=%d%% T3=%dC T0=%dC\nH4=%d%% T4=%dC add , BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value
                                   sprintf(SMS_text,"H1=%d%% T1=%dC  Amb:\nH2=%d%% T2=%dC H0=%d%%\nH3=%d%% T3=%dC T0=%dC\nH4=%d%% T4=%dC",BeeHive[1].Humidity_value, BeeHive[1].Temperature_value,BeeHive[2].Humidity_value, BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value);
//                                  c1=strlen(SMS_text);
                                   UART_Transmit_string(SMS_text);
                                   _delay_ms(50);
                                   UART_Transmit_char(0x1A); //CTRL-Z - required by datasheet
                                   _delay_ms(50);
//                                  UART_Transmit_char('\n');
//                                  d1=strlen(ser_rec);
                                   clear_sec_rec();
                                   _delay_ms(1000); //wait until response about credit will come                                   
                               }
                           }
                       }
                   }
                   i++;                    
               }
                   //Telephone number changing SMS
               //clear buffers
               i=0;
               strcpy(SMS_text, "");
               strcpy(TemporaryString, "");
                   while( i<(sizeof(ser_rec)-15))
                   {
                       if(ser_rec[i]==((char) 'T'))
                       {
                           i++; //go forward only when there is a place for 16 characters
                           if(ser_rec[i]==((char) 'E'))
                           { 
                               i++;
                               if(ser_rec[i]==((char) 'L'))
                               {
                                   i++;
                                   if(ser_rec[i]==((char) ':'))
                                   {
                                       i++;
                                       memcpy(TemporaryString, &ser_rec[i], 13);
                                       TemporaryString[13]='[=10=]';
                                       if((strlen(TemporaryString)==strlen(tel_num))&&(strlen(tel_num)==13))
                                       {
                                       memcpy(tel_num,&TemporaryString[0],strlen(TemporaryString));
                                       //send info about changing number
                                       clear_sec_rec();
                                       _delay_ms(200);//clears the buffer
                                       UART_Transmit_string("AT+CMGS=");
                                       UART_Transmit_char(34);
                                       UART_Transmit_string(tel_num);//the phone number
                                       UART_Transmit_char(34);
                                       UART_Transmit_string("\r");
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(200);//clear the buffer
                                       sprintf(SMS_text,"This is my new telephone number. BeeHiveMonitor");
                                       UART_Transmit_string(SMS_text);
                                       _delay_ms(50);
                                       UART_Transmit_char(0x1A);
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(1000); //wait until response about credit will come
                                       eeprom_update_block((void*)&tel_num, (const void*)&SMS_tel_number, 13);
                                       }
                                   }
                               }
                           }
                       }
                       i++;
                   }
                   //Alert turn on SMS
                       //clear buffers
                       strcpy(SMS_text, "");
                       strcpy(TemporaryString, "");
                       i=0;
                       //Info SMS
                       while( i<sizeof(ser_rec))
                       {
                           if(ser_rec[i]==((char) 'K'))
                           {
                               if(i<(sizeof(ser_rec))) i++;
                               if(ser_rec[i]==((char) 'K'))
                               {
                                           SMS_alert=0;
                                           //send info alert turning on 
                                           clear_sec_rec();
                                           _delay_ms(200);//clears the buffer
                                           UART_Transmit_string("AT+CMGS=");
                                           UART_Transmit_char(34);
                                           UART_Transmit_string(tel_num);//the phone number
                                           UART_Transmit_char(34);
                                           UART_Transmit_string("\r");
                                           _delay_ms(50);
                                           clear_sec_rec();
                                           _delay_ms(200);//clear the buffer
                                           UART_Transmit_string("Alerts are turned on\r");
                                           _delay_ms(50);
                                           UART_Transmit_char(0x1A);
                                           _delay_ms(50);
                                           clear_sec_rec();
                                           _delay_ms(1000); //wait until response about credit will come


                               }
                           }
                           i++;
                       }


                   i=0;
                   clear_sec_rec(); //clears the buffer
                   if(sms_index!=0)//deleting SMS
                   {
                   UART_Transmit_string("AT+CMGD=");
                   _delay_ms(50);
                   UART_Transmit_string("1,4\r"); //clear all SMSs in inbox
                   _delay_ms(50);
                   }
                   clear_sec_rec();
   }




    int main(void)
    {
   Humidity_high_range = eeprom_read_word(&HumidityHighRange);  //get init values of previously set limits both Humidity and Temperature
   Humidity_low_range  = eeprom_read_word(&HumidityLowRange);  
   Temperature_high_range = eeprom_read_word(&TemperatureHighRange);    
   Temperature_low_range  = eeprom_read_word(&TemperatureLowRange);
   eeprom_read_block((void*)&tel_num, (const void*)&SMS_tel_number, 13);
   sei();   

   char Text[80]; //character array for writing on the display
   char SMS_text[80]; // character array for writing via SMS
   char ATCommand[20];
   int flag=0;
   MCUCSR = (1<<JTD);  // no -O0, interrupts disabled
   MCUCSR = (1<<JTD);  // do not use read-modify-write
   DDRC=0xFF;
   DDRD=0b11111010;
   DDRB=0b10111111;
   PORTB = PORTB | (1 << PB3); // Reset pin of SIM800L
   _delay_ms(200);
   DDRA=0xFF;   
   PORTC = PORTC | (1 << PC7); // turn on LCD backlight
   //UART INIT
   UCSRB = (1 << RXEN ) | (1 << TXEN );
   UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 );
   UBRRH = (unsigned char)( BAUD_PRESCALE >> 8);
   UBRRL = (unsigned char) BAUD_PRESCALE&0xFF ;
   UCSRB |= (1 << RXCIE );

   lcd_init(LCD_DISP_ON); // display initialization
   rf22_init();
   rf22_setfreq(RF22FREQ(869.545));

   rf22_rxmode();


   //GSM init 3 times AT
   UART_Transmit_string("ATE0\r");
   _delay_ms(200);

   UART_Transmit_string("AT\r");
       _delay_ms(200);
   UART_Transmit_string("AT\r");
       _delay_ms(200);
   UART_Transmit_string("AT\r");   
       _delay_ms(200);
   clear_sec_rec();
   UART_Transmit_string("AT+CMGF=1\r");//set text mode
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
//  while(!(strstr((char*)ser_rec,"OK")));
   clear_sec_rec();
   UART_Transmit_string("AT+CNMI=1,1,0,0,0\r");
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
   clear_sec_rec();
   UART_Transmit_string("AT+CMGD=1,4\r"); //delete all SMS in inbox
   _delay_ms(100); 
//  UART_Transmit_string("1,4\r"); 
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
   clear_sec_rec();

   while(1)     
   {
       if((INTERRUPT==1)&&(DECODE_SMS==0))
       {   
       sms_index=sms_index1();
       INTERRUPT=0;

       if(sms_index!=0)
       {
       //if index exists - ready for decoding SMS  
       DECODE_SMS=1;
       sprintf(ATCommand,"AT+CMGR=%c\r",sms_index); 
       UART_Transmit_string(ATCommand); //request for reading SMS with sms index   
       }
       }


       if((INTERRUPT==1)&&(DECODE_SMS==1))//decodes the sms
       {
       sms_decode(); 
       DECODE_SMS=0; //finally clear both flags
       INTERRUPT=0;
       }   



for(int x=0;x<5;++x)
{
       rf22_getpacket(rx_tmp);
       _delay_ms(10);   
       sscanf(rx_tmp,"_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d",&BeeHive[0].Humidity_value, &BeeHive[0].Temperature_value,&BeeHive[1].Humidity_value, &BeeHive[1].Temperature_value,&BeeHive[2].Humidity_value, &BeeHive[2].Temperature_value,&BeeHive[3].Humidity_value, &BeeHive[3].Temperature_value,&BeeHive[4].Humidity_value, &BeeHive[4].Temperature_value);      
       _delay_ms(10);
       lcd_clrscr();
       _delay_ms(10);
       lcd_gotoxy(0,0);
       sprintf(Text,"H1=%02d T1=%+03d  Amb:\nH2=%02d T2=%+03d H0=%02d\nH3=%02d T3=%+03d T0=%+03d\nH4=%02d T4=%+03d",BeeHive[1].Humidity_value, BeeHive[1].Temperature_value,BeeHive[2].Humidity_value, BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value);
   //  sprintf(Text,"a:%d b:%d c:%d d:%d\n tel:%s\n index: %d",a1,b1,c1,d1,tel_num,sms_index);
   //  sprintf(Text,"HL:%d HH:%d\n tel:%s\n TL:%d TH:%d",Humidity_low_range,Humidity_high_range,tel_num, Temperature_low_range, Temperature_high_range);
   //  sprintf(Text,"High Limit:%d\nLow Limit:%d",Humidity_high_range, Humidity_low_range);
       //UART_Transmit_string("AT+CMGF=1\r");
       //_delay_ms(100);       
       //sprintf(Text,"%s",ser_rec);
       //ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
       //{
       //UART_Transmit_string("AT\r");
       //_delay_ms(1000);  
       //sprintf(Text,"%s",ser_rec);           
       //}
//
       //UART_Transmit_string("AT\r");
       //clear_sec_rec();
       lcd_puts(Text);
       _delay_ms(2000);
}   
//SMS alert condition
   for(int j=1;j<5;j++)
       {
       if(!SMS_alert)
       {
       if(BeeHive[j].Humidity_value>Humidity_high_range || BeeHive[j].Humidity_value<Humidity_low_range || BeeHive[j].Temperature_value>Temperature_high_range ||BeeHive[j].Temperature_value<Temperature_low_range) 
       {
           //sending SMS alert
           SMS_alert=1;
           UART_Transmit_string("AT+CMGS=");
           _delay_ms(100);
           UART_Transmit_char(34);
           _delay_ms(100);
           UART_Transmit_string(tel_num);//the phone number
           _delay_ms(100);
           UART_Transmit_char(34);
           _delay_ms(100);
           UART_Transmit_string("\r");
           _delay_ms(100);
           clear_sec_rec();
           sprintf(SMS_text,"Alert: H%d=%d%% T%d=%+d C\r",j,BeeHive[j].Humidity_value,j,BeeHive[j].Temperature_value);
           UART_Transmit_string(SMS_text);
           _delay_ms(100);
           UART_Transmit_char(0x1A);
           _delay_ms(100);
           clear_sec_rec();
       }
       }
       }   
       _delay_ms(100);
   }
        return 0;

    }

ISR ( USART_RXC_vect )
{
   if(a<(sizeof(ser_rec)))
   {
   ser_rec[a]=UDR;
   if((ser_rec[a]!=0xd)&&(ser_rec[a]!=0xa)) //we do not need these bytes 0xd,0xa
   {
       a++;
       INTERRUPT=1;
   }
   }
   else
   {
   out=UDR;
   clear_sec_rec();
   }
}


警告: 这不是一个解决方案,而是清理您的代码以便您找到解决方案。那是因为你的代码有太多不必要的复杂性,很难分析它。

但是,一些[明显的]错误...


您的 ISR 与您的任务级别赛跑

尽管 volatile.

,但您的 ISR 与缓冲区任务级别的同步值得怀疑

当您尝试从任务级别访问它时,您需要在任务级别访问期间禁用中断。

您应该将访问权包装成 cli/sti 对。为 任何 任务级别访问 ser_reca 执行此操作。而且,not 只是围绕着循环中的 单个 字节获取。您应该将 cli 作为任务级函数的第一件事,将 sti 作为函数的最后一件事。

而且,我会将 a 重命名为更具描述性的名称,例如 ser_len


仅处理您知道您拥有

的数据

并且,在任务级别(例如 sms_decode),您的循环限制是 sizeof(ser_rec),因此您正在访问 garbage/random 值或来自 的部分陈旧值上一条 条新消息。

而不是:

while (i < sizeof(ser_rec))

你可能想要:

while (i < a)

或者,如果您重命名:

while (i < ser_len)

如果这样做,clear_sec_rec 函数不再需要 将缓冲区清零,而只需重置 ser_len。归零是为了减轻破环限制的尝试。


任务级别需要"slide"缓冲区

也就是说,如果当前传入的记录有(例如)8 个字符,但 ser_len 是(例如)12,任务级别必须 "slide" 缓冲区以删除已处理的记录:

memmove(&ser_rec[0],&ser_rec[8],ser_len - 8);
ser_len -= 8;

如果缓冲区溢出

,ISR 应该重置缓冲区

如果输入的字符太多,您的 ISR 就是 "resetting" 缓冲区。这可能会中断任务级处理,因为您可以在处理过程中进行重置。

如果 buffer/ring 填满,ISR 应该设置一个 "overflow" 标志,任务级别可以检查 [并删除字符],而不是从任务级别下拉出地毯随着重置。


使用环形队列

但是,您可能希望将缓冲区转换为环形队列。这有点复杂,但允许从 ISR 到任务的流程是连续的。 (即)这将消除 ISR 重置缓冲区的需要。而且,任务级别将能够处理 多个 条记录而不会丢失任何记录。

设置过大的缓冲区大小可能会有所帮助(例如 char ser_rec[10000])。但是,只有在修复同步后才执行此操作。

可能 甚至能够使用原子(例如 stdatomic.h 在环形缓冲区索引上)并避免在任务 cli/sti 中的需要 [虽然后者比较慢但是比较简单。


消除不必要的复杂性

您正在使用 N 级 if/else 梯子而不是简单的 memcmp:

char
sms_index1()
{
    int i = 0;
    char index = 0;

#if 0
    while (i < (sizeof(ser_rec) - 4)) {
        i++;                            // check if gsm sends SM",
        if (ser_rec[i] == ((char) 'S')) {
            i++;
            if (ser_rec[i] == ((char) 'M')) {
                i++;
                if (ser_rec[i] == ((char) '"')) {
                    i++;
                    if (ser_rec[i] == ((char) ',')) {
                        i++;
                        index = ser_rec[i]; // return index
                    }
                }
            }
        }
    }                                   // returns it
#else
    while (i < (sizeof(ser_rec) - 4)) {
        // return index
        if (memcmp(&ser_rec[i],"SM\",",4) == 0) {
            i += 4;
            index = ser_rec[i];
        }
        i += 1;
    }
#endif

    // clears the ser_rec buffer if there was index
    if (index)
        clear_sec_rec();

    return index;
}

将您的代码每行 80 个字符

在逻辑点分解长行

更改(例如):

if (BeeHive[j].Humidity_value > Humidity_high_range || BeeHive[j].Humidity_value < Humidity_low_range || BeeHive[j].Temperature_value > Temperature_high_range || BeeHive[j].Temperature_value < Temperature_low_range)

进入:

if ((BeeHive[j].Humidity_value > Humidity_high_range) ||
    (BeeHive[j].Humidity_value < Humidity_low_range) ||
    (BeeHive[j].Temperature_value > Temperature_high_range) ||
    (BeeHive[j].Temperature_value < Temperature_low_range)) {

避免在代码中使用 [long] "sidebar" 注释。而是将它们放在上面的一行上。 (例)

更改(例如):

i++;                        // go forward only when there is a place for 16 characters

进入:

// go forward only when there is a place for 16 characters
i++;

对特殊值使用#define/enum

您也在做(例如)UART_Transmit_char(34); 34 是一个 "hardwired" 值。 mean/represent 是什么意思?做类似的事情:#define STARTCHAR 34 // framing char 然后做:UART_Transmit_char(STARTCHAR);


用空行分隔 related/unrelated 代码块

添加一些空行来分组。例如,您执行 UART_Transmit_char,然后执行:_delay_ms(50)。在 _delay_ms 后添加一个空行。或者,更好的做法是创建一个同时执行这两项操作的函数并调用 that 函数。


修复损坏的评论

您的一些评论是 incorrect/misplaced:

_delay_ms(200); // clear the buffer

编译带有警告的代码启用并修复所有警告

因为我无权访问 AVR 文件(例如 avr/interrupt.h),所以我无法编译您的代码。但是,您应该使用 -Wall -O2 进行编译以生成警告并修复它们。而且,我怀疑你有一些。