Advertisement
Guest User

I2C

a guest
Feb 8th, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.51 KB | None | 0 0
  1. /* Defines */
  2. #define F_CPU 16000000UL
  3. #define FOSC 16000000 // Clock Speed
  4. #define BAUD 9600
  5. #define MYUBRR FOSC/16/BAUD-1
  6. #define USART_RX_BUFFER_SIZE 128 /* 2,4,8,16,32,64,128 or 256 bytes */
  7. #define USART_TX_BUFFER_SIZE 128 /* 2,4,8,16,32,64,128 or 256 bytes */
  8. #define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
  9. #define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )
  10. #define I2C_READ 0x01
  11. #define I2C_WRITE 0x00
  12. #define text "Hello from Arduino!\n\nThis project contains a variety of different functionalities.\nBy going through the menu you can easily setup and control the system.\n"
  13. /* Preprocessor */
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <util/delay.h>
  19. #include <MyLib/I2Cmaster/i2c_master.h>
  20. #include <util/twi.h>
  21. #include "i2c_master.h"
  22. #define F_SCL 16000000UL // SCL frequency
  23. #define Prescaler 1
  24. #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
  25. /* Function Prototypes */
  26. void ReceiveSystemInstructions( char* Buffer, unsigned int BufferSize );
  27. void USART_Transmit_IO( char data, FILE *stream );
  28. void USART_Init( unsigned int baudrate );
  29. void USART_Transmit( unsigned char data);
  30. void USART_PutString(char* StringPointer);
  31. void menu(int menuposition);
  32. void sendADCValue(void);
  33. void readLightingSensor(void);
  34. void TemperatureSensor(void);
  35. void i2c_stop(void);
  36. void i2c_init(void);
  37. uint8_t i2c_start(uint8_t address)
  38. uint8_t i2c_write(uint8_t data)
  39. uint8_t i2c_read_ack(void)
  40. uint8_t i2c_read_nack(void)
  41. uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
  42. uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
  43. uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  44. uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  45. void i2c_stop(void)
  46. /* Buffers */
  47. char USART_ReceiveBuffer[USART_RX_BUFFER_SIZE];
  48. static unsigned char USART_TxBuf[USART_TX_BUFFER_SIZE];
  49. char USART_Instruction[32];
  50. /* Static Variables */
  51. static volatile unsigned char WritingPositionOnTheBuffer;
  52. static volatile unsigned char ReadingPositionOnTheBuffer;
  53. static volatile unsigned char USART_TxHead;
  54. static volatile unsigned char USART_TxTail;
  55. static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit_IO, NULL, _FDEV_SETUP_WRITE);
  56. /* String Declarations */
  57. char String[] = text;
  58. /* Flags */
  59. volatile uint8_t adcflag = 0;
  60. volatile uint8_t i2cflag = 1;
  61. /* Global Variables */
  62. uint8_t i2c_start(uint8_t address);
  63. uint8_t i2c_write(uint8_t data);
  64. uint8_t i2c_read_ack(void);
  65. uint8_t i2c_read_nack(void);
  66. uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
  67. uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
  68. uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
  69. uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
  70.  
  71.  
  72. int main(void)
  73. {
  74. /* Outputs */
  75. DDRD |= (1<<PIND7)|(1<<PIND6)|(1<<PIND5)|(1<<PIND4)|(1<<PIND3)|(1<<PIND2);
  76. /* Button ADC conversion start/stop */
  77. DDRB &= ~(1<<PINB0);
  78. /* Pull up resistor */
  79. PORTB |= (1<<PINB0);
  80. /* ADC */
  81. ADCSRA |= 1<<ADPS2;
  82. ADMUX |= 1<<ADLAR;
  83. ADMUX |= 1<<REFS0;
  84. ADCSRA |= 1<<ADIE;
  85. ADCSRA |= 1<<ADEN;
  86. /* Global Interrupts Enabled */
  87. sei();
  88. /* USART */
  89. USART_Init( MYUBRR );
  90. stdout = &mystdout;
  91. /* I2C */
  92. i2c_init();
  93. USART_PutString(String);
  94. menu(0);
  95. /* Menu Flags */
  96. int pmenu = 0;
  97. int LEDs = 0;
  98. int LEDMenuMessage = 1;
  99. /* Forever Loop */
  100. while(1)
  101. {
  102. ReceiveSystemInstructions(USART_Instruction, USART_TX_BUFFER_SIZE);
  103. if(strcmp(USART_Instruction, "Temperature") == 0) pmenu = 1;
  104. if(strcmp(USART_Instruction, "Menu") == 0) pmenu = 2;
  105. if(strcmp(USART_Instruction, "ADC") == 0) pmenu = 3;
  106. if(strcmp(USART_Instruction, "LED") == 0) pmenu = 4;
  107. if(strcmp(USART_Instruction, "back") == 0) pmenu = 5;
  108. if(strcmp(USART_Instruction, "LEDs off") == 0) pmenu = 6;
  109. if(strcmp(USART_Instruction, "LED 1 on") == 0) pmenu = 7;
  110. if(strcmp(USART_Instruction, "LED 1 off") == 0) pmenu = 8;
  111. if(strcmp(USART_Instruction, "LED 2 on") == 0) pmenu = 9;
  112. if(strcmp(USART_Instruction, "LED 2 off") == 0) pmenu = 10;
  113. if(strcmp(USART_Instruction, "LED 3 on") == 0) pmenu = 11;
  114. if(strcmp(USART_Instruction, "LED 3 off") == 0) pmenu = 12;
  115. if(strcmp(USART_Instruction, "LED 4 on") == 0) pmenu = 13;
  116. if(strcmp(USART_Instruction, "LED 4 off") == 0) pmenu = 14;
  117. if(strcmp(USART_Instruction, "LED 5 on") == 0) pmenu = 15;
  118. if(strcmp(USART_Instruction, "LED 5 off") == 0) pmenu = 16;
  119. if(strcmp(USART_Instruction, "LED 6 on") == 0) pmenu = 17;
  120. if(strcmp(USART_Instruction, "LED 6 off") == 0) pmenu = 18;
  121. if(strcmp(USART_Instruction, " ") == 0) printf("\n");
  122. if(pmenu > 18) // Needs to be continued
  123. {
  124. printf("Invalid Command\n");
  125. }
  126. switch(pmenu)
  127. {
  128. case 1: i2cflag = 1;
  129. TemperatureSensor();
  130. break;
  131. case 2: menu(0);
  132. pmenu = 0;
  133. break;
  134. case 3: sendADCValue();
  135. pmenu = 0;
  136. break;
  137. case 4: LEDs = 1;
  138. pmenu = 0;
  139. break;
  140. }
  141. if(LEDs)
  142. {
  143. menu(LEDMenuMessage);
  144. LEDMenuMessage = 10; // Clear the flag
  145. switch(pmenu)
  146. {
  147. case 5:
  148. LEDs = 0; // Clear the flag
  149. LEDMenuMessage = 1; // Reset the flag
  150. printf("You are back to the main menu!\n\n");
  151. menu(0);
  152. break;
  153. case 6:
  154. PORTD &= ~(1<<PIND7);
  155. _delay_ms(200);
  156. PORTD &= ~(1<<PIND6);
  157. _delay_ms(200);
  158. PORTD &= ~(1<<PIND5);
  159. _delay_ms(200);
  160. PORTD &= ~(1<<PIND4);
  161. _delay_ms(200);
  162. PORTD &= ~(1<<PIND3);
  163. _delay_ms(200);
  164. PORTD &= ~(1<<PIND2);
  165. _delay_ms(200);
  166. printf("LED's are off\n");
  167. break;
  168. case 7:
  169. PORTD |= (1<<PIND7);
  170. printf("LED 1 is on\nTo turn it off type: LED 1 off\n");
  171. break;
  172. case 8:
  173. PORTD &= ~(1<<PIND7);
  174. printf("LED 1 is turned off\n");
  175. break;
  176. case 9:
  177. PORTD |= (1<<PIND6);
  178. printf("LED 2 is on\nTo turn it off type: LED 2 off\n");
  179. break;
  180. case 10:
  181. PORTD &= ~(1<<PIND6);
  182. printf("LED 2 is turned off\n");
  183. break;
  184. case 11:
  185. PORTD |= (1<<PIND5);
  186. printf("LED 3 is on\nTo turn it off type: LED 3 off\n");
  187. break;
  188. case 12:
  189. PORTD &= ~(1<<PIND5);
  190. printf("LED 3 is turned off\n");
  191. break;
  192. case 13:
  193. PORTD |= (1<<PIND4);
  194. printf("LED 4 is on\nTo turn it off type: LED 4 off\n");
  195. break;
  196. case 14: {
  197. PORTD &= ~(1<<PIND4);
  198. printf("LED 4 is turned off\n");
  199. break;
  200. case 15:
  201. PORTD |= (1<<PIND3);
  202. printf("LED 5 is on\nTo turn it off type: LED 5 off\n");
  203. break;
  204. case 16:
  205. PORTD &= ~(1<<PIND3);
  206. printf("LED 5 is turned off\n");
  207. break;
  208. case 17:
  209. PORTD |= (1<<PIND2);
  210. printf("LED 6 is on\nTo turn it off type: LED 6 off\n");
  211. break;
  212. case 18:
  213. PORTD &= ~(1<<PIND2);
  214. printf("LED 6 is turned off\n");
  215. break;
  216. }
  217. }
  218. }
  219. }
  220. }
  221.  
  222. ISR(ADC_vect)
  223. {
  224. adcflag = 1;
  225. }
  226.  
  227. ISR(USART_RX_vect) // Generating data in the Receive Buffer
  228. {
  229. if(i2cflag == 1) i2cflag = 0;
  230. unsigned char data;
  231. unsigned char tmpWPosition;
  232. /* Read the received data */
  233. data = UDR0;
  234. /* Determine the Write PositionInTheBuffer */
  235. tmpWPosition = (WritingPositionOnTheBuffer + 1) & USART_RX_BUFFER_MASK;
  236. /* Store new index */
  237. WritingPositionOnTheBuffer = tmpWPosition;
  238. /* Store received data in buffer */
  239. USART_ReceiveBuffer[tmpWPosition] = data;
  240. }
  241.  
  242. ISR(USART_UDRE_vect)
  243. {
  244. unsigned char tmptail;
  245.  
  246. /* Check if all data is transmitted */
  247. if ( USART_TxHead != USART_TxTail )
  248. {
  249. /* Calculate buffer index */
  250. tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
  251. USART_TxTail = tmptail; /* Store new index */
  252.  
  253. UDR0 = USART_TxBuf[tmptail]; /* Start transmission */
  254. }
  255. else
  256. {
  257. UCSR0B &= ~(1<<UDRIE0); /* Disable UDRE interrupt */
  258. }
  259. }
  260.  
  261.  
  262. void USART_Init( unsigned int baudrate )
  263. {
  264. unsigned char x;
  265.  
  266. /* Set the baud rate */
  267. UBRR0H = (unsigned char) (baudrate>>8);
  268. UBRR0L = (unsigned char) baudrate;
  269.  
  270. /* Enable UART receiver and transmitter */
  271. UCSR0B = ( ( 1 << RXCIE0 ) | ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
  272.  
  273. /* Set frame format: 8 data 1stop */
  274. UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
  275.  
  276. /* Flush receive buffer */
  277. x = 0;
  278. ReadingPositionOnTheBuffer = x;
  279. WritingPositionOnTheBuffer = x;
  280. USART_TxTail = x;
  281. USART_TxHead = x;
  282. }
  283.  
  284. void USART_Transmit( unsigned char data) //Simple Transmit Function
  285. {
  286. while(!(UCSR0A & (1<<UDRE0))); // Wait
  287. UDR0 = data;
  288. }
  289. void USART_PutString(char* StringPointer)
  290. {
  291. while(*StringPointer != 0x00) //Here we check if there is still more chars to send, this is done checking the actual char and see if it is different from the null char
  292. {
  293. USART_Transmit(*StringPointer); //Using the simple send function we send one char at a time
  294. StringPointer++; //We increment the pointer so we can read the next char
  295. }
  296. }
  297. void ReceiveSystemInstructions( char* Buffer, unsigned int BufferSize )
  298. {
  299. unsigned char tmpWPosition;
  300. unsigned int i = 0;
  301. int b;
  302. uint8_t ReadPin;
  303.  
  304. while ( WritingPositionOnTheBuffer == ReadingPositionOnTheBuffer ) // Wait for incoming data /
  305. {
  306.  
  307. for(b = 0; b < 200 ; b++)
  308. {
  309. _delay_ms(1);
  310. ReadPin = ( PINB & ( 1 << PINB0 ) ) ? 1 : 0; // Read the pin
  311. if(!ReadPin)
  312. {
  313. printf("Start Conversion\n");
  314. do
  315. {
  316. ADCSRA |= 1<<ADSC; // Start ADC Conversion
  317. _delay_ms(1000);
  318. ReadPin = ( PINB & ( 1 << PINB0 ) ) ? 1 : 0;
  319. readLightingSensor();
  320. } while (ReadPin == 1);
  321. printf("Stop Conversion\n");
  322. _delay_ms(1000);
  323. }
  324. }
  325. b=0;
  326. }
  327. _delay_ms(10);
  328. for( i=0; i < BufferSize - 1; ++i )
  329. {
  330. tmpWPosition = ( ReadingPositionOnTheBuffer + 1 ) & USART_RX_BUFFER_MASK; // Calculate buffer index /
  331.  
  332. ReadingPositionOnTheBuffer = tmpWPosition; // Store new index /
  333.  
  334. Buffer[i] = USART_ReceiveBuffer[tmpWPosition]; // Return data /
  335. if( WritingPositionOnTheBuffer == ReadingPositionOnTheBuffer )
  336. break;
  337. }
  338. Buffer[i+1] = '\0'; // Adding a Null Terminator
  339. }
  340. void menu(int menuposition)
  341. {
  342. if(menuposition == 0)
  343. {
  344. printf("Temperature sensor type: Temperature\n");
  345. printf("To access the LEDs type: LED\n");
  346. printf("To get the ADC Value type: ADC\n");
  347. printf("Turning off the LED's by typing: LEDs off\n");
  348. printf("\nTo see the menu again type: Menu\n");
  349. }
  350. if(menuposition == 1)
  351. {
  352. printf("You are now in the LED section.\n\nTo turn on the LEDn type LED n on, where n goes from 1 to 6: \n\nGo back by typing: back\n");
  353. }
  354.  
  355. }
  356. void USART_Transmit_IO( char data, FILE *stream )
  357. {
  358. unsigned char tmphead;
  359. /* Calculate buffer index */
  360. tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK;
  361. while ( tmphead == USART_TxTail ); /* Wait for free space in buffer */
  362.  
  363. USART_TxBuf[tmphead] = data; /* Store data in buffer */
  364. USART_TxHead = tmphead; /* Store new index */
  365.  
  366. UCSR0B |= (1<<UDRIE0); /* Enable UDRE interrupt */
  367. }
  368.  
  369. void sendADCValue(void)
  370. {
  371. ADCSRA |= 1<<ADSC; // Start Conversion
  372. _delay_ms(1); // Wait for the interrupt to complete and then to check the if statement
  373. if (adcflag)
  374. {
  375. uint16_t adcData = ADCH;
  376. printf("ADC Value: %u\n", adcData);
  377. adcflag = 0;
  378. }
  379. }
  380. void readLightingSensor(void)
  381. {
  382. if (adcflag)
  383. {
  384. uint16_t adcData = ADCH;
  385. printf("%u\n", adcData);
  386. adcflag = 0;
  387. }
  388.  
  389. }
  390. void TemperatureSensor(void)
  391. {
  392. int data;
  393. printf("\nYou have requested the stream of temperature sensor values. To cancel the request type: back\n\n");
  394. printf("Stream of temperature sensor values:\n");
  395. _delay_ms(100);
  396. while(i2cflag == 1)
  397. {
  398. i2c_start(0b10010001); // Start and Read request
  399. if(i2c_start(0b10010001)==1) printf("ERROR\n");
  400. i2c_read_ack();
  401. data = TWDR;
  402. printf("%d\n", data);
  403. _delay_ms(1000);
  404. }
  405. }
  406.  
  407. void i2c_init(void)
  408. {
  409. TWBR = (uint8_t)TWBR_val;
  410. }
  411.  
  412. uint8_t i2c_start(uint8_t address)
  413. {
  414. // reset TWI control register
  415. TWCR = 0;
  416. // transmit START condition
  417. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  418. // wait for end of transmission
  419. while( !(TWCR & (1<<TWINT)) );
  420.  
  421. // check if the start condition was successfully transmitted
  422. if((TWSR & 0xF8) != TW_START){ return 1; }
  423.  
  424. // load slave address into data register
  425. TWDR = address;
  426. // start transmission of address
  427. TWCR = (1<<TWINT) | (1<<TWEN);
  428. // wait for end of transmission
  429. while( !(TWCR & (1<<TWINT)) );
  430.  
  431. // check if the device has acknowledged the READ / WRITE mode
  432. uint8_t twst = TW_STATUS & 0xF8;
  433. if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
  434.  
  435. return 0;
  436. }
  437.  
  438. uint8_t i2c_write(uint8_t data)
  439. {
  440. // load data into data register
  441. TWDR = data;
  442. // start transmission of data
  443. TWCR = (1<<TWINT) | (1<<TWEN);
  444. // wait for end of transmission
  445. while( !(TWCR & (1<<TWINT)) );
  446.  
  447. if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return ERROR(); }
  448.  
  449. return 0;
  450. }
  451.  
  452. uint8_t i2c_read_ack(void)
  453. {
  454.  
  455. // start TWI module and acknowledge data after reception
  456. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  457. // wait for end of transmission
  458. while( !(TWCR & (1<<TWINT)) );
  459. // return received data from TWDR
  460. return TWDR;
  461. }
  462.  
  463. uint8_t i2c_read_nack(void)
  464. {
  465.  
  466. // start receiving without acknowledging reception
  467. TWCR = (1<<TWINT) | (1<<TWEN);
  468. // wait for end of transmission
  469. while( !(TWCR & (1<<TWINT)) );
  470. // return received data from TWDR
  471. return TWDR;
  472. }
  473.  
  474. uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
  475. {
  476. if (i2c_start(address | I2C_WRITE)) return ERROR();
  477.  
  478. for (uint16_t i = 0; i < length; i++)
  479. {
  480. if (i2c_write(data[i])) return ERROR();
  481. }
  482.  
  483. i2c_stop();
  484.  
  485. return 0;
  486. }
  487.  
  488. uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
  489. {
  490. if (i2c_start(address | I2C_READ)) return 1;
  491.  
  492. for (uint16_t i = 0; i < (length-1); i++)
  493. {
  494. data[i] = i2c_read_ack();
  495. }
  496. data[(length-1)] = i2c_read_nack();
  497.  
  498. i2c_stop();
  499.  
  500. return 0;
  501. }
  502.  
  503. uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  504. {
  505. if (i2c_start(devaddr | 0x00)) return 1;
  506.  
  507. i2c_write(regaddr);
  508.  
  509. for (uint16_t i = 0; i < length; i++)
  510. {
  511. if (i2c_write(data[i])) return 1;
  512. }
  513.  
  514. i2c_stop();
  515.  
  516. return 0;
  517. }
  518.  
  519. uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  520. {
  521. if (i2c_start(devaddr)) return 1;
  522.  
  523. i2c_write(regaddr);
  524.  
  525. if (i2c_start(devaddr | 0x01)) return 1;
  526.  
  527. for (uint16_t i = 0; i < (length-1); i++)
  528. {
  529. data[i] = i2c_read_ack();
  530. }
  531. data[(length-1)] = i2c_read_nack();
  532.  
  533. i2c_stop();
  534.  
  535. return 0;
  536. }
  537.  
  538. void i2c_stop(void)
  539. {
  540. // transmit STOP condition
  541. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  542. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement