phillip_bourdon234

I2C_Driver.c

Feb 28th, 2021 (edited)
518
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.20 KB | None | 0 0
  1. #include "stm32f10x.h"
  2. #include "system_stm32f10x.h"
  3. #include "I2C_Driver.h"
  4.  
  5. void i2c_init(void)
  6. {
  7.     RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
  8.     RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
  9.    
  10.     //configure the correct GPIO setting for the SDA and SCL pins of I2C mode 2
  11.     GPIOB->CRH |= GPIO_CRH_CNF10 | GPIO_CRH_MODE10 | GPIO_CRH_CNF11 | GPIO_CRH_MODE11;
  12.     GPIOB->ODR |= (1<<10) | (1<<11);
  13.    
  14.     RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; //enables clock for the I2C 2 bus
  15.    
  16.     I2C2->CR2 |= I2C_CR2_FREQ_5 | I2C_CR2_FREQ_2; //sets i2c freq to 36Mhz (because the APB1 clock runs at 36Mhz)
  17.    
  18.     I2C2->CCR |= 180; //(CCR * Tpclock) = (Tpi2c/2) -->>  (180 * (1/36Mhz)) = (1/100kHz)(0.5)
  19.     I2C2->TRISE = 37; //(1000ns / Tpclock) + 1 = TRISE -->> (1000ns/27.7ns) + 1 = 37
  20.    
  21.     I2C2->CR1 &= ~(I2C_CR1_NOSTRETCH);//enables clock stretching    
  22.    
  23.     I2C2->CR1 |= I2C_CR1_ACK | I2C_CR1_PE; //starts the I2C bus and enables ACKs
  24.    
  25. }
  26.  
  27. void i2c_write(uint8_t device_address, uint8_t mem_address, uint8_t data)
  28. {
  29.     uint16_t temp;
  30.    
  31.     I2C2->CR1 |= I2C_CR1_START; //generate start condition
  32.     while(!(I2C2->SR1 & I2C_SR1_SB)) //wait for the i2c to send the start condition
  33.     {
  34.     }
  35.     temp = I2C2->SR1;
  36.     I2C2->DR = device_address | 0x00; //send the adress plus a write opperation (0x01)
  37.  
  38.     while(!(I2C2->SR1 & I2C_SR1_ADDR)) //wait for the i2c to get a match for the address
  39.     {
  40.     }
  41.     temp = I2C2->SR1;
  42.     temp = I2C2->SR2;
  43.    
  44.     I2C2->DR = mem_address;
  45.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the mem_address
  46.     {
  47.     }
  48.    
  49.     I2C2->CR1 &= ~(I2C_CR1_ACK); //This sends a NACK to the slave, which tells it that this is the last read
  50.     I2C2->DR = data;
  51.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the data
  52.     {
  53.     }
  54.    
  55.     I2C2->CR1 |= I2C_CR1_STOP; //generates a stop condition
  56.    
  57. }
  58.  
  59. void i2c_write_2(uint8_t device_address, uint8_t mem_address_hi, uint8_t mem_address_lo, uint8_t data)
  60. {
  61.     uint16_t temp;
  62.    
  63.     I2C2->CR1 |= I2C_CR1_START; //generate start condition
  64.     while(!(I2C2->SR1 & I2C_SR1_SB)) //wait for the i2c to send the start condition
  65.     {
  66.     }
  67.     temp = I2C2->SR1;
  68.     I2C2->DR = device_address | 0x00; //send the adress plus a write opperation (0x00)
  69.  
  70.     while(!(I2C2->SR1 & I2C_SR1_ADDR)) //wait for the i2c to get a match for the address
  71.     {
  72.     }
  73.     temp = I2C2->SR1;
  74.     temp = I2C2->SR2;
  75.    
  76.     I2C2->DR = mem_address_hi;
  77.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the mem_address
  78.     {
  79.     }
  80.    
  81.     I2C2->DR = mem_address_lo;
  82.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the mem_address
  83.     {
  84.     }
  85.    
  86.     I2C2->CR1 &= ~(I2C_CR1_ACK); //This sends a NACK to the slave, which tells it that this is the last read
  87.     I2C2->DR = data;
  88.    
  89.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the data
  90.     {
  91.     }
  92.    
  93.     I2C2->CR1 |= I2C_CR1_STOP; //generates a stop condition
  94. }
  95.  
  96. uint8_t i2c_read(uint8_t device_address, uint8_t mem_address)
  97. {
  98.     uint16_t temp;
  99.    
  100.     I2C2->CR1 |= I2C_CR1_START; //generate start condition
  101.     while(!(I2C2->SR1 & I2C_SR1_SB)) //wait for the i2c to send the start condition
  102.     {
  103.     }
  104.     temp = I2C2->SR1;
  105.     I2C2->DR = device_address | 0x00; //send the adress plus a write opperation (0x00)
  106.  
  107.     while(!(I2C2->SR1 & I2C_SR1_ADDR)) //wait for the i2c to get a match for the address
  108.     {
  109.     }
  110.     temp = I2C2->SR1;
  111.     temp = I2C2->SR2; //reading from SR2 clears the ADDR flag
  112.    
  113.     I2C2->DR = mem_address;
  114.     while(!(I2C2->SR1 & I2C_SR1_BTF)) //wait for the i2c to send the mem_address
  115.     {
  116.     }
  117.    
  118.     I2C2->CR1 |= I2C_CR1_START; //generate repeat start condition
  119.    
  120.     while(!(I2C2->SR1 & I2C_SR1_SB)) //wait for the i2c to send the repeat start condition
  121.     {
  122.     }
  123.     temp = I2C2->SR1;
  124.     I2C2->DR = device_address | 0x01; //send the adress plus a read opperation (0x01)
  125.  
  126.     while(!(I2C2->SR1 & I2C_SR1_ADDR)) //wait for the i2c to get a match for the address
  127.     {
  128.     }
  129.     I2C2->CR1 &= ~(I2C_CR1_ACK); //This sends a NACK to the slave, which tells it that this is the last read
  130.     temp = I2C2->SR1;
  131.     temp = I2C2->SR2; //reading from SR2 clears the ADDR flag
  132.        
  133.     while((I2C2->SR1 & I2C_SR1_ADDR)) //wait for the addr bit to be cleared
  134.     {
  135.     }
  136.     I2C2->CR1 |= I2C_CR1_STOP; //generates a stop condition
  137.    
  138.     while((I2C2->SR2 & I2C_SR2_BUSY)) //wait until the bus is not busy
  139.     {
  140.     }
  141.    
  142.     temp = (uint8_t)I2C2->DR;
  143.     return (uint8_t)temp;
  144. }
  145.  
  146.  
  147.  
Add Comment
Please, Sign In to add comment