اطلاعیه

Collapse
No announcement yet.

هنگ کردن برنامه

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    هنگ کردن برنامه

    {کل پروژه رو پلود کردم، اگه فرصت دارید یه نگاهی بندازید شاید یه نکته خیلی ساده از دید من پنهان مونده باشه.}
    سلام.
    یه مشکل عجیب در برنامه من ایجاد شده، مطرح میکنم دوستان راهنمایی کنن.
    من در یک برنامه 4 تا وقفه دارم که تقریبا همزمان فعال هستن.
    سه تا وقفه تایمر هست و یکی وقفه سخت افزاری.
    از بین وقفه ها دو تایی که مربوط به تایمر هستن اولویتشون متوسط هست و زمان اجراشون کوتاه.
    تایمر آخری اولویتش پایین هست و زمان اجرای اون خیلی طولانی هست. حدود 2 میلی ثانیه و خودش هم هر 2.5 میلی ثانیه یک بار فراخونی میشه.
    وقفه سخت افزاری هم اولویتش متوسط هست.
    نکته دیگه اینکه وقفه سخت افزاری و وقفه یکی از تایمر ها(نه اونی که طولانی هست) درون برنامه مداوم فعال و غیر فعال میشن.
    حالا اتفاقی که میفته اینه که برنامه در حالات مختلف کار میکنه ولی یه مدت که کار کرد وارد حالتی میشه که دیگه کد حلقه اصلی برنامه رو اجرا نمیکنه فقط داخل وقفه ها میمونه. من چک کردم زمان وقفه ها طوری نیست که برنامه در وقفه ها گیر افتاده باشه. مثلا زمان یه وقفه هر 3 میلی ثانیه هست که حداکثر زمانی که برای اجرای روتین اون نیاز هست 2 میلی ثانیه هست و اولویت این وقفه هم LOWآ‌تعریف شده.
    اون یکی هم اولویتش MED تعریف شده و حداکثر زمان اجرای روتینش 2 میکرو ثانیه هست.
    زمانی هم که برنامه به اصطلاح هنگ میکنه این دو وقفه به خوبی کار میکنن، میکرو وارد این وقفه ها میشه و ازشون خارج میشه ولی هیچ خطی از حلقه اصلی برنامه رو اجرا نمی کنن.
    الان برام سوال شده که CPU وقتی از وقفه ها خارج میشه داره چی رو اجرا می کنه؟؟؟
    ---
    آزمایش های مختلف انجام دادم متوجه شدم همه چیز برمیگرده به تابع SD_read که از طریق اون با کارت ارتباط برقرار میکنم. داخل این تابع از توابع کتابخونه spi_driver استفاده شده.
    حالا اگه تابع SD_read رو که در وقفه فراخونی شده غیر فعال کنم و به جای اون مثلا 2 و نیم میکرو ثانیه تاخیر بذارم برنامه به هیچ وجه هنگ نمیکنه. به نظر شما علت چی میتونه باشه؟
    این هم کد ها:

    کد:
    unsigned char SD_Command( unsigned char cmd,unsigned long int arg)
    {
      char resp;
      char retry=0; 
      SPI_MasterSSLow(ssPort, PIN4_bm);  
      sendData=cmd|0x40;// note command is CMD-X + 0x40
    
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
    
      sendData=arg>>24;
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      sendData=arg>>16;
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      sendData=arg>>8;
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      sendData=arg;
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      sendData=0x95;                   // spi CRC = always 0xff OR 0x95 for MMC_GO_IDLE_STATE command
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      sendData = 0xff;
      resp=SPI_MasterTransceiveByte(&spiMasterD,sendData);
      
      while(resp == 0xff)
      {
        resp=SPI_MasterTransceiveByte(&spiMasterD,sendData);
        if(retry++ > 80) 
          break;         // card has timed out
      }
      
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      return resp;      // Note! MMC enable is ON
    }
    
    //---------------------------
    unsigned char SD_Read(unsigned long int Sector) 
    {
      uint8_t resp,retry=0;
      int i;
      
      resp = SD_Command(READ_BLK, Sector);  // send command:READ-BLOCK
      if(resp != 0x00)
        return resp;    // check response
    
      sendData = 0xff;
      retry=0x00;
      do
      {
        resp=SPI_MasterTransceiveByte(&spiMasterD,sendData);
    
        retry++;
        if(retry>200)
          return 0xff;
      }while(!(resp == STARTBYTE_RDWR));
    
      
      for(i=0; i<BLOCKSIZE; i++)
      {
        Buffer[i]=SPI_MasterTransceiveByte(&spiMasterD,sendData);// read in data
      }
    
      // read 16-bit CRC
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      // last 8 CLK
      SPI_MasterTransceiveByte(&spiMasterD,sendData);
      SPI_MasterSSHigh(ssPort, PIN4_bm);  
      return 0; // return OK
    }

    این هم فایل اصلی برنامه:
    کد:
    #include "avr_compiler.h"
    #include "TDA8551.h"
    #include "SD.h"
    #include "port_driver.h"
    #include "TC_driver.h"
    #include "dac_driver.h"
    #include "pmic_driver.h"
    enum PLAYRESPONSE{
      EndFile,
      Intrpt};
    typedef enum PLAYRESPONSE PlayResult;
    //------------
    //struct _ULTRASONIC
    //{
    unsigned int ADistanceCM[10];
    unsigned int DistanceCM;
    unsigned int PUTSET=0;
    unsigned int UTSET=0;
    unsigned char USampleCNT=0;
    volatile uint16_t TimeCNT;
    //}UltraSonic;
    
    volatile enum _UltraSonicStatus{
      TXDisable,
      TXEnable,
      EchoReady,
      TXEn_PortINT,
      TXDi_PortINT}UltaSonicStatus;
    
    volatile enum {
      PLAY,
      MELODY,
      SOUNDEFFECT}DeviceMode;
    
    
    unsigned int USoundF[5]={71,67,63,59,55};
    //------------
    uint16_t DACVAL=0;
    
    struct _FILEATTRIBUTE
    {
      unsigned int Name;
      unsigned long int StartingAdd;  
      unsigned long int EndAdd;
      unsigned char Type;
      unsigned long int WhenInterrupt;
      unsigned long int NonInterrupt;  
      unsigned long int Answer;  
    };
    volatile struct _Flags
    {
      unsigned char INT0Event:1;//external interrupt
      unsigned char EnIntInPlay:1;//enable interrupt in Play function
      unsigned char PlayState:1;
      unsigned char DeviceStatus:1;
    }Flags;
    
    /* Global variables. */
    #define BfrSize 512
    #define SprtBfrSize 200
    volatile uint8_t Buffer[BfrSize],PBuffer[SprtBfrSize];
    volatile unsigned long int SD_Add,SD_StartAdd;
    volatile unsigned int BufferCounter=0;
    volatile unsigned char Buffer_Flag=0; // --
    unsigned long int PlayFileEndAdd;
    struct _FILEATTRIBUTE CurrentFileAttribute;
    
    PORT_t *ssPort = &PORTD;
    
    SPI_Master_t spiMasterD;
    
    SPI_DataPacket_t DataPacket;
    
    uint8_t sendData;//[NUM_BYTES + 1] = { 0x55, 0xaa, 0x00 };
    
    uint8_t receivedData;//[NUM_BYTES + 1];
    
    
    
    inline void initial(void);
    inline void Timer_Init(void);
    inline struct _FILEATTRIBUTE FileAttributeReader(unsigned long int);
    inline void Play(unsigned long int,unsigned long int);
    uint16_t Delay;
    void main(void)
    {
      uint16_t i;
      OSC.CTRL|=OSC_RC32MEN_bm;
      while(!(OSC.STATUS & OSC_RC32MRDY_bm));
      CCP=CCP_IOREG_gc;
      CLK.CTRL=CLK_SCLKSEL_RC32M_gc; 
      PORTE.DIRSET=0x0c;
      PORTE.OUTSET=0x0c;
      PORTE.OUTCLR=0x08;        
      initial();
      DAC_SingleChannel_Enable(&DACB,DAC_REFSEL_AVCC_gc,false);  
      PORTE.OUTCLR=0x08;      
      DistanceCM=0;
      PORTA.DIRSET=0x04;
      DeviceMode=MELODY;
      Flags.DeviceStatus=1;
      Flags.PlayState=1;
      
      while(1)
      {
        PORTE.OUTTGL=0x04;                    
        delay_us(3000);    
        UltaSonicStatus=TXDisable;
        TC_Restart(&TCD0);                       
        PORTA.OUTSET=0x01;   
        delay_us(100);
        PORTA.OUTCLR=0x01;       
        delay_us(400); 
        PORT_ConfigureInterrupt0( &PORTA,
                     PORT_INT0LVL_MED_gc,//PORT_INT0LVL_HI_gc,//PORT_INT0LVL_LO_gc,
                     PIN1_bm );
        
        UltaSonicStatus=TXEnable;
        TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV4_gc );
    
        while(UltaSonicStatus==TXEnable);//&&(PORT_GetPortValue(&PORTA)&PIN1_bm));
          
        TimeCNT=TCD0.CNT;
        if(UltaSonicStatus==TXEn_PortINT)
        {
    //      PORTE.OUTTGL=0x08;    
          UltaSonicStatus=TXDisable;
          ADistanceCM[USampleCNT]=(TimeCNT/480);// 480 ==> reselotion 1cm
          USampleCNT++;
          if(USampleCNT>10)
          {
            USampleCNT=0;
            DistanceCM=0;
            for(i=0;i<10;i++)
            {
              DistanceCM+=ADistanceCM[i];
            }
            DistanceCM=DistanceCM/10;
              
            UltaSonicStatus=EchoReady;        
          }
          else
          {
            UltaSonicStatus=TXDisable;        
          }
        }
        else
        {
          UltaSonicStatus=TXDisable;
        }
        if(UltaSonicStatus==EchoReady)
        {  
          UltaSonicStatus=TXDisable;
          PUTSET=UTSET;      
    
          switch(DeviceMode)
          {
            case PLAY:
            {
              if(Flags.DeviceStatus)
              {
                Flags.DeviceStatus=0;
                TC0_ConfigClockSource(&TCC0, TC_CLKSEL_DIV1024_gc );//DIV1024          
                TC1_ConfigClockSource(&TCD1, TC_CLKSEL_OFF_gc );//DIV8          
                TC1_ConfigClockSource(&TCC1, TC_CLKSEL_OFF_gc );//DIV1024          
                TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV4_gc );//DIV8              
              }
              
              UTSET=DistanceCM;      
              if(UTSET!=PUTSET)
              {
                TC_SetPeriod(&TCC0,UTSET);
                TC_Restart(&TCC0);                   
              }
              break;
            }
            case MELODY:
            {
              if(UTSET==(5-1))
              {
                if(DistanceCM>28&&DistanceCM<=41)            
                {
                  UTSET=5-1;
                  break;
                }
              }
              else if(UTSET==(6-1))
              {
                if(DistanceCM>20&&DistanceCM<=36)
                {
                  UTSET=6-1;
                  break;
                }
              }
              else if(UTSET==(7-1))
              {
                if(DistanceCM>12&&DistanceCM<=28)
                {
                  UTSET=7-1;
                  break;
                }
              }
              else if(UTSET==(8-1))
              {
                if(DistanceCM>4&&DistanceCM<=20)
                {
                  UTSET=8-1;
                  break;
                }
              }
              else if(UTSET==(9-1))
              {
                if(DistanceCM>0&&DistanceCM<=12)
                {
                  UTSET=9-1;
                  break;
                }
              }
              
              if(DistanceCM>32&&DistanceCM<=41)
              {
                UTSET=5-1;
              }
              else if(DistanceCM>24&&DistanceCM<=32)
              {
                UTSET=6-1;
              }
              else if(DistanceCM>16&&DistanceCM<=24)
              {
                UTSET=7-1;
              }
              else if(DistanceCM>8&&DistanceCM<=16)
              {
                UTSET=8-1;
              }
              else if(DistanceCM>0&&DistanceCM<=8)
              {
                UTSET=9-1;
              }
              
              if(UTSET!=PUTSET)
              {
                CurrentFileAttribute=FileAttributeReader(UTSET);                  
                Play(CurrentFileAttribute.StartingAdd,CurrentFileAttribute.EndAdd);       
              if(Flags.DeviceStatus)
              {
                Flags.DeviceStatus=0;
                TC0_ConfigClockSource(&TCC0, TC_CLKSEL_OFF_gc );//DIV1024          
                TC1_ConfigClockSource( &TCD1, TC_CLKSEL_DIV8_gc );//DIV8          
                TC1_ConfigClockSource(&TCC1, TC_CLKSEL_DIV256_gc );//DIV1024          
    //            TC0_ConfigClockSource(&TCD0, TC_CLKSEL_OFF_gc );//DIV8              
              }
                
              }
              
              break;
            }
            default:
            DeviceMode=MELODY;
          }
        }
      }
    }
    //---------------------------
    void initial(void)
    {
      SD_init(); 
      PORTE.OUTCLR=0x04;
      //-------- initial AMP
    
      AMPCNFG();
      AMPVolUP(50);
      
      //-------- Ultrasonic
      TimeCNT=0;  
      
      PORTA.DIRSET=0x01;
      PORTA.OUTCLR=0x01;
      PORT_ConfigurePins(&PORTA,
                PIN1_bm,
                false,
                false,
                PORT_OPC_TOTEM_gc,
                PORT_ISC_BOTHEDGES_gc );
      PORT_SetPinAsInput( &PORTA,
                PIN1_bp );  
    
      PORT_ConfigureInterrupt0( &PORTA,
                   PORT_INT0LVL_OFF_gc,//PORT_INT0LVL_HI_gc,//PORT_INT0LVL_LO_gc,
                   PIN1_bm );
    
      PMIC.CTRL |= PMIC_LOLVLEN_bm;
      //-------
      Timer_Init();
    
      sei();
     }
    //--------------------------- Timer
    void Timer_Init(void)
    {
      TC_SetPeriod(&TCD1,0x00fa);// 0x00fa => 62.5 us
      TC1_SetOverflowIntLevel(&TCD1,TC_OVFINTLVL_MED_gc);
    //  TC1_ConfigClockSource( &TCD1, TC_CLKSEL_DIV8_gc );//DIV8
      //--------
    
      TC_SetPeriod(&TCD0,0x5000);// distance(MAX)=(80)/2cm        ultrasound distance 
      TC0_SetOverflowIntLevel(&TCD0,TC_OVFINTLVL_MED_gc);
    //  TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV4_gc );//DIV8  
    
      TC_SetPeriod(&TCC0,0x00ff);//                    DAC sample player timer 
      TC0_SetOverflowIntLevel(&TCC0,TC_OVFINTLVL_MED_gc);
    //  TC0_ConfigClockSource(&TCC0, TC_CLKSEL_DIV1024_gc );//DIV1024
    
      TC_SetPeriod(&TCC1,0x0190);// ~5ms                 MicroSD Buffer update
      TC1_SetOverflowIntLevel(&TCC1,TC_OVFINTLVL_LO_gc);
    //  TC1_ConfigClockSource(&TCC1, TC_CLKSEL_DIV256_gc );//DIV1024TC_CLKSEL_DIV256_gc
    
      
      PMIC.CTRL |= PMIC_MEDLVLEN_bm;// | PMIC_LOLVLEN_bm;  
      PMIC.CTRL |=PMIC_HILVLEN_bm;
    }
    //-----------------------------------------------
    struct _FILEATTRIBUTE FileAttributeReader(unsigned long int FileAdd)
    {
    ...
    }
    //-----------------
    void Play(unsigned long int StartAdd,unsigned long int EndAdd)
    {
      cli();
      Flags.PlayState=1;
      SD_Add=SD_StartAdd+StartAdd;
      PlayFileEndAdd=(SD_StartAdd+EndAdd);
      sei();
      Buffer_Flag=0x01;
      BufferCounter=0;
      SD_Read(SD_Add);
      DAC_SingleChannel_Enable(&DACB,DAC_REFSEL_AVCC_gc,false);
    }
    //---------------------------
    
    ISR(TCD1_OVF_vect)
    {
      uint16_t tmp;
      if(Flags.PlayState)
      {
        if(BufferCounter<(BfrSize-SprtBfrSize))
        {
          if(BufferCounter==0)
            Buffer_Flag=0x01;
          tmp=Buffer[BufferCounter+1];
          tmp=tmp<<8;
          tmp|=Buffer[BufferCounter];
          DAC_Channel_Write(&DACB,tmp,CH0);
          BufferCounter+=2;
        }
        else 
        {
          if(BufferCounter==(BfrSize-SprtBfrSize))
          {
            Buffer_Flag=0x02;
    //        TCC1.CNT=0x0189;
          }
          tmp=PBuffer[BufferCounter-(BfrSize-SprtBfrSize)+1];
          tmp=tmp<<8;
          tmp|=PBuffer[BufferCounter-(BfrSize-SprtBfrSize)];
          DAC_Channel_Write(&DACB,tmp,CH0);
          BufferCounter+=2;
    
          if(BufferCounter>=BfrSize)
            BufferCounter=0;
        }
      }
    }
    
    //---------------------------
    
    ISR(PORTA_INT0_vect)
    {
      if(UltaSonicStatus==TXEnable)
      {
    //    PORT_ConfigureInterrupt0( &PORTA,
    //                 PORT_INT0LVL_OFF_gc,//PORT_INT0LVL_HI_gc,//PORT_INT0LVL_LO_gc,
    //                 PIN1_bm );
        TC0_ConfigClockSource(&TCD0,TC_CLKSEL_OFF_gc);
        UltaSonicStatus=TXEn_PortINT;
      }
    }
    
    //------------
    ISR(TCD0_OVF_vect)
    {
      cli();
      UltaSonicStatus=TXDisable;
      sei();
    }
    //------------
    ISR(TCC0_OVF_vect)
    {
      if(DeviceMode==PLAY)
      {
        DACVAL=0x0fff-DACVAL;
        DAC_Channel_Write(&DACB,DACVAL,CH0);      
      }
    }
    //------------
    ISR(TCC1_OVF_vect)
    {
      uint16_t i;
      PORTE.OUTTGL=0x08;                        
      if((SD_Add<PlayFileEndAdd)&&(Flags.PlayState))
      {
        if(Buffer_Flag==0x01)
        {
          for(i=0;i<SprtBfrSize;i++)
          {
            PBuffer[i]=Buffer[(BfrSize-SprtBfrSize)+i];
          }
          Buffer_Flag=0;
        }
        if(Buffer_Flag==0x02)
        {
    //      TC1_ConfigClockSource(&TCC1, TC_CLKSEL_OFF_gc );      
          SD_Add+=0x200;
    //      delay_us(2300);
          SD_Read(SD_Add);    
          Buffer_Flag=0;        
    //      TC1_ConfigClockSource(&TCC1, TC_CLKSEL_DIV256_gc );      
        }
      }
      else
      {
        Flags.PlayState=0;
        Flags.DeviceStatus=1;
        DeviceMode=PLAY;
        TC1_ConfigClockSource(&TCC1, TC_CLKSEL_OFF_gc );//DIV1024              
        TC1_ConfigClockSource(&TCD1, TC_CLKSEL_OFF_gc );//DIV1024              
      }
    }
    //--------------
    ISR(PORTC_INT0_vect){}
    ISR(PORTC_INT1_vect){}
    
    /// PORTR interrupt vectors
    ISR(PORTR_INT0_vect){}
    ISR(PORTR_INT1_vect){}
    
    /// DMA interrupt vectors
    ISR(DMA_CH0_vect){}
    ISR(DMA_CH1_vect){}
    ISR(DMA_CH2_vect){}
    ISR(DMA_CH3_vect){}
    
    /// RTC interrupt vectors
    ISR(RTC_OVF_vect){}
    ISR(RTC_COMP_vect){}
    
    /// TWIC interrupt vectors
    ISR(TWIC_TWIS_vect){}
    ISR(TWIC_TWIM_vect){}
    
    /// TCC0 interrupt vectors
    //ISR(TCC0_OVF_vect){}
    ISR(TCC0_ERR_vect){}
    ISR(TCC0_CCA_vect){}
    ISR(TCC0_CCB_vect){}
    ISR(TCC0_CCC_vect){}
    ISR(TCC0_CCD_vect){}
    
    /// TCC1 interrupt vectors
    //ISR(TCC1_OVF_vect){}
    ISR(TCC1_ERR_vect){}
    ISR(TCC1_CCA_vect){}
    ISR(TCC1_CCB_vect){}
    
    /// SPIC interrupt vectors
    ISR(SPIC_INT_vect){}
    
    /// USARTC0 interrupt vectors
    ISR(USARTC0_RXC_vect){}
    ISR(USARTC0_DRE_vect){}
    ISR(USARTC0_TXC_vect){}
    
    /// USARTC1 interrupt vectors
    ISR(USARTC1_RXC_vect){}
    ISR(USARTC1_DRE_vect){}
    ISR(USARTC1_TXC_vect){}
    
    /// AES interrupt vectors
    ISR(AES_INT_vect){}
    
    /// NVM interrupt vectors
    ISR(NVM_EE_vect){}
    ISR(NVM_SPM_vect){}
    
    /// PORTB interrupt vectors
    ISR(PORTB_INT0_vect){}
    ISR(PORTB_INT1_vect){}
    
    /// PORTE interrupt vectors
    ISR(PORTE_INT0_vect){}
    ISR(PORTE_INT1_vect){}
    
    /// TWIE interrupt vectors
    ISR(TWIE_TWIS_vect){}
    ISR(TWIE_TWIM_vect){}
    
    /// TCE0 interrupt vectors
    ISR(TCE0_OVF_vect){}
    ISR(TCE0_ERR_vect){}
    ISR(TCE0_CCA_vect){}
    ISR(TCE0_CCB_vect){}
    ISR(TCE0_CCC_vect){}
    ISR(TCE0_CCD_vect){}
    
    /// TCE1 interrupt vectors
    
    /// USARTE0 interrupt vectors
    ISR(USARTE0_RXC_vect){}
    ISR(USARTE0_DRE_vect){}
    ISR(USARTE0_TXC_vect){}
    
    /// PORTD interrupt vectors
    ISR(PORTD_INT0_vect){}
    ISR(PORTD_INT1_vect){}
    
    /// PORTA interrupt vectors
    //ISR(PORTA_INT0_vect){}
    ISR(PORTA_INT1_vect){}
    
    /// ACA interrupt vectors
    ISR(ACA_ACW_vect){}
    ISR(ACA_AC1_vect){}
    ISR(ACA_AC0_vect){}
    
    /// ADCA interrupt vectors
    ISR(ADCA_CH0_vect){}
    ISR(ADCA_CH1_vect){}
    ISR(ADCA_CH2_vect){}
    ISR(ADCA_CH3_vect){}
    
    /// TCD0 interrupt vectors
    //ISR(TCD0_OVF_vect){}
    ISR(TCD0_ERR_vect){}
    ISR(TCD0_CCA_vect){}
    ISR(TCD0_CCB_vect){}
    ISR(TCD0_CCC_vect){}
    ISR(TCD0_CCD_vect){}
    
    /// TCD1 interrupt vectors
    //ISR(TCD1_OVF_vect){}
    ISR(TCD1_ERR_vect){}
    ISR(TCD1_CCA_vect){}
    ISR(TCD1_CCB_vect){}
    
    /// SPID interrupt vectors
    ISR(SPID_INT_vect){}
    
    /// USARTD0 interrupt vectors
    ISR(USARTD0_RXC_vect){}
    ISR(USARTD0_DRE_vect){}
    ISR(USARTD0_TXC_vect){}
    
    /// USARTD1 interrupt vectors
    ISR(USARTD1_RXC_vect){}
    ISR(USARTD1_DRE_vect){}
    ISR(USARTD1_TXC_vect){}
    فایل های پیوست شده
    شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
    هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
    چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

    #2
    پاسخ : هنگ کردن برنامه

    از کجا میدونید خارج میشه ولی برنامه اجرا نمیکنه؟
    من فکر میکنم تو یه حلقه گیر میکنه اگه میتونید این رو بررسی کنید ببینید به چه صورته
    تو هر کدوم از این حلقه ها یه قطع و وصل کردن LED بزارید ببینید مشکل همینه
    یا اصلا وقفه یه تایمر با اولویت بالا رو باهاش همون کار رو بکنید

    دیدگاه


      #3
      پاسخ : هنگ کردن برنامه

      نوشته اصلی توسط شهریار رجب زاده
      از کجا میدونید خارج میشه ولی برنامه اجرا نمیکنه؟
      به این خاطر که در حلقه اصلی برنامه یه بیت رو TGLآ‌ میکنم ولی بعد از هنگ کردن اینکار متوقف میشه و دیگه انجام نمیشه. در حلقه اصلی من هم هیچ حلقه ای نیست به غیر از 1 یا 2 تا حلقه که TGL رو در اون حلقه ها هم گذاشتم ولی وقتی برنامه هنگ میکنه عملیات TGL در هر کجای حلقه اصلی باشه متوقف میشه.
      شواهد اینطوری نشون میده که برنامه فقط داره وقفه ها رو اجرا میکنه. در حالی که بین دو تا وقفه بیش از 2 میلی ثانیه زمان داره که به راحتی میتونه در این زمان کل حلقه اصلی رو اجرا کنه ولی این اتفاق نمیافته.

      نوشته اصلی توسط شهریار رجب زاده
      یا اصلا وقفه یه تایمر با اولویت بالا رو باهاش همون کار رو بکنید
      برنامه از نظر زمانبندی تقریبا بلادرنگ هست نمیتونم اینکار رو انجام بدم. اگه اینکار رو انجام بدم عملیات وقفه جاهای دیگه مختل میشه که اولویتشون باید بیشتر باشه.
      به هر حال چیزی به اون یقین دارم این هست که هر اتفاقی می افته مربوط به تابع SD_read میشه. چون همونطور که عرض کردم اگه به جای فراخونی این تابع در وقفه یه تاخیر با زمان برابر مثلا 2.6 میلی ثانیه بذارم برنامه ابدا هنگ نمیکنه. ولی زمانی که تابع SD_read رو اجرا میکنه بعد از چند ثانیه هنگ میکنه.
      با سپاس
      شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
      هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
      چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

      دیدگاه


        #4
        پاسخ : هنگ کردن برنامه

        ببین حجم جافظه مصرفیت چقدره. شاید مشکل پر شدن استک برات پیش میاد و به ما تبع اون میکرو توی لوپ میفته.
        بخاطر همین موقع برگشت از یک تابع آدرس برگشت رو گم میکنه و سر از کهریزک در میاره. سفر بی بازگشت!! :mrgreen:

        دیدگاه


          #5
          پاسخ : هنگ کردن برنامه

          رضا جان ممنون از توجه شما:
          RSTACK=500
          CSTACK=0x300
          HEAP=0x100
          تنظیمات رو اینطوری گذاشتم شرایط تفاوتی نمیکنه. کم و زیاد هم کردم اتفاق تازه ای نمی افته.
          با سپاس مجدد.
          شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
          هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
          چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

          دیدگاه


            #6
            پاسخ : هنگ کردن برنامه

            مشکل از مموری و سخت افزار اون قسمت شاید باشه
            احتمالا تابعی استفاده شده که منتظر میمونه تا فیدبک بیاد
            که نمیاد و همونجا برنامه گیر میکنه
            هرچه سعی کنیم لایه های نرم افزاری زیاد کرده و از سخت افزار دور کنیم مشکلات(باگ ها) کمتر خواهد شد(امنیت بیشتری خواهید داشت)
            بهترین جواب دهنده برای سوال شما، خود شما هستید البته بعد تلاش،پشتکار و مطالعه بیشتر
            میدونی مشکل ما کجاست؟سرمایه و مغز ها رو نمیتونیم یکجا جمع کنیم...

            تعدادی ماژول GPS GP5MX1513F1 با بالاتریت حساسیت -170db به قیمت خرید بفروش میرسد

            دیدگاه


              #7
              پاسخ : هنگ کردن برنامه

              نوشته اصلی توسط n340
              مشکل از مموری و سخت افزار اون قسمت شاید باشه
              احتمالا تابعی استفاده شده که منتظر میمونه تا فیدبک بیاد
              که نمیاد و همونجا برنامه گیر میکنه
              اگه توابعی که قراره پاسخ بدن، پاسخ ندن برنامه قفل میشه و دیگه نمیتونه بلادرنگ از کارت بخونه.
              در توضیح بگم که برنامه در حال پخش یه فایل صوتیه. اگر به هر علتی کارت حافظه پاسخ نده پخش صدا با اختلال مواجه میشه.این اتفاق نمی افته.
              حلقه های دیگری هم که در برنامه دارم رو امتحان کرده برنامه اونجا هم نمونده.

              شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
              هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
              چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

              دیدگاه


                #8
                پاسخ : هنگ کردن برنامه

                کد فایل main رو در پست اول قرار دادم.
                با سپاس
                شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
                هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
                چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

                دیدگاه


                  #9
                  پاسخ : هنگ کردن برنامه

                  نوشته اصلی توسط محمد نحوی
                  به این خاطر که در حلقه اصلی برنامه یه بیت رو TGLآ‌ میکنم ولی بعد از هنگ کردن اینکار متوقف میشه و دیگه انجام نمیشه. در حلقه اصلی من هم هیچ حلقه ای نیست به غیر از 1 یا 2 تا حلقه که TGL رو در اون حلقه ها هم گذاشتم ولی وقتی برنامه هنگ میکنه عملیات TGL در هر کجای حلقه اصلی باشه متوقف میشه.
                  شواهد اینطوری نشون میده که برنامه فقط داره وقفه ها رو اجرا میکنه. در حالی که بین دو تا وقفه بیش از 2 میلی ثانیه زمان داره که به راحتی میتونه در این زمان کل حلقه اصلی رو اجرا کنه ولی این اتفاق نمیافته.
                  برنامه از نظر زمانبندی تقریبا بلادرنگ هست نمیتونم اینکار رو انجام بدم. اگه اینکار رو انجام بدم عملیات وقفه جاهای دیگه مختل میشه که اولویتشون باید بیشتر باشه.
                  به هر حال چیزی به اون یقین دارم این هست که هر اتفاقی می افته مربوط به تابع SD_read میشه. چون همونطور که عرض کردم اگه به جای فراخونی این تابع در وقفه یه تاخیر با زمان برابر مثلا 2.6 میلی ثانیه بذارم برنامه ابدا هنگ نمیکنه. ولی زمانی که تابع SD_read رو اجرا میکنه بعد از چند ثانیه هنگ میکنه.
                  با سپاس
                  لازم نیست روشن و خاموش شدن LED رو ببینید توی وقفه میتونید سیگنال سریع درست کنید و با اسیلوسکوپ ببینید
                  با کارت های درگه هم امتحان کنید شاید مسئله حل شد ولی نظر من گیر کردن تو یه LOOP هستش
                  اون وقفه هایی که اولویتشون بالاتره رو سطحشو بالا ببرید اگر وقفه با سطح بالاتر خواست اجرا بشه این وقفه رو قطع میکنه و خودشو اجرا میکنه و بعد میاد سر این وقفه باقی مونده

                  دیدگاه


                    #10
                    پاسخ : هنگ کردن برنامه

                    فکر کنم آخر این صحبت ها بدون داشتن اصل کد یه کمی تا قسمتی وقت تلف کردن باشه. چون واقعا ممکنه یک باگ برنامه نویسی وسط باشه که نه شما متوجه اش باشین نه کسی بتونه کاری کنه.

                    دیدگاه


                      #11
                      پاسخ : هنگ کردن برنامه

                      من به چند مسئله اشاره می کنم تا شاید برای حل مشکل شما مفید واقع شود. اول اینکه مقادیری که برای RSTACK و CSTACK و HEAPSIZE در نظر می گیرید باید برمبنای فایلهای lst و map باشد و با حدس و سعی و خطا نمی توان در این مورد تصمیم گیری کرد. مورد دوم اینکه بعد از بازگشت از هر وقفه، همیشه یک دستور از حلقه اصلی اجرا می شود و بعد به وقفه بعدی وارد می شود( یک دستور اسمبلی). بنابراین امکان اجرا نشدن برنامه حلقه اصلی به دلیل وقفه های متعدد وجود ندارد. اما نوع برنامه نویسی می تواند سبب اختلال در روند انجام حلقه اصلی شود. مثلا اگر بنا باشد پارامتری از حلقه اصلی به وقفه پاس شود، اما به دلیل وقفه های متعدد و اخلال در رابطه متقابل بین وقفه و برنامه اصلی، نوعی هنگ کردن بوجود بیاید. مسئله بعدی این است که انجام عملیات پر حجم در روتین وقفه و معطل نگه داشتن CPU در آن کار چندان اصولی نیست و در برنامه های با بار پردازشی بالا می تواند منجر به مشکلاتی نظیر همین مورد اخیر گردد. مورد آخر این است که در برنامه شما نوعی معطلی برای پاسخ دادن یک وسیله دیگر وجود دارد که زمان پاسخگویی آن عدد متغیری است و شما باید این زمان را در بدترین شرایط حساب کنید (مثلا 80 یا 81 باری که برنامه در یک حلقه، منتظر پاسخگویی صحیح می ماند).
                      اوژن: به معنای افکننده و شکست دهنده است
                      دانایی، توانایی است-Knowledge is POWER
                      برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                      وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                      قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                      اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                      ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                      دیدگاه


                        #12
                        پاسخ : هنگ کردن برنامه

                        نوشته اصلی توسط شهریار رجب زاده
                        لازم نیست روشن و خاموش شدن LED رو ببینید توی وقفه میتونید سیگنال سریع درست کنید و با اسیلوسکوپ ببینید
                        با کارت های درگه هم امتحان کنید شاید مسئله حل شد ولی نظر من گیر کردن تو یه LOOP هستش
                        اون وقفه هایی که اولویتشون بالاتره رو سطحشو بالا ببرید اگر وقفه با سطح بالاتر خواست اجرا بشه این وقفه رو قطع میکنه و خودشو اجرا میکنه و بعد میاد سر این وقفه باقی مونده
                        بله با اسکوپ نگاه میکنم.
                        کارت مشکلی نداره امتحان کردم در ضمن برنامه باید با کارت های مختلف جواب بده.
                        در مورد اولویت هم اولویت ها طوری تنظیم شده که برنامه به درستی کار میکنه. اولویت وقفه ای که زمان اجرا اون طولانی هست LOWآ‌تعریف شده تا در کار بقیه اخلال ایجاد نکنه که این اتفاق هم نمیفته و برنامه به درستی کار میکنه.
                        شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
                        هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
                        چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

                        دیدگاه


                          #13
                          پاسخ : هنگ کردن برنامه

                          نوشته اصلی توسط reza_agha
                          فکر کنم آخر این صحبت ها بدون داشتن اصل کد یه کمی تا قسمتی وقت تلف کردن باشه. چون واقعا ممکنه یک باگ برنامه نویسی وسط باشه که نه شما متوجه اش باشین نه کسی بتونه کاری کنه.
                          رضا جان من گفتم کد مفصل هست ممکنه باعث سردرگمی بشه. به این خاطر قرار نداده بود.
                          به هر حال در پست اول فایل main.c رو گذاشتم.
                          با سپاس
                          شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
                          هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
                          چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

                          دیدگاه


                            #14
                            پاسخ : هنگ کردن برنامه

                            نوشته اصلی توسط طراح
                            اول اینکه مقادیری که برای RSTACK و CSTACK و HEAPSIZE در نظر می گیرید باید برمبنای فایلهای lst و map باشد و با حدس و سعی و خطا نمی توان در این مورد تصمیم گیری کرد.
                            به چه صورت من فایل map رو در همین پست قرار دادم اگه امکان داره بفرمایید چطوری از روی این فایل میشه سایز استک رو تعیین کرد.
                            نوشته اصلی توسط طراح
                            مورد دوم اینکه بعد از بازگشت از هر وقفه، همیشه یک دستور از حلقه اصلی اجرا می شود و بعد به وقفه بعدی وارد می شود( یک دستور اسمبلی). بنابراین امکان اجرا نشدن برنامه حلقه اصلی به دلیل وقفه های متعدد وجود ندارد. اما نوع برنامه نویسی می تواند سبب اختلال در روند انجام حلقه اصلی شود. مثلا اگر بنا باشد پارامتری از حلقه اصلی به وقفه پاس شود، اما به دلیل وقفه های متعدد و اخلال در رابطه متقابل بین وقفه و برنامه اصلی، نوعی هنگ کردن بوجود بیاید.
                            تعداد وقفه های من زیاد نیست. یک وقفه دارم که هر 62.5 میکرو ثانیه فراخونی میشه که زمان اجرای اون 2 میکرو ثانیه هست.
                            یک وقفه هم دارم که هر 3 میلی ثانیه فراخونی میشه و زمان اجرای اون حداکثر 2.5 میکرو ثانیه هست.
                            بقیه وقفه ها همواره فعال نیست، فعال و غیر فعال میشن.

                            برنامه من یک جا در حلقه اصلی منتظر پاسخ از وقفه میمونه ولی من چک کردم و یه TGL در اون حلقه گذاشتم و به این نتیجه رسیدم که زمانی که برنامه هنگ میکنه در اون حلقه نیست حتی میتونم بگم هیچ خطی از خطوط حلقه اصلی رو اجرا نمیکنه.
                            نوشته اصلی توسط طراح
                            مسئله بعدی این است که انجام عملیات پر حجم در روتین وقفه و معطل نگه داشتن CPU در آن کار چندان اصولی نیست و در برنامه های با بار پردازشی بالا می تواند منجر به مشکلاتی نظیر همین مورد اخیر گردد.
                            بله این دقیقا نکته ای هست که همیشه اون رو رعایت میکنم و در این مسئله هم به نظر رسید اگه کار در وقفه انجام بشه تداخل زمانی کمتر خواهد بود. من اجرای روتین طولانی رو از وقفه برداشتم مشکلم حل شد ولی واقعا کنجکاوا بدونم کجای برنامه ایراد داره.
                            نوشته اصلی توسط طراح
                            مورد آخر این است که در برنامه شما نوعی معطلی برای پاسخ دادن یک وسیله دیگر وجود دارد که زمان پاسخگویی آن عدد متغیری است و شما باید این زمان را در بدترین شرایط حساب کنید (مثلا 80 یا 81 باری که برنامه در یک حلقه، منتظر پاسخگویی صحیح می ماند).
                            بله بدترین زمان رو در نظر گرفتم. زمان عادی 2 میلی ثانیه هست من 2.6 میلی ثانیه در نظر گرفته بودم. روی اسکوپ که چک میکردم حداکثر زمان تاخیر کمتر از 2.3 میلی ثانیه بود.

                            من کل پروژه رو هم قرار میدم در پست اول. شاید واقعا یه جواب خیلی ساده داره که از چشم من دور مونده.
                            دوستان یه نگاهی بندازید ممنون میشم.
                            با سپاس فراوان
                            فایل های پیوست شده
                            شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
                            هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
                            چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

                            دیدگاه


                              #15
                              پاسخ : هنگ کردن برنامه

                              چند تا مسئله:
                              1- در خیلی جاهای برنامه اومده که خواستین وقفه هارو غیر فعال و فعال کنین. یعنی در قسمتی از اجرای کد مطمئن باشین وقفه غیر فعاله. استفاده محض از cli انجام عمل و سپس sei کار درستی نیست. کدتون رو به این صورت بنویسین:

                              uint8_t sr = SREG;
                              cli();

                              انجام عمل

                              SREG = sr;


                              با استفاده از این کد حتی اگر قبل از اجرای این کد وقفه ها خفه باشن بازهم بعد از اجرای اون وقفه ها خفه میمونن و اگر فعال بوده باشن دوباره فعال میشن. یعنی مطمئنا در طی این مدت (داخل این کد) وقفه ها غیر فعال هستن ولی در ادامه کد عین حالتی که قبل از اجرای کد بوده. این کد این حسن رو داره که میتونه بدون ایجاد اختلال حتی از درون یک وقفه صدا زده بشه. بجای این کار هم میتونین از ماکروهای زیر استفاده کنین:

                              AVR_ENTER_CRITICAL_REGION()
                              انجام عمل
                              AVR_LEAVE_CRITICAL_REGION()



                              2- شاید طبق معمول من درست کد رو متوجه نشده باشم اما فکر کنم کدتون یه جاییش مشکل داره. طبق کد تابع SD_Read با شماره سکتور کار میکنه. ولی در کد اصلی در TCC1_OVF_vect مقدار SD_Add با 0x200 یا همون 512 جمع میشه و به این تابع ارسال میشه یعنی 512 بایت - بایت جلو میره ولی چون آرگومان تابع بر اساس شماره سکتور هست این مقدار باید یکی یکی بالا بره.

                              3- شما وقفه هایی دارین که زمان زیادی از میکرو رو مصرف میکنه. در حلقه اصلی تاخیراتی مثل 3000 میکرو ثانیه دارین.چون این تاخیرات با لوپ زدن ساخته میشه؛ این 3000 میکرو ثانیه ممکنه خیلی بیش از اینا بشه (چون وسط تاخیر وقفه ها میان و میرن). بهتره برای ایجاد این میزان تاخیر از تایمر استفاده بشه. و گرنه معلوم نیست این 3000 میکرو ثانیه چند میلی ثانیه دربیاد.

                              4- جسارتا! برنامه تون یه کمی برای من دیر پزه!! :mrgreen:
                              شما که رم به اندازه کافی دارین. چرا از USART ها در حالت SPI استفاده نمیکنین تا بتونین DMA مربوطه رو بکار بگیرین و عمده خوندن اطلاعات از روی SD رو (یک سکتور) با استفاده از DMA انجام بدین؟ برای این کار میتونین دو تا بافر 512 بایتی بگیرین و با حداقل زمان اجرای کد فایلتون رو بخونین (از روی SD) و بنوازین (روی DAC).

                              پی نوشت:
                              همونطور که میبینین چون نتونستم مشکل رو حل کنم؛ صورت مسئله تون رو عوض کردم!
                              :mrgreen: :mrgreen:

                              دیدگاه

                              لطفا صبر کنید...
                              X