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