当前位置:网站首页>Programming implementation of I2C communication protocol
Programming implementation of I2C communication protocol
2022-07-18 21:03:00 【Xiao AI Kun who likes code】
Code implementation at24c02 Between master device and slave device I2C data communication
(at24c02 Equipment schematic information is being shared stm32 In the data )
The idea of code editing is to realize the start signal , End signal , Send slave address and write signal , Send the on-chip address , Send written data , Encapsulate these steps into code functions , Call .
#include <stm32f4xx.h>
#include <iic.h>
#include <delay.h>
#include <stdio.h>
void ic_init(void)
{
// Clock initialization structure
GPIO_InitTypeDef GPIO_InitStruct;
//1. Turn on GPIOB The clock of
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
//2.GPIO initialization PB8 PB9 Pin
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // The output mode
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;// Push pull output
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;// High speed
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;// No up and down
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;// Pin for 9 and 10
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
// Set the serial data line SDA Transmission direction ( Two-way communication ), Mode of incoming pin
void set_sda_io(GPIOMode_TypeDef IO)
{
GPIO_InitTypeDef GPIO_InitStruct;
//2.GPIO initialization PB9
GPIO_InitStruct.GPIO_Mode = IO;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;// Push pull output
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;// High speed
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;// No up and down
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;// Pin for 9 Pin No
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
// Start signal
void iic_start(void)
{
// Set the serial data bus SDA The output mode
set_sda_io(GPIO_Mode_OUT);
// Both buses are idle , The default is high
SCL = 1; // Clock bus high
SDA_OUT = 1; // Data bus low level
delay_us(5);
// Serial data bus SDA Pull it down
SDA_OUT = 0;
delay_us(5);
//SDA After pulling down , Lower the clock bus SCL, Clamp the bus
SCL = 0;
}
// Stop signal
void iic_stop(void)
{
// Serial data bus SDA The output mode
set_sda_io(GPIO_Mode_OUT);
// Serial data bus and clock bus are low level
SCL = 0;
SDA_OUT = 0;
delay_us(5);
// Serial clock bus SCL pull up
SCL = 1;
delay_us(5);
// Pull up the serial data bus SDA, here SCL and SDA All of them are high , The bus is idle
SDA_OUT = 1;
}
// Wait for the slave device to answer , return 0 Indicates a valid response , return 1 Indicates an invalid response
u8 iic_wait_ack(void)
{
u8 ack = 0;
// Serial data bus SDA The input mode , Receive response
set_sda_io(GPIO_Mode_IN);
// Pull up the serial clock bus SCL, Allow operation from the device SDA
SCL = 1;
delay_us(5);
// Read serial data bus SDA level
if(SDA_IN){
ack = 1;// Invalid response
iic_stop();// Invalid response received , Stop communication immediately
}
else{
ack = 0;
}
SCL = 0;
delay_us(5);
return ack;
}
// Generate a response signal , The ginseng ack=0 Effective response ,ack=1 Invalid response
void iic_ack(u8 ack)
{
// Set the serial data bus SDA The output mode
set_sda_io(GPIO_Mode_OUT);
// Pull down the clock line , Prepare to modify the data line level
SCL = 0;
delay_us(5);
// Set the serial data bus SDA level
if(ack){
SDA_OUT = 1;
}
else{
SDA_OUT = 0;// Effective response
}
delay_us(5);
// After the data is stable, pull up the clock line to let the slave device receive ack
SCL = 1;
delay_us(5);
SCL = 0;
}
// send out 1 Bytes of data --------- High and low
void iic_send_byte(u8 txd)
{
u8 i;
// Set the data serial bus SDA The output mode
set_sda_io(GPIO_Mode_OUT);
SCL = 0;
delay_us(5);
// Send each bit at a time from high to low
// Judge txd Is it high or low , It only needs &( And operation ) On 1<<(7-i) You can judge
//1<<(7-i) It's actually 1 Move left 7 position , Students who are not clear should review bit operations well
for(i=0;i<8;i++){
if(txd&1<<(7-i)){
SDA_OUT = 1;
}
else{
SDA_OUT = 0;
}
delay_us(5);
// Pull up the clock line bus , Let's read this bit from the device
SCL = 1;
delay_us(5);
// Pull down the clock line , Ready to send next
SCL = 0;
}
}
// receive 1 Bytes of data
u8 iic_recv_byte(void)
{
u8 rxd = 0,i;
// Set the serial clock bus SDA The input mode
set_sda_io(GPIO_Mode_IN);
SCL = 0;
// Receive each bit from high to low
for(i=0;i<8;i++){
// Wait for the other party to set the level
delay_us(5);
// Read during high level 1 Bit data
SCL = 1;
if(SDA_IN)
rxd |= 1<<(7-i);
// Ready to receive the next
delay_us(5);
SCL = 0;
}
return rxd;
}
//at24c02 Write 1 Bytes of data
void at24c02_write_byte(u8 addr,u8 data)
{
u8 ack;
// Start signal
iic_start();
// Send slave address + Write the signal 0x50<<1 | 0 = 0xa0
// Slave device address (0x50) Move left 1 position Or operations 0
iic_send_byte(0xa0);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 1\r\n");
return ;
}
// Send the written on-chip address
iic_send_byte(addr);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 2\r\n");
return ;
}
// Send written data
iic_send_byte(data);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 3\r\n");
return ;
}
// Stop signal
iic_stop();
}
//at24c02 Write 1 Page data
void at24c02_write_page(u8 addr,u8 *data,u8 len)
{
u8 ack;
// Start signal
iic_start();
// Send slave address + Write the signal 0x50<<1 | 0 = 0xa0
iic_send_byte(0xa0);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 1\r\n");
return ;
}
// Send the written on-chip address
iic_send_byte(addr);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 2\r\n");
return ;
}
// Send written data
while(len--){
iic_send_byte(*data++);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 3\r\n");
return ;
}
}
// Stop signal
iic_stop();
}
//at24c02 read 1 byte
u8 at24c02_read_byte(u8 addr)
{
u8 ack,data;
// Start signal
iic_start();
// Send slave address + Write the signal 0x50<<1 | 0 = 0xa0
iic_send_byte(0xa0);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 1\r\n");
return 0;
}
// Send read on-chip address
iic_send_byte(addr);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 2\r\n");
return 0;
}
// Start signal
iic_start();
// Send slave address + Read the signal 0x50<<1 | 1 = 0xa1
iic_send_byte(0xa1);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 3\r\n");
return 0;
}
// Receive read 1 Bytes of data
data = iic_recv_byte();
// Invalid response
iic_ack(1);
// Stop signal
iic_stop();
return data;
}
//at24c02 Read continuously
void at24c02_seq_read(u8 addr,u8 *data,u8 len)
{
u8 ack;
// Start signal
iic_start();
// Send slave address + Write the signal 0x50<<1 | 0 = 0xa0
iic_send_byte(0xa0);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 1\r\n");
return;
}
// Send read on-chip address
iic_send_byte(addr);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 2\r\n");
return;
}
// Start signal
iic_start();
// Send slave address + Read the signal 0x50<<1 | 1 = 0xa1
iic_send_byte(0xa1);
// wait for ACK
ack = iic_wait_ack();
if(ack){
printf("ack failed 3\r\n");
return;
}
// Reading data
while(len--){
// Receive read data
*data++ = iic_recv_byte();
if(len>0){
// Effective response
iic_ack(0);
}
else{
iic_ack(1);
}
}
// Stop signal
iic_stop();
}边栏推荐
- Code that programmers can't understand gradually fade out 1920-500 (1)
- 初探BLE 蓝牙电池服务
- 高数下|二重积分的概念及性质|高数叔|手写笔记
- Flutter 绘制非常有趣的贝塞尔曲线动画
- MySQL common commands for viewing database performance
- UE4 shadow: perobjectshadow verification
- 劍指 Offer 57. 和為s的兩個數字
- High numbers | calculation of double integral 1 | high numbers | handwritten notes
- 鸿蒙应用开发项目新建过程与hap包生成方法
- 第十三篇,STM32 I2C串行总线通信实现
猜你喜欢

