Зависает цикл while
- Войдите на сайт для отправки комментариев
День добрый много уважаемая публика
Суть проблемы такая. есть пустой цикл
while(TWIbusy);
TWIbusy это моя переменная. которая во премя работы TWI не равна нулю. При посылки на шину сигнала STOP данная переменная в обработчике прерывания ставится равной 0 и следовательно условие уже не выполняется. цикл должен прекратиться. но этого не происходит. Тоже самое с циклом for(;TWIbusy;);
Что интересно. Из прерывания я вывожу в порт значение переменной когда он ее обнуляет. И это действительно происходит. Если цикл сделать не пустой. а скажем воткнуть в тело Serial.print( TWIbusy);
то все хорошо. как только обработчик прерывания обнуляет значение данной переменной цикл прекращается. но стоит его оставить пустым(хотя я пробовал и бесполезные вычисления внутрь ставить) то он зависает намертво. пока не выведешь что то в порт. Подскажите в чем причина может быть? могу весь скеч скинуть
плата Arduino Uno если это важно
ну конечно код покажите
#define WRITE 0x00 // TWIBus WRITE command #define READ 0x01 // TWIBus READ command #define BMP085 0x77 // Device address for BMP085 // TWIBus states: // MT = Master Transmitter // MR = Master Receiver // ST = Slave transmitter (not implemented) // SR = Slave receiver (not implemented) #define TWIBusErr 0x00 // (all modes) BUS ERROR #define TWINoInfo 0xF8 // unknown state #define TWIStart 0x08 // (MT & MR) START transmitted #define TWIRestart 0x10 // (MT & MR) repeated START #define TWIMtAddAck 0x18 // (MT) Slave address + W transmitted; ACK received #define TWIMtAddNack 0x20 // (MT) Slave address + W transmitted; NACK received #define TWIMtDbAck 0x28 // (MT) data byte transmitted; ACK received #define TWIMtDbNack 0x30 // (MT) data byte transmitted; NACK received #define TWIMtArbLost 0x38 // (MT) arbitration lost #define TWIMrAddAck 0x40 // (MR) Slave address + R transmitted; ACK received #define TWIMrAddNack 0x48 // (MR) Slave address + R transmitted; NACK received #define TWIMrDbAck 0x50 // (MR) data byte rec'vd; ACK transmitted #define TWIMrDbNack 0x58 // (MR) data byte rec'vd; NACK transmitted #define TWSR_MASK 0xfc // Calibration values-------------------- int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) // so ...Temperature(...) must be called before ...Pressure(...). long b5; //---------------------------------------- char WrAdr, RdAdr; // slave address + Write (or Read) char TWIbusy; // This flag is set when a send or receive is started. It is cleared // by the ISR when the operation is finished char RW; // R/W command flag. 1=read, 0=write unsigned char txbuf[3]; // buffer of data to be transferred to BMP085 unsigned char rxbuf[3]; // buffer to hold data read from BMP085 unsigned char dispBuf[8]; // buffer for temperature to be displayed/////////////////////// unsigned char command; // command to be sent to BMP085 unsigned char byte2Send; // number of bytes to send to BMP085 unsigned char byte2Read; // number of bytes to read from BMP085 unsigned char wIndex; // index to txbuf unsigned char rIndex; // index to rxbuf void initTWI(void); void initBMP085(char config); void setup() { // put your setup code here, to run once: Serial.begin(57600); initTWI(); TWIbusy = 0; // initially TWI bus is not busy Serial.println( "Initializing BMP085..." ); //sei(); //Init BMP085 Calibration values initBMP085(0xAA); // initBMP085(0xAC); while(TWIbusy){ Serial.print(""); } ac1 = (int16_t)rxbuf[0]<<8 | rxbuf[1]; //------------------------------ } void loop() { // put your main code here, to run repeatedly: // ac1 = (int16_t)rxbuf[0]<<8 | rxbuf[1]; Serial.print( "ac1 = "); Serial.println( ac1, DEC ); delay(200); } // ------------------------------------------------------------------------------------------------------------ // The following function initializes the TWI module to operate at 400 kHz. // ------------------------------------------------------------------------------------------------------------ void initTWI(void) { TWBR = 0x0C; // set baud rate to 400 kHz (with prescaler set to 0) TWSR &= 0xFC;// " TWCR = 0x05; // enable TWI and its interrupt // DDRD = 0; // configure SCL and SDA pins to open drain } // ------------------------------------------------------------------------------------------------------------- // The following function Calibration values the BMP085. // ------------------------------------------------------------------------------------------------------------- void initBMP085(char config) { while(TWIbusy); // wait until TWI bus is idle TWIbusy = 1; // occupies the TWI bus (set to busy) RW = 1; // indicate read WrAdr = (BMP085<<1)|0; //set control byte to "BMP085 ID + W" RdAdr = (BMP085<<1)|1; //set read control byte to "BMP085 ID + R" command = config; byte2Send = 1; // number of bytes to be transferred byte2Read = 2; // number of bytes to be read TWCR = 0xA5; // generate a START condition } void stat(char aaa) { Serial.print( " -<>- " ); Serial.print( TWSR & TWSR_MASK, HEX ); Serial.print( " <-> " ); Serial.print( aaa, HEX ); Serial.println( " -<>- " ); } // ------------------------------------------------------------------------------------------------------------- // TWI module Interrupt Service Routine // ------------------------------------------------------------------------------------------------------------- ISR(TWI_vect) { switch (TWSR & 0xF8){ // Check the status code for the TWI module case TWIBusErr: TWCR = 0x95; // reset TWI bus break; case TWIStart: TWDR = WrAdr; // send slave ID + W TWCR = 0x85; // and clear TWINT flag break; // Master Transmitter/Receiver: Repeated START condition transmitted. // This state should only occur during a read, after the memory address // has been sent and acknowledged. case TWIRestart: TWDR = RdAdr; // send slave ID + R. TWCR = 0x85; // and clear the TWINT flag break; // Master Transmitter: Slave address + W transmitted. ACK received. case TWIMtAddAck: TWDR = command; // send a command to DS1631A. wIndex = 0; // write buffer starting index rIndex = 0; // read buffer starting index byte2Send--; TWCR = 0x85; // send out command and clear TWINT flag break; // Master Transmitter: Slave address + WRITE transmitted. NACK received. // The slave is not responding. Send a STOP followed by a START to try again. case TWIMtAddNack: TWCR = 0xB5; break; // Master Transmitter: Data byte transmitted. ACK received. // This state is used in both READ and WRITE operations. Check RW to find // out data transfer type. RW = 1 is read data; RW = 0 is write data case TWIMtDbAck: if (byte2Send==0){ // all bytes to be transmitted have been sent if (RW) { // If (R/W == READ), generate repeated START. TWCR = 0xA5; } else { TWIbusy = 0; // release TWI bus TWCR = 0x94; // If a write, generate a STOP condition. } } else { // send next data byte TWDR = txbuf[wIndex++]; TWCR = 0x85; // clear TWINT flag and trigger transmission byte2Send--; } break; // Master Transmitter: Data byte transmitted. NACK received. // Slave not responding. Send STOP followed by START to try again. case TWIMtDbNack: TWCR = 0xB5; // generate STOP and then START condition break; // Master Transmitter: Arbitration lost. // Should not occur. If so, restart transfer. case TWIMtArbLost: TWCR = 0xA5; // if MT lost in arbitration, wait until TWI bus idle and generate START break; // Master Receiver: Slave address + R transmitted. ACK received. // Set to transmit NACK after next transfer since it will be the last only byte. case TWIMrAddAck: if(byte2Read > 1) TWCR = 0xC5; // ACK sent on acknowledge cycle. else TWCR = 0x85; // read one byte only, assert NACK break; // Master Receiver: Slave address + READ transmitted. NACK received. // Slave not responding. Send repeated start to try again. case TWIMrAddNack: TWCR = 0xA5; // if receive NACK after sending address, generate RESTART break; // Data byte received. ACK transmitted. case TWIMrDbAck: byte2Read--; rxbuf[rIndex++] = TWDR; if(byte2Read == 1) TWCR = 0x85; // NACK the last byte else TWCR = 0xC5; // more than one byte to read, send ACK break; // Data byte received. NACK transmitted. // Read operation has completed. Read data register and send STOP. case TWIMrDbNack: rxbuf[rIndex] = TWDR; TWIbusy = 0; // Free TWI bus stat( TWIbusy ); //-------------------------------------------------------------------- TWCR = 0x95; // Assert STOP condition break; // All other status codes meaningless in this application. Reset communication. default: TWIbusy = 0; TWCR = 0x95; // Reset communication. break; } }69-71 строка это тот самый цикл. стоит вывод в порт убрать на нем все зависает
в 212 строке вывод в порт информации из обработчика прерывания который ставит TWIbusy в ноль
Это происходит четко
Благодарю. Работает