4651 views|3 replies

18

Posts

0

Resources
The OP

TM4C123G softI2C help please ~ [Copy link]

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); } }
This post is from Microcontroller MCU

Latest reply

This post was last edited by Study_Stellaris on 2014-4-30 08:55 I wanted to use this before, but later found it too complicated, so I wrote one myself. I2C is very simple if you can use an oscilloscope to see the waveform. You can first verify it one function at a time. Then look at the waveform and timing.   Details Published on 2014-4-30 08:54

59

Posts

0

Resources
2
You can use an oscilloscope to capture the waveform and determine whether the data sent is correct. It is more convenient than analyzing code problems.
This post is from Microcontroller MCU

1934

Posts

31

Resources
3
Is there anything wrong with the hardware circuit? Does I2C have pull-up?
This post is from Microcontroller MCU

1801

Posts

0

Resources
4
This post was last edited by Study_Stellaris on 2014-4-30 08:55 I wanted to use this before, but later found it too complicated, so I wrote one myself. I2C is very simple if you can use an oscilloscope to see the waveform. You can first verify it one function at a time. Then look at the waveform and timing.

This post is from Microcontroller MCU

Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

    EEWorld
    subscription
    account

    EEWorld
    service
    account

    Automotive
    development
    circle

    Robot
    development
    community

    Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
    快速回复 返回顶部 Return list