Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
12 views

Non Blocking I2C Read Function (Arduino)

Uploaded by

Bruno Voltz
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

Non Blocking I2C Read Function (Arduino)

Uploaded by

Bruno Voltz
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?

p=122

1. #ifndef FASTWIRE_H
2. #define FASTWIRE_H
3. #include <inttypes.h> // uint8_t is defined here
4.
5. void FastWireSend(uint8_t reg, uint8_t dat);
6. void FastWireRead(uint8_t reg, uint8_t * buf, uint8_t n);
7. uint8_t FastWireIsBusy(void);
8.
9. #endif

1. #include "FastWire.h"
2. #include <avr/io.h> // The I2C registers are defined here
3. #include <avr/interrupt.h>
4.
5. // Status messeges from I2C

1 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

6. #define MT_START 0x08


7. #define MT_SLA_ACK 0x18
8. #define MT_DATA_ACK 0x28
9. #define MR_START 0x10 // repeated start
10. #define MR_SLA_ACK 0x40
11. #define MR_SLA_NACK 0x48
12. #define MR_DATA_ACK 0x50
13. #define MR_DATA_NACK 0x58
14.
15. // These are specific to MPU6050 and should be changed if used with other components
16. #define SLA_W 0xD0 // 11010000 // (208)
17. #define SLA_R 0xD1 // 11010001 // (209)
18.
19. static uint8_t I2Cwritebuffer[2];
20. static volatile uint8_t I2Cwrite_n = 0;
21. static volatile uint8_t I2Cwrite_i = 0;
22. static volatile uint8_t I2Cwrite_sendstop = 0;
23. static uint8_t * I2Creadbuffer;
24. static volatile uint8_t I2Cread_i = 0;
25. static volatile uint8_t I2Cbusy = 0;
26.
27. void FastWireSend(uint8_t reg, uint8_t dat){
28. // Wait for free line
29. while(I2Cbusy != 0);
30. while(TWCR & (1 << TWSTO));
31. I2Cwritebuffer[0] = reg;
32. I2Cwritebuffer[1] = dat;
33. I2Cwrite_n = 2;
34. I2Cwrite_i = 0;
35. I2Cwrite_sendstop = 1;
36.
37. I2Cbusy = 1;
38.
39. // Initiate the I2C comunication
40. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
41. }
42.
43. void FastWireRead(uint8_t reg, uint8_t * buf, uint8_t n){
44. // Wait for free line
45. while(I2Cbusy != 0);
46. while(TWCR & (1 << TWSTO));
47. I2Cwritebuffer[0] = reg;
48. I2Cwrite_n = 1;
49. I2Cwrite_i = 0;
50. I2Cwrite_sendstop = 0;
51. I2Creadbuffer = buf;
52. I2Cread_i = n-1;
53.
54. I2Cbusy = 1;
55.
56. // Initiate the I2C comunication
57. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
58. }
59.
60. uint8_t FastWireIsBusy(void){
61. return I2Cbusy;
62. }
63. /******************************************************************
64. The interrupt that does all the work
65. */
66. ISR(TWI_vect)
67. {
68. switch(TWSR & 0xF8){
69. case MT_START:
70. // Send the slave address and write bit
71. TWDR = SLA_W;
72. I2Cbusy = 2;

2 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

73. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);


74. break;
75. case MT_SLA_ACK:
76. I2Cbusy = 3;
77. // Send the data in the transmit buffer
78. TWDR = I2Cwritebuffer[I2Cwrite_i];
79. I2Cwrite_i ++;
80. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
81. break;
82. case MT_DATA_ACK:
83. I2Cbusy = 4;
84. // Send more data or send stop signal
85. if (I2Cwrite_i < I2Cwrite_n){
86. TWDR = I2Cwritebuffer[I2Cwrite_i];
87. I2Cwrite_i ++;
88. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
89. }else{
90. if (I2Cwrite_sendstop){
91. // Stop the transmission
92. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) | (1<<TWIE);
93. I2Cbusy = 0;
94. }else{
95. // Start recieving data by sending a start signal
96. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
97. I2Cbusy = 1;
98. }
99. }
100. break;
101. case MR_START:
102. TWDR = SLA_R;
103. I2Cbusy = 5;
104. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
105. break;
106. case MR_SLA_ACK:
107. I2Cbusy = 6;
108. // Ask for the first uint8_t of data
109. if (I2Cread_i == 0){
110. // send NACK
111. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
112. }else{
113. TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
114. }
115. break;
116. // case MR_SLA_NACK:
117. // I2Cbusy = 8;
118. // break;
119. case MR_DATA_ACK:
120. I2Cbusy = 7;
121. // Save data in buffer
122. I2Creadbuffer[I2Cread_i] = TWDR;
123. // In case there is more data to read, ask for more
124. if (I2Cread_i == 1){
125. // send NACK
126. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
127. }else{
128. TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
129. }
130. I2Cread_i--;
131. break;
132. case MR_DATA_NACK:
133. // Save the lase uint8_t
134. I2Creadbuffer[I2Cread_i] = TWDR;
135. // End the transmission
136. TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
137. I2Cbusy = 0;
138. break;
139. default:

3 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

140. I2Cbusy = TWSR;


141. }
142. }

4 sur 4 12/07/2018 à 17:30

You might also like