Copy of EE128 Lab 6

docx

School

University of California, Riverside *

*We aren’t endorsed by this school

Course

128

Subject

Electrical Engineering

Date

Apr 3, 2024

Type

docx

Pages

9

Uploaded by MasterLapwing1954

Report
LABORATORY #6: REPORT Serial Communication (UART, SPI, I2C) Part 1: I2C-Based 6-Axis Accelerometer and Magnetometer Part 2: SPI-Based Communication with Arduino Abstract: In this lab, we will familiarize ourselves with I2C(Inter-Integrated Circuit), a multi- master synchronous serial communication bus. In I2C, devices are classified into masters and servants and use two lines for data communication: SCL and SDA. We will use I2C to interface with an accelerometer/magnetometer sensor. In addition to this, we will familiarize ourselves with SPI based communication with Arduino. SPI, a synchronous serial protocol, classifies
devices into masters and servants and uses four wires to carry out the task of data communication: MOSI, MISO, SCK, and SS. Experiment System Specification: Part 1: 1. We will use the processor expert to communicate with the on board accelerometer and magnetometer and send the telemetry to our computer via UART to USB. 2. This experiment requires configuring the component and some additional software packages to work. 3. Send and output the accelerometer and magnetometer and message to the terminal using I2C. Part 2: 1. We will use K64F as a master and Arduino Uno as a slave device in the SPI bus. 2. SS will not be used since there is only one servant in this lab. 3. We will also use Processor Expert as well. 4. Connect the Arduino Uno and K64F via SPI line. 5. Send and output the accelerometer and magnetometer and message to the Arduino Uno’s serial monitor. Hardware Design: Part 2:
Question 1: Software Design: K64F /* ################################################################### ** Filename : main.c ** Project : Lab6_Part2 ** Processor : MK64FN1M0VLL12 ** Version : Driver 01.01 ** Compiler : GNU C Compiler ** Date/Time : 2019-11-03, 17:50, # CodeGen: 0
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
** Abstract : ** Main module. ** This module contains user's application code. ** Settings : ** Contents : ** No public methods ** ** ###################################################################*/ /*! ** @file main.c ** @version 01.01 ** @brief ** Main module. ** This module contains user's application code. */ /*! ** @addtogroup main_module main module documentation ** @{ */ /* MODULE main */ /* Including needed modules to compile this module/procedure */ #include "Cpu.h" #include "Events.h" #include "Pins1.h" #include "FX1.h" #include "GI2C1.h" #include "WAIT1.h" #include "CI2C1.h" #include "CsIO1.h" #include "IO1.h" #include "MCUC1.h" /* Including shared modules, which are used for whole project */ #include "PE_Types.h" #include "PE_Error.h" #include "PE_Const.h" #include "IO_Map.h" #include "PDD_Includes.h" #include "Init_Config.h" /* User includes (#include below this line is not maintained by Processor Expert) */ /*lint -save -e970 Disable MISRA rule (6.3) checking. */ /*library to configure GPIO*/ #include "MK64F12.h" unsigned char write[512]; int main(void) /*lint -restore Enable MISRA rule (6.3) checking. */ { //Configure GPIO PORTB[2] SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; /*Enable Port B Clock Gate Control*/ PORTB_GPCLR = 0x00040100; /*Configure PORTB[2] for GPIO*/ GPIOB_PDDR = 0x04; /*Configure PORTB[2] as output*/ GPIOB_PDOR = 0x00; //Initialize PORTB[2] = 0 /* Write your local variable definition here */ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ /* Write your code here */ uint32_t delay; uint8_t ret, who; int8_t temp; int16_t accX, accY, accZ; int16_t magX, magY, magZ;
int len; LDD_TDeviceData *SM1_DeviceData; SM1_DeviceData = SM1_Init(NULL); printf("Hello\n"); FX1_Init(); for(;;) { // get WHO AM I values if (FX1_WhoAmI(&who)!=ERR_OK) { return ERR_FAILED; } printf("Who Am I value in decimal \t: %4d\n",who); len = sprintf(write, "Who Am I value in decimal \t: %4d\n",who); GPIOB_PDOR = 0x04; /*Set PORTB[2] to high before calling SM1_Sendblock*/ SM1_SendBlock(SM1_DeviceData, &write, len); for(delay = 0; delay < 300000; delay++); //delay GPIOB_PDOR = 0x00; /*Set PORTB[2] to low after sending SM1_Sendblock*/ // get raw temperature values if (FX1_GetTemperature(&temp)!=ERR_OK) { return ERR_FAILED; } printf("RAW Temperature value in decimal \t: %4d\n",temp); len = sprintf(write, "RAW Temperature value in decimal \t: %4d\n",temp); SM1_SendBlock(SM1_DeviceData, &write, len); for(delay = 0; delay < 300000; delay++); //delay // Set up registers for accelerometer and magnetometer values if (FX1_WriteReg8(FX1_CTRL_REG_1, 0x00) != ERR_OK) { return ERR_FAILED; } if (FX1_WriteReg8(FX1_M_CTRL_REG_1, 0x1F) != ERR_OK) { return ERR_FAILED; } if (FX1_WriteReg8(FX1_M_CTRL_REG_2, 0x20) != ERR_OK) { return ERR_FAILED; } if (FX1_WriteReg8(FX1_XYZ_DATA_CFG, 0x00) != ERR_OK) { return ERR_FAILED; } if (FX1_WriteReg8(FX1_CTRL_REG_1, 0x0D) != ERR_OK) { return ERR_FAILED; } // Get the X Y Z accelerometer values accX = FX1_GetX(); accY = FX1_GetY(); accZ = FX1_GetZ(); printf("Accelerometer value \tX: %4d\t Y: %4d\t Z: %4d\n", accX, accY, accZ); len = sprintf(write, "Accelerometer value \tX: %4d\t Y: %4d\t Z: %4d\n", accX, accY, accZ); SM1_SendBlock(SM1_DeviceData, &write, len); for(delay = 0; delay < 300000; delay++); //delay // Get the X Y Z magnetometer values if (FX1_GetMagX(&magX)!=ERR_OK) { return ERR_OK; } if (FX1_GetMagY(&magY)!=ERR_OK) { return ERR_OK; } if (FX1_GetMagZ(&magZ)!=ERR_OK) { return ERR_OK; } printf("Magnetometer value \tX: %4d\t Y: %4d\t Z: %4d\n", magX, magY, magZ);
len = sprintf(write, "Magnetometer value \tX: %4d\t Y: %4d\t Z: %4d\n", magX, magY, magZ); SM1_SendBlock(SM1_DeviceData, &write, len); for(delay = 0; delay < 300000; delay++); //delay } /* For example: for(;;) { } */ /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/ #ifdef PEX_RTOS_START PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of RTOS startup code. ***/ /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;){} /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/ /* END main */ /*! ** @} */ /* ** ################################################################### ** ** This file was created by Processor Expert 10.4 [05.11] ** for the Freescale Kinetis series of microcontrollers. ** ** ################################################################### */ Arduino Uno #include <SPI.h> char buff [255]; volatile byte indx; volatile boolean process; #define PIN_6 6 void setup (void) { Serial.begin (115200); pinMode(MISO, OUTPUT); // have to send on master in so it set as output SPCR |= _BV(SPE); // turn on SPI in slave mode indx = 0; // buffer empty process = false; SPI.attachInterrupt(); // turn on interrupt pinMode(PIN_6, OUTPUT); digitalWrite(PIN_6, LOW); } ISR (SPI_STC_vect) // SPI interrupt routine { byte c = SPDR; // read byte from SPI Data Register if (indx < sizeof(buff)) { buff[indx++] = c; // save data in the next index in the array buff if (c == '\n') { digitalWrite(PIN_6, HIGH); delay(100);
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
digitalWrite(PIN_6, LOW); buff[indx - 1] = 0; // replace newline ('\n') with end of string (0) process = true; } } } void loop (void) { if (process) { process = false; //reset the process Serial.println (buff); //print the array on serial monitor indx= 0; //reset button to zero } } Technical Issues and Resolutions: 1. One issue we had was within Question 1 was that when connecting our K64F and Arduino to the oscilloscope, the oscilloscope showed a lot of noise to the point where we couldn’t receive a realistic measurement of latency. The oscilloscope showed that the K64F was outputting 20-50 V, which is completely wrong. We resolved this by using a different oscilloscope. Questions: 1. Measure the latency of transmitting a string of the “Who Am I” value.
The approximate end-to-end latency is 1.020 ms as shown in the oscilloscope image. The measured latency is reasonable because the clock rate of SPI is 374.491429 kHz. Since serial communication is sending one bit at a time, the latency depends on the SPI clock rate and the length of the message. In addition to this, we configured the SPI timing to have some delays. 2. An I2C communication has been captured by a mixed signal oscilloscope. SDA is the blue waveform and SCL is the red one. The address and data portions are indicated in the picture. a. What is the address of the slave? 1011110
b. What is the data value being transferred? Is the master reading or writing the data? The data value is 01010010. The master is writing the data. Conclusion: In this lab, we learned to configure the K64F for I2C and SPI to read the accelerometer and magnetometer and output those readings to a local terminal via I2C and to the Arduino’s monitor via SPI. In addition to this, we modified the code on the K64F and the Arduino and measured the latency of serial communication using the oscilloscope.
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help