BÀI 09: I2C VỚI STM32F103

posted in: Uncategorized | 0

1. Giao tiếp I2C

I2C – Inter- Intergrated Circuit là chuẩn truyền thông nối tiếp gồm 2 dây Clock và  Data được phát minh bởi hãng Philips. Chuẩn I2C trở nên thông dụng với nhiều module và IC sử dụng rộng rãi như: IC nhớ (24Cxxx), cảm biến góc nghiêng(MPU6050), module giao tiếp LCD (dùng IC PCF8574), IC thời gian thực (DS1307, DS3231, BQ32000), IC chuyển đổi tín hiệu số, tương tự… Chuẩn giao tiếp này hỗ trợ giao tiếp ở tốc độ 100Khz hoặc 400Khz.

I2C Protocol - inter integrated controller - javatpoint

STM32F103C8T6 có 2 bộ chuyển đổi I2C với các tính năng được tóm tắt như sau:

  • Có thể lập trình là Master hay Slave.
  • Đối với Master: Tạo ra xung clock và tạo ra tín hiệu start, stop.
  • Đối với Slave : Lập trình được địa chỉ của thiết bị I2C, chế độ kiểm tra bit stop.
  • Số địa chỉ được sinh ra cũng như được kiểm tra là 7 bit hoặc 10 bit. كازينو ٨٨٨
  • Hỗ trợ 2 chuẩn tốc độ là 100khz và 400 Khz. موقع قمار
  • Có bộ lọc nhiễu Analog.
  • Tích hợp mode DMA.
  • Có các cờ báo trạng thái : Nhận, truyền, kết thúc chuyển đổi, báo lỗi…
  • Có các ngắt như: Ngắt buffer truyền, nhận; ngắt sự kiện, ngắt báo lỗi.

Quá trình truyền data tùy thuộc vào modde cấu hình của I2C là master hoặc slave, ở chế độ 10 bit địa chỉ hay 7 bit địa chỉ (phổ biến hơn). لعب قمار على النت Dưới đây là ví dụ về cấu hình I2C là master:

Tóm tắt quá trình truyền như sau:

  • Đầu tiên bộ I2C sẽ tạo ra tín hiệu start đến EV5: SB = 1 (tạo ra điều kiện bắt đầu trên thanh ghi SR1)
  • Sau đó gửi địa chỉ và hướng truyền
  • Đợi bit ACK từ Slave truyền cho Master 
  • Tiếp tục kiểm tra EV6: ADDR = 1(Master sẽ gởi địa chỉ của Slave và Slave nhận đúng chính xác địa chỉ của mình do Master gởi) – EV8.1: TxE=1 (hiện tại thì thanh ghi dịch và thanh ghi dữ liệu hiện đang trống) 
  • Kiểm tra EV8 (lúc này dữ liệu thanh ghi dịch đã có và bắt đầu truyền đến Slave)
  • Gửi Data đến thiết bị slave với địa chỉ truyền ở trên
  • Nếu Slave nhận được dữ liệu sẽ trả về bit ACK cho Master để xác nhận đã dữ liệu
  • Kiểm tra EV8_2 – tương ứng code là kiểm tra toàn bộ Data đã truyền xong chưa (TXE, BTF)
  • Đợi truyền xong và bộ I2C sẽ tạo ra tín hiệu kết thúc

2. Cấu hình I2C với thư viện chuẩn

Bài tập: Giao tiếp với cảm biến gia tốc MPU050 sử dụng bộ giao tiếp I2C1 trên board STM32F103C8T6

Sơ đồ kết nối:

  1. Khai báo macro định nghĩa địa chỉ cảm biến
#define MPU6050_ADDR 0xD0
#define SMPLRT_DIV_REG 0x19
#define GYRO_CONFIG_REG 0x1B
#define ACCEL_CONFIG_REG 0x1C
#define ACCEL_XOUT_H_REG 0x3B
#define TEMP_OUT_H_REG 0x41
#define GYRO_XOUT_H_REG 0x43
#define PWR_MGMT_1_REG 0x6B
#define WHO_AM_I_REG 0x75

2. Định nghĩa lại hàm ghi và đọc MPU6050

void MPU_write(I2C_TypeDef* I2Cx, uint8_t address, uint8_t reg, uint8_t data)
{
	I2C_Write(I2Cx, address, reg, data);
}
uint8_t MPU_read(I2C_TypeDef* I2Cx, uint8_t address, uint8_t reg, uint8_t *data, uint8_t count)
{
	return I2C_ReadMulti(I2Cx, address, reg, data, count);
}

3. Khởi tạo hàm cấu hình các thanh ghi MPU6050

void Mpu6050_Init(void)
{
	uint8_t check;
	uint8_t Data;
	IIC_Init(I2C1, Pin_PB8PB9, 100000);
	
	if(I2C_Read(I2C1, MPU6050_ADDR, WHO_AM_I_REG) ==  104){
		Data = 0;

		MPU_write(I2C1,MPU6050_ADDR,PWR_MGMT_1_REG,Data);

		Data = 0x07;
		MPU_write(I2C1, MPU6050_ADDR, SMPLRT_DIV_REG, Data);
    		Data = 0x00;
		MPU_write(I2C1, MPU6050_ADDR, ACCEL_CONFIG_REG, Data);

		Data = 0x00;
		MPU_write(I2C1, MPU6050_ADDR, GYRO_CONFIG_REG, Data);
	}	
}

4. Hàm đọc gia tốc 3 trục trên MPU6050

void MPU6050_Read_Accel(void)
{
	uint8_t Rx_data[6];
        // Read 6 BYTES of data starting from ACCEL_XOUT_H register

	MPU_read(I2C1, MPU6050_ADDR, ACCEL_XOUT_H_REG, Rx_data, 6);

	Accel_X_RAW = (int16_t)(Rx_data[0] << 8 | Rx_data [1]);
	Accel_Y_RAW = (int16_t)(Rx_data[2] << 8 | Rx_data [3]);
	Accel_Z_RAW = (int16_t)(Rx_data[4] << 8 | Rx_data [5]);

	Ax = Accel_X_RAW/16384.0;
	Ay = Accel_Y_RAW/16384.0;
	Az = Accel_Z_RAW/16384.0;
}

5. Hàm main đọc dữ liệu và truyền lên máy tính qua UART

 int main(void)
 {	

   Mpu6050_Init();
	 delay_init();
	 
	 USARTx_Init(USART2, Pins_PA2PA3, 115200);
	 printf("abc\r\n");

  while(1)
	{
         MPU6050_Read_Accel ();
	 delay_ms (1000);
	 printf("Ax= %f\n ",Ax);
	 printf("Ay= %f \n",Ay);
	 printf("Az= %f \n",Az);
	}
 }

6. Kết quả

Link code mẫu

Trả lời

Email của bạn sẽ không được hiển thị công khai.