int get_AC1(void) { union { unsigned int Word; unsigned char Byte[2]; } AC1; // AC1 // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // START (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = 0xEE; // SLA+W TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+W (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = 0xAA; // 0xAA TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // 0xAA (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // REPEATED START (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = 0xEF; // SLA+R TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+R (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // ACK (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- AC1.Byte[1] = TWDR; // MSB TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // NACK (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- AC1.Byte[0] = TWDR; // LSB TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // STOP (0<<TWWC); // ---------------------------------------- return AC1.Word; }
int get_Data(unsigned char Register_adress) { union { unsigned int Word; unsigned char Byte[2]; } Data; // Data // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // START (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = 0xEE; // SLA+W TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+W (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = Register_adress; // Register_adress TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Register_adress (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // REPEATED START (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWDR = 0xEF; // SLA+R TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+R (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // ACK (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- Data.Byte[1] = TWDR; // MSB TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // NACK (0<<TWWC); while (!(TWCR & (1<<TWINT))) // TWINT ; // ---------------------------------------- Data.Byte[0] = TWDR; // LSB TWCR = (1<<TWEN)| // TWI (0<<TWIE)|(1<<TWINT)| // (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // STOP (0<<TWWC); // ---------------------------------------- return Data.Word; }
struct { short AC1; short AC2; short AC3; unsigned short AC4; unsigned short AC5; unsigned short AC6; short B1; short B2; short MB; short MC; short MD; } BMP085_EEPROM; ... static void get_EEPROM(void) { BMP085_EEPROM.AC1 = get_Data(0xAA); BMP085_EEPROM.AC2 = get_Data(0xAC); BMP085_EEPROM.AC3 = get_Data(0xAE); BMP085_EEPROM.AC4 = get_Data(0xB0); BMP085_EEPROM.AC5 = get_Data(0xB2); BMP085_EEPROM.AC6 = get_Data(0xB4); BMP085_EEPROM.B1 = get_Data(0xB6); BMP085_EEPROM.B2 = get_Data(0xB8); BMP085_EEPROM.MB = get_Data(0xBA); BMP085_EEPROM.MC = get_Data(0xBC); BMP085_EEPROM.MD = get_Data(0xBE); }
struct { unsigned char SLA; // Slave address unsigned char *pW; // ? unsigned char nW; // ? unsigned char *pR; // ? unsigned char nR; // ? } TWI;
unsigned char Register_address; ... void get_AC1(void) { Register_address = 0xAA; // Register address TWI.SLA = 0x77; // Slave address BMP085 TWI.pW = &Register_address; // TWI.nW = 1; // ? TWI.pR = &BMP085_EEPROM.AC1; // ? TWI.nR = 2; // ? TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // START (0<<TWWC); }
ISR(TWI_vect) { /* ----------------------------------------------------------------------------------- Jump table which is stored in flash ------------------------------------------------------------------------------------*/ static const void * const twi_list[] PROGMEM = {&&TWI_00, &&TWI_08, &&TWI_10, &&TWI_18, &&TWI_20, &&TWI_28, &&TWI_30, &&TWI_38, &&TWI_40, &&TWI_48, &&TWI_50, &&TWI_58, &&TWI_60, &&TWI_68, &&TWI_70, &&TWI_78, &&TWI_80, &&TWI_88, &&TWI_90, &&TWI_98, &&TWI_A0, &&TWI_A8, &&TWI_B0, &&TWI_B8, &&TWI_C0, &&TWI_C8, &&TWI_F8}; /* ----------------------------------------------------------------------------------- Jump to label, address of which is in twi_list[TWSR>>3] ------------------------------------------------------------------------------------*/ goto *(pgm_read_word(&(twi_list[TWSR>>3]))); /* ----------------------------------------------------------------------------------- Bus error handler ------------------------------------------------------------------------------------*/ TWI_00: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- A START condition has been transmitted A repeated START condition has been transmitted nW = nR = 0: STOP condition will be generated nW > 0, nR - don't care: SLA+W will be send nW = 0, nR > 0: SLA+R will be send ------------------------------------------------------------------------------------*/ TWI_08: TWI_10: if (TWI.nW != 0) // SLA+W will be send TWDR = (TWI.SLA)<<1; else if (TWI.nR != 0) // SLA+R will be send TWDR = (TWI.SLA)<<1 | 1<<0; else // STOP condition will be generated goto STOP; TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+R/W (0<<TWWC); return; /* ----------------------------------------------------------------------------------- SLA+W has been transmitted; ACK has been received Data byte has been transmitted; ACK has been received nW > 0, nR - don't care: Data byte will be transmitted and ACK or NOT ACK will be received nW = 0, nR > 0: Repeated START will be transmitted nW = nR = 0: STOP condition will be generated ------------------------------------------------------------------------------------*/ TWI_18: TWI_28: if (TWI.nW != 0) { // Data byte will be transmitted and ACK or NOT ACK will be received TWDR = *TWI.pW++; TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // (0<<TWWC); TWI.nW--; } else if (TWI.nR != 0) // Repeated START will be transmitted TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // START (0<<TWWC); else // STOP condition will be generated goto STOP; return; /* ----------------------------------------------------------------------------------- SLA+W has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_20: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Data byte has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_30: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Arbitration lost in SLA+W or data bytes Arbitration lost in SLA+R or NOT ACK bit ------------------------------------------------------------------------------------*/ TWI_38: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- SLA+R has been transmitted; ACK has been received nR = 1: Data byte will be received and NOT ACK will be returned nR > 1: Data byte will be received and ACK will be returned ------------------------------------------------------------------------------------*/ TWI_40: if (TWI.nR == 1) // Data byte will be received and NOT ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + NACK (0<<TWWC); else // Data byte will be received and ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + ACK (0<<TWWC); return; /* ----------------------------------------------------------------------------------- SLA+R has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_48: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Data byte has been received; ACK has been returned nR = 2: Data byte will be received and NOT ACK will be returned nR > 2: Data byte will be received and ACK will be returned ------------------------------------------------------------------------------------*/ TWI_50: // Read data *TWI.pR++ = TWDR; if (TWI.nR-- == 2) // Data byte will be received and NOT ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + NACK (0<<TWWC); else // Data byte will be received and ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + ACK (0<<TWWC); return; /* ----------------------------------------------------------------------------------- Data byte has been received; NOT ACK has been returned Repeated START will be transmitted STOP condition will be transmitted and TWSTO Flag will be reset STOP condition followed by a START condition will be transmitted and TWSTO Flag will be reset ------------------------------------------------------------------------------------*/ TWI_58: // Read data *TWI.pR = TWDR; TWI_60: TWI_68: TWI_70: TWI_78: TWI_80: TWI_88: TWI_90: TWI_98: TWI_A0: TWI_A8: TWI_B0: TWI_B8: TWI_C0: TWI_C8: TWI_F8: // STOP condition will be transmitted and TWSTO Flag will be reset STOP: TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // + NACK (0<<TWWC); }
#define size 8 ... typedef struct { unsigned char SLA; // Slave address unsigned char *pW; // ? unsigned char nW; // ? unsigned char *pR; // ? unsigned char nR; // ? } twi; twi TWI[size];
unsigned char buf[size]; ... void get_AC1(void) { volatile twi *pl; // twi buf[0] = 0xAA; // Register address pl->SLA = 0x77; // Slave address BMP085 pl->pW = buf; // pl->nW = 1; // ? pl->pR = buf; // ? pl->nR = 2; // ? Scheduler(pl); // }
void Scheduler(twi *pl) { if (tail-head !=1 && head-tail != size-1) // , { twi *pg = &TWI[head]; // pg->SLA = pl->SLA; // SLA pg->pW = pl->pW; // *pW pg->nW = pl->nW; // nW pg->pR = pl->pR; // *pR pg->nR = pl->nR; // nR head = (head+1)&(size-1); // - if (!flag.twi_run) // TWI ( 0) { flag.twi_run = 1; // 1 TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| (0<<TWWC); } } }
ISR(TWI_vect) { twi *p = &TWI[tail]; /* ----------------------------------------------------------------------------------- Jump table which is stored in flash ------------------------------------------------------------------------------------*/ static const void * const twi_list[] PROGMEM = {&&TWI_00, &&TWI_08, &&TWI_10, &&TWI_18, &&TWI_20, &&TWI_28, &&TWI_30, &&TWI_38, &&TWI_40, &&TWI_48, &&TWI_50, &&TWI_58, &&TWI_60, &&TWI_68, &&TWI_70, &&TWI_78, &&TWI_80, &&TWI_88, &&TWI_90, &&TWI_98, &&TWI_A0, &&TWI_A8, &&TWI_B0, &&TWI_B8, &&TWI_C0, &&TWI_C8, &&TWI_F8}; /* ----------------------------------------------------------------------------------- Jump to label, address of which is in twi_list[TWSR>>3] ------------------------------------------------------------------------------------*/ goto *(pgm_read_word(&(twi_list[TWSR>>3]))); /* ----------------------------------------------------------------------------------- Bus error handler ------------------------------------------------------------------------------------*/ TWI_00: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- A START condition has been transmitted A repeated START condition has been transmitted nW = nR = 0: STOP condition will be generated nW > 0, nR - don't care: SLA+W will be send nW = 0, nR > 0: SLA+R will be send ------------------------------------------------------------------------------------*/ TWI_08: TWI_10: if (p->nW != 0) // SLA+W will be send TWDR = p->SLA<<1; else if (p->nR != 0) // SLA+R will be send TWDR = p->SLA<<1 | 1<<0; else // STOP condition will be generated goto STOP; TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // SLA+R/W (0<<TWWC); return; /* ----------------------------------------------------------------------------------- SLA+W has been transmitted; ACK has been received Data byte has been transmitted; ACK has been received nW > 0, nR - don't care: Data byte will be transmitted and ACK or NOT ACK will be received nW = 0, nR > 0: Repeated START will be transmitted nW = nR = 0: STOP condition will be generated ------------------------------------------------------------------------------------*/ TWI_18: TWI_28: if (p->nW != 0) { // Data byte will be transmitted and ACK or NOT ACK will be received TWDR = *p->pW; p->pW++; TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // (0<<TWWC); p->nW--; } else if (p->nR != 0) // Repeated START will be transmitted TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // START (0<<TWWC); else // STOP condition will be generated goto STOP; return; /* ----------------------------------------------------------------------------------- SLA+W has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_20: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Data byte has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_30: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Arbitration lost in SLA+W or data bytes Arbitration lost in SLA+R or NOT ACK bit ------------------------------------------------------------------------------------*/ TWI_38: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- SLA+R has been transmitted; ACK has been received nR = 1: Data byte will be received and NOT ACK will be returned nR > 1: Data byte will be received and ACK will be returned ------------------------------------------------------------------------------------*/ TWI_40: if (p->nR == 1) // Data byte will be received and NOT ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + NACK (0<<TWWC); else // Data byte will be received and ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + ACK (0<<TWWC); return; /* ----------------------------------------------------------------------------------- SLA+R has been transmitted; NOT ACK has been received ------------------------------------------------------------------------------------*/ TWI_48: // STOP condition will be generated goto STOP; /* ----------------------------------------------------------------------------------- Data byte has been received; ACK has been returned nR = 2: Data byte will be received and NOT ACK will be returned nR > 2: Data byte will be received and ACK will be returned ------------------------------------------------------------------------------------*/ TWI_50: // Read data *p->pR = TWDR; p->pR++; if (p->nR-- == 2) // Data byte will be received and NOT ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + NACK (0<<TWWC); else // Data byte will be received and ACK will be returned TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // + ACK (0<<TWWC); return; /* ----------------------------------------------------------------------------------- Data byte has been received; NOT ACK has been returned Repeated START will be transmitted STOP condition will be transmitted and TWSTO Flag will be reset STOP condition followed by a START condition will be transmitted and TWSTO Flag will be reset ------------------------------------------------------------------------------------*/ TWI_58: // Read data *p->pR = TWDR; TWI_60: TWI_68: TWI_70: TWI_78: TWI_80: TWI_88: TWI_90: TWI_98: TWI_A0: TWI_A8: TWI_B0: TWI_B8: TWI_C0: TWI_C8: TWI_F8: // STOP condition will be transmitted and TWSTO Flag will be reset STOP: tail = (tail+1)&(size-1); // tail 1, , if (head != tail) // head tail , TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(1<<TWSTA)|(1<<TWSTO)| // - (0<<TWWC); else // { TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| // ! (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // (0<<TWWC); flag.twi_run = 0; // } }
unsigned char bufTx[size]; unsigned char pos = 0; ... void get_AC1(void) { volatile twi *pl; // twi volatile uint8_t buf[] = {0xAA}; // Register address buf pl->SLA = 0x77; // Slave address BMP085 pl->pW = buf; // pl->nW = 1; // ? pl->pR = buf; // ? pl->nR = 2; // ? Scheduler(pl); // } // ============================================ void get_AC2(void) { volatile twi *pl; // twi volatile uint8_t buf[] = {0xAC}; // Register address buf pl->SLA = 0x77; // Slave address BMP085 pl->pW = buf; // pl->nW = 1; // ? pl->pR = buf; // ? pl->nR = 2; // ? Scheduler(pl); // } // ============================================ void Scheduler(volatile twi *pl) { if (tail-head !=1 && head-tail != size-1) // , { twi *pg = &TWI[head]; // pg->SLA = pl->SLA; // SLA pg->pW = pushToBuf(pl->pW,pl->nW); // , // buf bufTX pg->nW = pl->nW; // nW pg->pR = pl->pR; // *pR pg->nR = pl->nR; // nR head = (head+1)&(size-1); // - if (!flag.twi_run) // TWI ( 0) { flag.twi_run = 1; // 1 TWCR = (1<<TWEN)| // TWI (1<<TWIE)|(1<<TWINT)| (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| (0<<TWWC); } } } // ============================================ unsigned char *pushToBuf(unsigned char *buf, unsigned char n) { unsigned char *p = &bufTx[pos]; // do { bufTx[pos++] = *buf++; // buf bufTx pos &= size-1; // - } while (--n); // n return p; // p }
head = (head+1)&(size-1); tail = (tail+1)&(size-1); pos &= size-1;
Source: https://habr.com/ru/post/193456/
All Articles