/* 6-22-11 Aaron Weiss aaron at sparkfun dot com OSHW 1.0 License, http://freedomdefined.org/OSHW LiPo Fuel Gauge Example Code Uses the MAX17043 ATmega328@3.3V w/ external 8MHz resonator HF: 0xDA, LF: 0xFF, EF: 0xF8 PIN CONNECTIONS: VCC - No connect or connect to system power GND - GND SDA - PC4 SCL - PC5 ALT - PD2 QST - GND or a hardware reset pin Default Baud Rate: 9600bps 8N1 Firmware: v10 Hardware: v10 Usage: Displays the raw A/D value in mV and percentage of charge every second */ #include #include #include #include #include #include "types.h" #include "defs.h" #include "i2c.h" #define FOSC 8000000 #define BAUD 9600 #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask)) #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask)) #define STATUS_LED 5 ///===========Main Prototypes=============================/////////////////////// void config(void); void power_on_reset(void); long read_ad(void); long read_config(void); void read_percent(void); void quick_start_reset(void); /////=====================================================/////////////////////// ///============Initialize Prototypes=====================/////////////////////// void ioinit(void); // initializes IO void UART_Init(unsigned int ubrr); static int uart_putchar(char c, FILE *stream); uint8_t uart_getchar(void); static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); void delay(uint16_t x); // general purpose delay /////===================================================//////////////////////// ///============I2C Prototypes=============////////////////// void i2cSendStart(void); void i2cSendStop(void); void i2cWaitForComplete(void); void i2cSendByte(unsigned char data); void i2cInit(void); void i2cHz(long uP_F, long scl_F); ///===========Global Vars=============================////////////////////////// volatile long i=0; //counts per second volatile double percent_decimal; /////===================================================//////////////////////// //=========MAIN================///////////////////////////////////////////////// ISR (INT0_vect) { //when charge drops below 32% turn on status LED sbi(PORTB, STATUS_LED); } ISR(TIMER1_OVF_vect) { //one second timer, prints values every second TCNT1 = 34286; //printf("config=%5ld, ", read_config()); printf("a/d=%5ld, ", read_ad()); read_percent(); } int main(void) { ioinit(); //Setup IO pins and defaults power_on_reset(); // reset MAX module upon MCU reset config(); while(1) { //put your additional code here } return (0); } void config(void) { /////////write config register/////////////// i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0x0C); //mode register i2cWaitForComplete(); i2cSendByte(0x97); i2cWaitForComplete(); i2cSendByte(0x00); //set alert to 32% i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); } void power_on_reset(void) { /////////write command register to reset/////////////// i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0xFE); //mode register i2cWaitForComplete(); i2cSendByte(0x54); i2cWaitForComplete(); i2cSendByte(0x00); i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); } long read_ad(void) { //0x6C write, 0x6D read uint16_t xm, xl; long temp, xo; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0x02); //mode register i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6D); //read from MAX i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xm = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cSendStop(); i2cSendStart(); temp = ((xl|(xm << 8)) >> 4); xo = 1.25* temp; //returns A/D value in mV return xo; } long read_config(void) { ///should read 38656 or 0x9700 before alert ///should read 38752 or 0x9760 after alert //0x6C write, 0x6D read uint16_t xm, xl; long xo; //////////read command register///////////// i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0x0C); //mode register i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6D); //read from MAX i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xm = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cSendStop(); i2cSendStart(); xo = xl|(xm << 8); return xo; } void read_percent(void) { //0x6C write, 0x6D read uint8_t xm, xl; //uint8_t xmh, xml, xlh, xll; //long xo; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0x04); //SOC register i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6D); //read from MAX i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xm = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); //high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cSendStop(); i2cSendStart(); //percent_decimal = (0.003906)*xl + xm; //xo = xl|(xm << 8); printf("percent=%d\n\r", xm); //printf("percent=%4.2f\n\r", percent_decimal); } void quick_start_reset(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x6C); //write MAX i2cWaitForComplete(); i2cSendByte(0x06); //mode register i2cWaitForComplete(); i2cSendByte(0x40); i2cWaitForComplete(); i2cSendByte(0x00); i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); } //////////////////////////////////////////////////////////////////////////////// ///==============Initializations=======================================///////// //////////////////////////////////////////////////////////////////////////////// void ioinit (void) { //1 = output, 0 = input DDRB = 0b11101111; //PB4 = MISO DDRC = 0b11111111; //Output on PORTC0, PORTC4 (SDA), PORTC5 (SCL), all others are inputs DDRD = 0b11110010; //PORTD (RX on PD0), input on PD2 ,out on PD5 for ATtiny motor enable PORTD |= (1<>8; UBRR0L = ubrr; // Enable receiver and transmitter UCSR0A = (0< 50 ; x--){ for ( y = 0 ; y < 200 ; y++){ asm volatile ("nop"); } } }