4651 views |3 replies
Last login 2016-5-10
Online Time 14 hours
Prestige 8 points
Points 0 points
I used the routine provided by TI and wrote it for pcf8591, but no matter what sub-address I write, I can only read address 0, which is the voltage value of IN0. Help: #include
#include
#include
#include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/ sysctl.h" #include "driverlib/timer.h" #include "driverlib/uart.h" #include "utils/softi2c.h" #include "utils/uartstdio.h" // // The I2C slave address of the AT24C08A EEPROM device. This address is based // on the A2 pin of the AT24C08A being pulled high on the board. // //********************************************** ***************************** #define SLAVE_ADDR 0x48 #define STATE_IDLE 0 #define STATE_WRITE_NEXT 1 #define STATE_WRITE_FINAL 2 #define STATE_WAIT_ACK 3 #define STATE_SEND_ACK 4 #define STATE_READ_ONE 5 #define STATE_READ_FIRST 6 #define STATE_READ_NEXT 7 #define STATE_READ_FINAL 8 #define STATE_READ_WAIT 9 static tSoftI2C g_sI2C; static uint8_t *g_pui8Data = 0; static uint32_t g_ui32Count = 0; static volatile uint32_t g_ui32State = STATE_IDLE; void InitConsole(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0, 115200, 16000000); } //************************************************ ******************************* // // The callback function for the SoftI2C module. // //***** *************************************************** ********************** void SoftI2CCallback(void) { SoftI2CIntClear(&g_sI2C); switch(g_ui32State) { case STATE_IDLE: { break; } case STATE_WRITE_NEXT: { SoftI2CDataPut(&g_sI2C, *g_pui8Data++); g_ui32Count--; SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_SEND_CONT); if(g_ui32Count == 1) { g_ui32State = STATE_WRITE_FINAL; } break; } case STATE_WRITE_FINAL: { SoftI2CDataPut(&g_sI2C, *g_pui8Data++); g_ui32Count--; SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_SEND_FINISH); g_ui32State = STATE_SEND_ACK; break; } case STATE_WAIT_ACK: { if(SoftI2CErr(&g_sI2C) == SOFTI2C_ERR_NONE) { SoftI2CDataGet(&g_sI2C); g_ui32State = STATE_IDLE; break; } } case STATE_SEND_ACK: { SoftI2CSlaveAddrSet(&g_sI2C, SLAVE_ADDR, true); SoftI2CControl(&g_sI2C,SOFTI2C_CMD_SINGLE_RECEIVE); g_ui32State = STATE_WAIT_ACK; break; } case STATE_READ_ONE: { SoftI2CSlaveAddrSet(&g_sI2C, SLAVE_ADDR, true); SoftI2CControl(&g_sI2C, SOFTI2C_CMD_SINGLE_RECEIVE); g_ui32State = STATE_READ_WAIT; break; } case STATE_READ_FIRST: { SoftI2CSlaveAddrSet(&g_sI2C, SLAVE_ADDR, true); SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_RECEIVE_START); g_ui32State = STATE_READ_NEXT; break; } case STATE_READ_NEXT: { *g_pui8Data++ = SoftI2CDataGet(&g_sI2C); g_ui32Count--; SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_RECEIVE_CONT); if(g_ui32Count == 2) { g_ui32State = STATE_READ_FINAL; } break; } case STATE_READ_FINAL: { *g_pui8Data++ = SoftI2CDataGet(&g_sI2C); g_ui32Count--; SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_RECEIVE_FINISH); g_ui32State = STATE_READ_WAIT; break; } case STATE_READ_WAIT: { *g_pui8Data++ = SoftI2CDataGet(&g_sI2C); g_ui32Count--; g_ui32State = STATE_IDLE; break; } } } //********************************************** ********************************** // // Write to the Atmel device. // // *************************************************** *************************** void AtmelWrite(uint8_t *pui8Data, uint32_t ui32Offset, uint32_t ui32Count) { g_pui8Data = pui8Data; g_ui32Count = ui32Count; /*if(ui32Count != 1) { g_ui32State = STATE_WRITE_NEXT; } else { g_ui32State = STATE_WRITE_FINAL; }*/ SoftI2CSlaveAddrSet(&g_sI2C, SLAVE_ADDR | (ui32Offset >> 8), false); SoftI2CDataPut(&g_sI2C, ui32Offset); SoftI2CControl(&g_sI2C, SOFTI2C_CMD_BURST_SEND_START); while(g_ui32State != STATE_IDLE) { } } void AtmelRead(uint8_t *pui8Data, uint32_t ui32Offset, uint32_t ui32Count) { g_pui8Data = pui8Data; g_ui32Count = ui32Count; if(ui32Count == 1) { g_ui32State = STATE_READ_ONE; } else { g_ui32State = STATE_READ_FIRST; } SoftI2CSlaveAddrSet(&g_sI2C, SLAVE_ADDR | (ui32Offset >> 8), false); SoftI2CDataPut(&g_sI2C, ui32Offset); SoftI2CControl(&g_sI2C, SOFTI2C_CMD_SINGLE_SEND); while(g_ui32State != STATE_IDLE) { } } void Timer0AIntHandler(void) { TimerIntClear(TIMER0_BASE,TIMER_TIMA_TIMEOUT); SoftI2CTimerTick(&g_sI2C); } void main(void) { uint8_t pui8Data[16] = {3}; uint8_t pui8DataGet[16] = {0}; uint32_t ui32Idx; SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3); memset(&g_sI2C, 0, sizeof(g_sI2C)); SoftI2CCallbackSet(&g_sI2C, SoftI2CCallback); SoftI2CSCLGPIOSet(&g_sI2C, GPIO_PORTB_BASE, GPIO_PIN_2); SoftI2CSDAGPIOSet(&g_sI2C, GPIO_PORTB_BASE, GPIO_PIN_3); SoftI2CInit(&g_sI2C); SoftI2CIntEnable(&g_sI2C); TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 40000); TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); IntMasterEnable(); IntEnable(INT_TIMER0A); TimerEnable(TIMER0_BASE, TIMER_A); InitConsole(); while(1) { UARTprintf("SoftI2C Atmel PCF8591 example\n"); UARTprintf("Write:"); for(ui32Idx = 0; ui32Idx < 1; ui32Idx++) { / /pui8Data[ui32Idx] = ui32Idx; UARTprintf(" 0x%02x", pui8Data[ui32Idx]); } UARTprintf(" \n"); AtmelWrite(pui8Data, 0, 1); AtmelRead(pui8DataGet, 0, 1); UARTprintf("Read(0) :"); for(ui32Idx = 0; ui32Idx < 1; ui32Idx++) { UARTprintf(" %02x", pui8DataGet[ui32Idx] ); } UARTprintf("\n"); UARTprintf("Done.\n\n"); SysCtlDelay(SysCtlClockGet() / 2 / 3); } }"); for(ui32Idx = 0; ui32Idx < 1; ui32Idx++) { UARTprintf(" %02x", pui8DataGet[ui32Idx] ); } UARTprintf("\n"); UARTprintf("Done.\n\n"); SysCtlDelay(SysCtlClockGet() / 2 / 3); } }"); for(ui32Idx = 0; ui32Idx < 1; ui32Idx++) { UARTprintf(" %02x", pui8DataGet[ui32Idx] ); } UARTprintf("\n"); UARTprintf("Done.\n\n"); SysCtlDelay(SysCtlClockGet() / 2 / 3); } }