IIC IO方向设置-寄存器版本

问题描述:

在一个STM32单片机IIC驱动例程中看到下面的两行代码:

#define MPU_SDA_IN()  {GPIOC->CRH&=0XF0FFFFFF;GPIOC->CRH|=8<<24;}
#define MPU_SDA_OUT() {GPIOC->CRH&=0XF0FFFFFF;GPIOC->CRH|=3<<24;}

我可以告诉大家上述代码是控制PC14的代码,下面分析一下上面代码的含义,便于我们修改成自己想要定义的引脚。因为有时候我们画好了PCB,两根线插在那个位置已经提前固定好了,因此只能通过修改代码实现。

下面,引用STM32 CRH和CRL设置方向_stm32 设置管脚方向-CSDN博客中的图解释一下,STM32单片机每个字母都有0-15个引脚,例如PA0-PA15,一般来说0-15又分为高八位(8-15)和低八位(0-7),每八位引脚由寄存器中的32位控制,如下图所示,记住是每八位引脚由32位配置。通过下图我们看一下32位是怎么控制引脚模式:

看一下整个引脚控制图:

 


先分析8<<24:

找上面的表,8是1000,1000左移24位,26-24位变为1000,看看啥意思,照上面的表,27-26就变为10-----上拉/下拉输入   00 - 输入模式

再分析3<<24:

 找上面的表,3是0011,0011左移24位,27-24位变为0011,看看啥意思,照上面的表,25-24就变为00-----输出模式,50MHZ;27-26就变为11-----开漏输出模式。

引脚13和14属于高,因此是GPIOC->CRH|=8<<24,GPIOC->CRH|=3<<24

再看作用在那个引脚?

每4位管理一个引脚,8*4=32,对吧,一共需要32位,所有引脚都可以用ox0FFFFFFF-0XFFFFFFF0表示,其中0XFFFFFFF0代表0号引脚,OK,下面看看下面代码啥意思:

GPIOC->CRH&=0XF0FFFFFF代表作用在到倒数第二个引脚,即PC14
GPIOC->CRH&=0XF0FFFFFF代表作用在到倒数第二个引脚,即PC14

说明这个引脚需要频繁切换输入输出模式!

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在ESP32上进行IIC通信时,可以使用ESP-IDF提供的I2C驱动程序库进行操作。在使用该库时,可以使用以下函数来写寄存器: ```c esp_err_t i2c_write_byte(i2c_port_t i2c_num, uint8_t addr, uint8_t reg, uint8_t data); ``` 这个函数的参数含义如下: - `i2c_num`: I2C总线的编号,取值为`I2C_NUM_0`或者`I2C_NUM_1`。 - `addr`: 要访问的I2C设备的地址。 - `reg`: 要写入数据的寄存器地址。 - `data`: 要写入的数据。 在使用该函数时,可以通过调用以下函数来初始化I2C总线和设备: ```c esp_err_t i2c_master_init(i2c_port_t i2c_num, const i2c_config_t *conf); ``` 该函数的参数`conf`是一个结构体类型,可以在其中设置I2C总线的时钟频率、地址模式等参数。 在使用这些函数之前,需要先在ESP-IDF的配置文件中设置I2C的GPIO管脚,同时在程序中引入I2C驱动程序库的头文件。 这里是一个写入寄存器的示例代码,供您参考: ```c #include <stdio.h> #include "driver/i2c.h" #define I2C_MASTER_SCL_IO 22 /*!< GPIO number for I2C master clock */ #define I2C_MASTER_SDA_IO 21 /*!< GPIO number for I2C master data */ #define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ void i2c_master_init() { i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = I2C_MASTER_SDA_IO; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = I2C_MASTER_SCL_IO; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = I2C_MASTER_FREQ_HZ; i2c_param_config(I2C_MASTER_NUM, &conf); i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0); } esp_err_t i2c_write_byte(i2c_port_t i2c_num, uint8_t addr, uint8_t reg, uint8_t data) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, reg, true); i2c_master_write_byte(cmd, data, true); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } void app_main() { i2c_master_init(); uint8_t addr = 0x68; // I2C设备地址 uint8_t reg = 0x00; // 要写入的寄存器地址 uint8_t data = 0x12; // 要写入的数据 esp_err_t ret = i2c_write_byte(I2C_MASTER_NUM, addr, reg, data); if (ret == ESP_OK) { printf("Write success!\n"); } else { printf("Write failed!\n"); } } ``` 在这个示例代码中,我们使用ESP-IDF的I2C驱动程序库,通过GPIO 21和GPIO 22两个管脚来实现I2C总线的连接。在`app_main`函数中,我们调用`i2c_master_init`函数来初始化I2C总线,在`i2c_write_byte`函数中调用了ESP-IDF提供的I2C写入函数,将数据写入到指定的寄存器中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值