Warning
This page is located in archive. Go to the latest version of this course pages.

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

Supportive materials

Lecture: busses

Low-level project: i2c.zip

Project using HAL library

Edushield schematic: edushield_schematic.pdf

Edushield github: link

Logic analyzer: link, 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)
    {
 
    }
}

courses/be2m37mam/tasks/task06.txt · Last modified: 2021/12/02 13:50 by viteks