I'm a beginner. I'm trying to understand about I2C Initialization of TMP102. It is a temperature sensor. It is connected via I2C. So, the initialization must be of I2C. But, my leader told we have to initialize GPIO also in this case, since interrupt pin is connected via GPIO. He also told it is not necessary in other cases. I couldn't understand the original purpose.
Why do we initialize GPIO?
In other cases, where does the slave's interrupt pin gets connected?(if not in GPIO)
Also, in case of large message, TX/RX FIFO may not fit. So, draining feature is used (XDR/RDR bit is set). What exactly is draining feature and what it does?
Why do we initialize GPIO?
Since interrupt pin is connected via GPIO.
In other cases, where does the slave's interrupt pin gets connected?
If slave has an interrupt pin, you SHOULD initialize corresponding GPIO/IOMUX.
Some slave devices may not contain interrupt. In that case, no need to initialize any GPIO.
Summary:
You should initialize ALL GPIO/IOMUX for all input/output from processor to slave device.
Related
I'm making a quadcopter with SparkFun ESP32 Thing module and using MPU9255 Waveshare IMU.
It looks like when I'm reading PWM signals from RC receiver with interrupts (6 interrupts for 6 chanels) I2C fails after some time. I am using interrupt over MPU9250 either (but not the DMP module, just sync for accel and gyro data). I am not sure if the connection fails, MPU9250 or ESP32.
It looks like this:
After 10-50sec, MPU9250 fails, and MPUs interrupt works at 8kHz (instead of 1,6kHz), and values wont change.
No idea what is happening ;/ Anyone?
Without interrupts, I2C works fine...
Your ISRs must save and restore ALL registers and flags that are used. If you are calling any external functions from your ISRs, there could be reentrancy issues. Without a look at the code, that's the best I can offer.
I'm working a little project where I make my own version of serial communication between 2 arduino megas using their digital I/O pins.
So there are a couple digital pins on arduino A that are set as output. These are plugged into two digital pins in arduino B which are set as input. Is there a way for arduino B to detect whether the output pins coming from arduino A are high or low?
I know this can be done with transistors, but is there a way to do it without them?
The digital pins from one Arduino can be connected directly to the digital pins on the other - no need for any transistors in between. Make sure there is a common ground between them so both boards are at the same reference level (connect the GND pins, or power both from the same supply).
You can read the digital pins on the receiving end by calling digitalRead(), and write to the digital pins on the sending end by calling digitalWrite(). Whatever protocol you implement will need to detect the high/low transitions and decode them accordingly.
I guess I'm curious why you wouldn't just use the built-in serial ports to communicate, unless this is just a learning exercise? Certainly worthwhile for learning, but unnecessary extra work otherwise...
I am trying to connect 2 I2C modules to arduino uno. GY86(HMC5883L,MS5611,MPU6050) and BMP085 or any other I2C module. When i test each one separately it works ok but when both are connected to the I2C bus port, Every thing ruins. th moment i connect the BMP module, GY86 starts to output wrong numbers. I also tested my GY86 with DS1307 module. same thing happens and the moment i connect them, the DS starts to output wrong random output. i tried to apply a pull up resistor for SDA and SCL but didn't work. Whats the problem?
I2C at the Hardware Level
Signals
Each I2C bus consists of two signals: SCL and SDA. SCL is the clock signal, and SDA is the data signal. The clock signal is always generated by the current bus master; some slave devices may force the clock low at times to delay the master sensing more data.
Unlike UART or SPI connections, the I2C bus drivers are "open drain", meaning that they can pull the corresponding signal low, but cannot drive it high. Thus, there can be no bus contention where one device is trying to drive the line high while another tries to pull it low, eliminating the potential for damage to the drivers or excessive power dissipation in the system. Each signal line has a pull_up resistor on it, to restore the signal to high when no device is asserting it low.
Resistor selection varies with devices on the bus, but a good rule of thumb is to start with 4.7k and adjust down.
Signal Levels
Since the devices on the bus don't actually drive the signals high, I2C allows for some flexibility in connecting devices with different I/O voltages. In general, in a system where one device is at a higher voltage level than another, it may be possible to connect the two devices via I2C without any level shifting circuitry in between them. The trick is to connect the pull_up resistor to the lower of the two voltages. This only work in some cases, where the lower of the two system voltages exceeds the high-level input voltage of the higher voltage system - for example, a 5V Arduino and a 3.3V accelerometer.
Protocol
Communication via I2C is more complex that with UART or SPI solution. The signalling must adhere to a certain protocol for the devices on the bus to recognize it as valid I2C communications.
Basics
Messages are broken up into two types of frame: an address frame, where the master indicates the slave to which the message is being sent, and one or more data frames, which are 8-bit data messages passed from master to slave or vice versa. Data is placed on the SDA line after SCL goes low, and is sampled after the SCL line goes high. The time between clock edge and data read/write is defined by the devices on the bus and will vary from chip to chip.
Start Condition
To initiate the address frame, the master device leaves SCL high and pulls SDA low. This puts all slave devices on notice that a transmission is about to start. If two master devices wish to take ownership of the bus at one time, whichever device pulls the SDA low first wins the race and gains control of the bus. It is possible to issue repeated starts, initiating a new communication sequence without relinquishing control of the bus to other masters.
Address Frame
The address frame is always first in any new communication sequence. For a 7-but address, the address is clocked out most significant bit (MSB) first, followed by a R/W bit indicating whether this is a read (1) or write (0) operation.
The 9th bit of the frame is the NACK/ACK bit. This is the case for all frames (data or address).
Once the 8 bit of the frame are sent, the receiving device is given control over SDA. If the receiving device does not pull the SDA line low before the 9th clock pulse, it can be inferred that the receiving device either did not receive the data or did not know how to parse the message. In that case, the exchange halts, and it's up to the master of the system to decide how to proceed.
Data Frames
After the address frame has been sent, data can begin being transmitted. The master will simply continue generating clock pulses at a regular interval, and the data will be placed on SDA by either the master or the slave, depending on whether the R/W bit indicated a read or write operation. The number of data frames is arbitrary, and most slave devices will auto-increment the internal register, meaning that subsequent reads or writes come from the next register in line.
Stop Condition
Once all the data frames have been sent, the master will generate a stop condition. Stop conditions are defined by a 0->1 (low to high) transition an SDA after a 0->1 transition on SCL, with SCL remaining high. During normal data writing operation, the value on SDA should not change when SCL is high, to avoid stop condition.
I think several devices have same address. That's why you receive bad data. Usually I2C devices have extra pins to setup lower bits of addr. Do it and don't forget to change corresponding software definitions.
Update:
MPU6050 has input pin, which specifies LSB of I2C addr. You need tie this pin to high level 3.3V. Otherwise MPU6050 will have same addr as DS1307. I know it for sure, because work with both ICs a lot. To do it you need broke wire between 9nth pin of MPU6050 and Gnd. And solder it through resistor >3k to 3,3V. Or not use DS1307. From memory there is ds1302 rtc module.
You should find datasheets for all ICs you use and check what are their I2C addresses. The board consists of three parts, so you must know those 3 addresses.
I have a doubt on SPI slaves.
When we pull up the Chip select line, does it disables the whole Slave ( Functionality ) or just the communication module of the slave.
Taking a Ex:
If we have a SPI ADC. When we Pull up the slave , will it disable the ADC conversion process also or just the SPI lines of the ADC will be disabled but the conversion will still in going on?
I may be wrong, but from the research I did while looking into the SPI bus on AVR MCU's, the SPI hardware in the chip works independently of the AVR core. That is to say, whether or not there is data being transferred on the SPI bus, chip functionality shouldn't be directly affected.
I don't know what electronics you're using, but I would assume that toggling the chip-select has no effect on the core function of your peripherals. When in doubt, reference the datasheet of your slave device. It may have some useful insights on the particular SPI hardware.
I hope this helps.
Is it possible to wake a Microchip PIC16F1825 from sleep using RS232 without looking characters?
Because one of the permissible RX pins supports interrupt on change, I thought this might be possible.
Has anybody implemented this successfully?
Sure!
From datasheet PIC16(L)F1825/1829:
9.1 Wake-up from Sleep
The device can wake-up from Sleep through one of the following events:
1. External Reset input on MCLR pin, if enabled
2. BOR Reset, if enabled
3. POR Reset
4. Watchdog Timer, if enabled
5. Any external interrupt
6. Interrupts by peripherals capable of running
during Sleep (see individual peripheral for more information)
So you can use:
1)External interrupt INTERRUPT-ON-CHANGE, if you are connecting RX pin with one of other pins which is configured as interrupt-on-change.
2)Peripheral interrupt RCIF: USART Receive Interrupt Flag bit. When receiver buffer is full (one UART word is received), an interrupt is pending and your CPU should wake up.