====== T06 - I2C communication ====== ===== Task ===== Measure temperature and display its value on Edushield. Temperature: * T = 1/(log(R_NTC/R)/3975 + 1/298.15)-273.15, where R = 6.8kΩ * R_NTC = R*5000/(ADC * 3300) - R {{:courses:be2m37mam:tasks:therm.png?300|}} ===== Supportive materials ===== Lecture: {{ :courses:be2m37mam:tasks:mam-busses.pdf |busses}} Project using {{ :courses:be2m37mam:tasks:i2c_f401_hal_lib.zip |HAL library}} Edushield schematic: {{ :courses:be2m37mam:tasks:edushield_schematic.pdf |}} Edushield github: [[https://github.com/arduino-edushield/edushield|link]] Logic analyzer: [[https://learn.sparkfun.com/tutorials/using-the-usb-logic-analyzer-with-sigrok-pulseview/all|link]], [[https://www.youtube.com/watch?v=z8Tdz7eQ8n4|YT]] #define setbit(reg, bit) ((reg) |= (1U << (bit))) #define clearbit(reg, bit) ((reg) &= (~(1U << (bit)))) #define togglebit(reg, bit) ((reg) ^= (1U << (bit))) #define getbit(reg, bit) (((reg) & (1U << (bit))) >> (bit)) #define DISPLAY_ADDRESS 0x27<<1 void delay(int ms) { volatile int x; for (x = 0; x < ms * 50; x++); } #define I2C_DELAY delay(1); #define I2C_SET_SCL setbit(GPIOB->ODR, 8); #define I2C_CLR_SCL clearbit(GPIOB->ODR, 8); #define I2C_SET_SDA setbit(GPIOB->ODR, 9); #define I2C_CLR_SDA clearbit(GPIOB->ODR, 9); void I2C_ReadBit(void); // I2C_SDA -> PB9 // I2C_SCL -> PB8 void GPIO_init () { setbit(RCC->AHB1ENR, 1); setbit(GPIOB->MODER, 16); // SCL setbit(GPIOB->OTYPER, 8); setbit(GPIOA->OSPEEDR, 16); setbit(GPIOA->OSPEEDR, 17); setbit(GPIOB->MODER, 18); // SDA setbit(GPIOB->OTYPER, 9); setbit(GPIOA->OSPEEDR, 18); setbit(GPIOA->OSPEEDR, 19); } void I2C_ReadBit(void) { I2C_SET_SDA I2C_DELAY // set SDA pin as digital input I2C_SET_SCL I2C_DELAY I2C_CLR_SCL // set SDA pin as digital output I2C_DELAY } void I2C_WriteBit(unsigned char c) { if(c > 0) I2C_SET_SDA else I2C_CLR_SDA I2C_DELAY I2C_SET_SCL I2C_DELAY I2C_CLR_SCL } void I2C_Init() { I2C_SET_SDA I2C_SET_SCL I2C_DELAY } void I2C_Start() { I2C_SET_SCL I2C_DELAY I2C_SET_SDA I2C_DELAY I2C_CLR_SDA I2C_DELAY I2C_CLR_SCL I2C_DELAY } void I2C_Stop() { I2C_DELAY I2C_CLR_SDA I2C_DELAY I2C_SET_SCL I2C_DELAY I2C_SET_SDA } unsigned char I2C_Write(unsigned char c) { for (char i = 0; i < 8; i++) { I2C_WriteBit(c & 128); c <<= 1; } I2C_SET_SDA return 0; } void I2C_Send(unsigned char addr, unsigned char reg, unsigned char data) { I2C_Start(); I2C_Write(addr); I2C_ReadBit(); // ACK I2C_Write(reg); I2C_ReadBit(); // ACK I2C_Write(data); I2C_ReadBit(); // ACK I2C_Stop(); } int main() { GPIO_init(); I2C_Init(); const unsigned char digits[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // your code I2C_Send (DISPLAY_ADDRESS, 0, digits[7]); I2C_Send (DISPLAY_ADDRESS, 1, digits[5]); I2C_Send (DISPLAY_ADDRESS, 2, digits[3]); I2C_Send (DISPLAY_ADDRESS, 3, digits[1]); while(1) { } }