剑指 Offer 57. 和为s的两个数字

AMASLAB-EPIC-KBS9工控机刷机文档

产业园区如何做好精细化运营管理

Pytorch 深度可分离卷积和MobileNet_v1

Initial redis (know redis and common commands)

Applet page navigation

鸿蒙开发板上安装HAP应用方法之经典

Improvement 20 of yolov5: introduction of new neural network operator into network

JS 中的事件委托是什么?

High numbers | calculation of double integral 1 | high numbers | handwritten notes
随机推荐
剑指 Offer 53 - II. 0~n-1中缺失的数字
nexus5 root 刷机
待处理问题
Scrcpy projection
摸清企业选址动机及需求,高效开展招商引资工作
R语言使用data.table包对dataframe行数据进行排序(基于多字段、变量进行数据行排序,不重新排序实际的数据变化)、并计算排序后分组的累积加和值
数学建模不会 LaTex 排版 | 教你如何在 Word 中优雅地使用漂亮的 LaTex 公式
Markdown basic syntax format
基于STM32电源模块开发
【缓存】一种新的缓存 Caffeine Cach 介绍
How to do fine operation management in industrial parks
Interview question 5
【云原生】DevOps(四):集成Sonar Qube
Initial redis (know redis and common commands)
Termux related
putchar()
Win10 如何将FAT32格式磁盘不用格式化无损转化为NFTS格式
21. How does the program execute after entering the URL in the browser?
High numbers | calculation of double integral 1 | high numbers | handwritten notes
R语言使用glm函数构建泊松对数线性回归模型处理三维列联表数据构建饱和模型、使用step函数基于AIC指标实现逐步回归筛选最佳模型