Tool/software: Code Composer Studio
Hi everybody, it is first time to write a post here.
Recently I've working on reading GY-80 accel data through Tivaware.
here are my Questions.
Q1. Is it okay if I write ctrl register through following process?
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
/* * main.c */ /*--------------------------------------------- GPIO_Pin Pin_Function Device PF4 GPIO SW1 PF0 GPIO SW2 PF1 GPIO RGB LED(Red) PF2 GPIO RGB LED(Blue) PF3 GPIO RGB LED(Green) PC4 PWM SERVO0 PC5 PWM SERVO1 PB7 PWM SERVO2 PD0 DOUT PD1 DOUT PD2 DOUT PE1 DIN PE2 DIN PE3 DIN PB2 I2C SCL PB3 I2C SDA -----------------------------------------------*/ //--------------include header------------------// #include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "inc/hw_gpio.h" #include "inc/hw_types.h" #include "inc/hw_i2c.h" #include "driverlib/pin_map.h" #include "driverlib/gpio.h" #include "driverlib/pwm.h" #include "driverlib/i2c.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/rom.h" //----------------------------------------------// //--------------define macro--------------------// #define SERVO0 0 //PC4 #define SERVO1 1 //PC5 #define SERVO2 2 //PB7 #define PD0 0 #define PD1 1 #define PD2 2 #define PE1 3 #define PE2 4 #define PE3 5 #define HIGH 0x01 #define LOW 0x0 #define ACCEL_SLAVE_ADDR 0x53 #define ACCEL_X_DATA 0x32 #define ACCEL_Y_DATA 0x34 #define ACCEL_Z_DATA 0x36 #define NUM_I2C_DATA 3 //----------------------------------------------// //---------- TivaWare driver initialize function--------------// void sys_init(); void clk_set(); void gpio_init(); void pwm_init(); void i2c_init(); //------------------------------------------------------------// //------------User Interface Function-------------------------// void Servo_write(int SERVO_N, int DUTY_CYCLE); void digitalWrite(int PIN_N, int STATE); int32_t digitalRead(int PIN_N); int8_t ReadAccel(uint8_t reg); uint32_t I2CRead(uint32_t slave_addr, uint8_t reg); void ConfigureUART(void); //------------------------------------------------------------// #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif int main(void) { sys_init(); ConfigureUART(); uint8_t Ax, Ay, Az=32; //int32_t temp=0; UARTprintf("Start I2C Communication!\n"); while (1) { Ax = ReadAccel(ACCEL_X_DATA); Ay = ReadAccel(ACCEL_Y_DATA); Az = ReadAccel(ACCEL_Z_DATA); UARTprintf("%d %d %d\n", Ax, Ay, Az); }; //return 0; } void sys_init() { clk_set(); gpio_init(); pwm_init(); i2c_init(); } void clk_set() { SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); } void gpio_init() { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)); GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2); GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); } void pwm_init() { //Configure PWM Clock to match system SysCtlPWMClockSet(SYSCTL_PWMDIV_64); //Enable the PWM0 peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); //Wait for the PWM0 module to be ready. while(!SysCtlPeripheralReady(SYSCTL_PERIPH_PWM0)); //HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; //HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01; GPIOPinConfigure(GPIO_PB7_M0PWM1); GPIOPinConfigure(GPIO_PC4_M0PWM6); GPIOPinConfigure(GPIO_PC5_M0PWM7); GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_7); GPIOPinTypePWM(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5); //GPIOPinTypePWM(GPIO_PORTC_BASE, GPIO_PIN_5); //Configure the PWM generator for count down mode with immediate //updates to the parameters. PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN|PWM_GEN_MODE_NO_SYNC); PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN|PWM_GEN_MODE_NO_SYNC); //These settings are specifically designed to run servo motors //which expect 20mS period with between 1ms and 2ms high time //System clock is 16MHz with PWM divider of 64 // 16000000/64 = 250000/50 = 5000 ### 1S/50 = 20mS thats where divisor comes from // Set high time to 2mS PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 5000); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, 5000); // Set the pulse width of PWM1 for a 10% duty cycle. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 500); //PB7 M0PWM1 // Set the pulse width of PWM6 for a 10% duty cycle. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, 500); //PC4 M0PWM6 // Set the pulse width of PWM7 for a 20% duty cycle. PWMPulseWidthSet(PWM0_BASE, PWM_OUT_7, 1000); //PC5 M0PWM7 // Start the timers in generator 3. PWMGenEnable(PWM0_BASE, PWM_GEN_0); PWMGenEnable(PWM0_BASE, PWM_GEN_3); // Enable the outputs. PWMOutputState(PWM0_BASE, (PWM_OUT_1_BIT | PWM_OUT_6_BIT | PWM_OUT_7_BIT), true); //DataSheet //Table 20-1. PWM Signals (64LQFP) --> pwm module , generator , pin number } void i2c_init() { // Enable the I2C0 peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); // Wait for the I2C0 module to be ready. while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0)); //reset module SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0); //GPIO port B needs to be enabled so these pins can be used. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Configure the pin muxing for I2C0 functions on port B2 and B3. GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); // Configures pin for use as SDA by the I2C peripheral.GPIO_PB3_I2C0SDA GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); // Configures pin for use as SCL by the I2C peripheral.GPIO_PB2_I2C0SCL GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); // Don't know HOW TO USE --JW I2CMasterEnable(I2C0_BASE); // Initialize Master and Slave // it will sets the bus speed and enables the master module. I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true); //I2CSlaveEnable(I2C0_BASE); //I2CSlaveInit(I2C0_BASE, ACCEL_SLAVE_ADDR); // Specify slave address // first data, define master send or recive // true -> master is initiating a read from the slave // false -> the addr indicates that the I2C master is initiating a write to slave. I2CMasterSlaveAddrSet(I2C0_BASE, ACCEL_SLAVE_ADDR, false); //0x3B // set power register as measurement mode I2CMasterDataPut(I2C0_BASE,0x2D); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); I2CMasterDataPut(I2C0_BASE,0x08); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); // set data format register as full resolution I2CMasterDataPut(I2C0_BASE,0x31); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); I2CMasterDataPut(I2C0_BASE,0x08); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); // clear I2C FIFO //HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000; } void ConfigureUART(void) { // Enable the GPIO Peripheral used by the UART. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable UART0 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // Configure GPIO Pins for UART mode. GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // Use the internal 16MHz oscillator as the UART clock source. UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // Initialize the UART for console I/O. UARTStdioConfig(0, 115200, 16000000); } void Servo_write(int SERVO_N, int DUTY_CYCLE) { //0~180 --> duty cycle : 3%~12% (in arduino) DUTY_CYCLE = 150+(DUTY_CYCLE*2.5); //convert integer to degree switch (SERVO_N) { case 0: //PC4 PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, DUTY_CYCLE); //PC4 M0PWM6 break; case 1: //PC5 PWMPulseWidthSet(PWM0_BASE, PWM_OUT_7, DUTY_CYCLE); //PC5 M0PWM6 break; case 2: //PB7 PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, DUTY_CYCLE); //PB7 M0PWM1 break; default: break; } } void digitalWrite(int PIN_N, int STATE) //테스트 필요 { switch (PIN_N) { case 0: if(STATE == LOW) GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x0); else GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0); break; case 1: if(STATE == LOW) GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_1, 0x0); else GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_1, GPIO_PIN_1); break; case 2: if(STATE == LOW) GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, 0x0); else GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_PIN_2); break; default: break; } } int32_t digitalRead(int PIN_N) { switch (PIN_N) { case 3: //PE1 return GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_1); case 4: return GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_2); case 5: return GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_3); default: return 0; } } int8_t ReadAccel(uint8_t reg) //reading accel data { uint8_t accelData = I2CRead(ACCEL_SLAVE_ADDR, reg); return accelData; } uint32_t I2CRead(uint32_t slave_addr, uint8_t reg) // for test. receiving sensor data { I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false); //specify register to be read I2CMasterDataPut(I2C0_BASE, reg); //send ctrl byte and reg addr byte to slave device I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); //wait for MCU to finish transaction while (I2CMasterBusy(I2C0_BASE)); I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); //wait while(I2CMasterBusy(I2C0_BASE)); //data return return I2CMasterDataGet(I2C0_BASE); }
/* Trial 1 //I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false); //I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE); //wait //while(I2CMasterBusy(I2C0_BASE)); I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); //wait //while(I2CMasterBusy(I2C0_BASE)); //data return return I2CMasterDataGet(I2C0_BASE); */ /* Trial 2 * * //0926 uint32_t pui32DataTx[NUM_I2C_DATA]; uint32_t pui32DataRx[NUM_I2C_DATA]; uint32_t ui32Index; I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); //I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); //while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ)) // { // } // Initalize the receive buffer. // for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++) { pui32DataRx[ui32Index] = 0; }+ I2CSlaveDataPut(I2C0_BASE, pui32DataTx[ui32Index]); // I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); // while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ)) // { // } pui32DataRx[ui32Index] = I2CMasterDataGet(I2C0_BASE); return pui32DataRx[ui32Index]; // Reset receive buffer. //for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++) //{ // pui32DataRx[ui32Index] = 0; //} * * */