【记录】esp32 s3 devkitc 1开发板micropython固件使用ad7705 16bit模数转换器

网上看到很多关于AD7705的驱动,大部分都是stm32开发板,C语言的。但是没有关于esp32 micropython固件下的驱动。于是参考网上的资料写了如下驱动。

由于我不是相关专业的人,所以以下内容可能会出现不规范或者错误的地方,恭请斧正。

参考文章放在后面

模块的模样

首先放一个简易的代码,以下代码需要自己根据开发板自己定义好引脚

from machine import Pin, SPI
import utime

#定义引脚,这是我使用的引脚,根据自己情况改。esp32的开发板改数字就行
#另外我用的是软件SPI,硬件SPI不知怎的有点问题,就不放代码了,虽然我用了一些硬件spi的引脚
CS_PIN = Pin(39, Pin.OUT)
RESET_PIN = Pin(45, Pin.OUT)
DIN_PIN = Pin(11, Pin.OUT)
SCK_PIN = Pin(12, Pin.OUT)
DOUT_PIN = Pin(13, Pin.IN)
DRDY_PIN = Pin(42, Pin.IN)

#软件SPI,开发板发送命令给模块
def spi_send(data):
    for i in range(7, -1, -1):
        DIN_PIN.value((data & (1 << i)) != 0)
        SCK_PIN.value(0)
        utime.sleep_us(1)
        SCK_PIN.value(1)
        utime.sleep_us(1)

#开发板接收数据
def spi_receive():
    data = 0
    for i in range(7, -1, -1):
        SCK_PIN.value(0)
        utime.sleep_us(1)
        if DOUT_PIN.value():
            data |= (1 << i)
        SCK_PIN.value(1)
        utime.sleep_us(1)
    return data

#片选cs为0,spi通信开始,调用发送方法,cs为1,关闭通信
def tm7705_send_byte(data):
    CS_PIN.value(0)
    spi_send(data)
    CS_PIN.value(1)

#cs=0,调spi接收,cs=1
def tm7705_receive_byte():
    CS_PIN.value(0)
    result = spi_receive()
    CS_PIN.value(1)
    return result

#初始化时同步SPI接口时序,文档中提到过,输入32个1
def tm7705_sync_spi():
    CS_PIN.value(1)
    for _ in range(4):
        tm7705_send_byte(0xFF)

#硬件复位方法
def tm7705_reset_hard():
    RESET_PIN.value(1)
    utime.sleep_ms(1)
    RESET_PIN.value(0)
    utime.sleep_ms(2)
    RESET_PIN.value(1)
    utime.sleep_ms(1)

#等待drdy状态
def tm7705_wait_drdy():
    for _ in range(8000):
        if not DRDY_PIN.value():
            break

#集合了初始化的所有动作
def tm7705_init():
    tm7705_reset_hard()
    utime.sleep_ms(5)
    tm7705_sync_spi()
    utime.sleep_ms(5)
    tm7705_send_byte(0x20)  #写通信寄存器
    tm7705_send_byte(0x0C)  #设置时钟及频率之类
    tm7705_calib_self(1)
    utime.sleep_ms(5)

#两种通道以及工作方式
def tm7705_calib_self(channel):
    if channel == 1:
        tm7705_send_byte(0x10 | 0x00)  # 在通信寄存器写“我要写设置寄存器,通道1”
        tm7705_send_byte(0x40)         # 写设置寄存器
    elif channel == 2:
        tm7705_send_byte(0x10 | 0x01)  # 在通信寄存器写“我要写设置寄存器,通道2”
        tm7705_send_byte(0x40)         # 写设置寄存器
    tm7705_wait_drdy()

#读取某个通道的结果
def tm7705_read_adc(channel):
    tm7705_wait_drdy()
    if channel == 1:
        tm7705_send_byte(0x38)  # 通道1
    elif channel == 2:
        tm7705_send_byte(0x39)  # 通道2
    return (tm7705_receive_byte() << 8) + tm7705_receive_byte()

#以下为示例,也是正常应该走的流程,最后输出结果,呃,自己改
tm7705_init()                              #初始化所需动作集合
adc_value = tm7705_read_adc(1)             #读通道1的值
adc_ev    = (adc_value-33000) * 3.3/14000  #我自己写的0-3.3范围的结果(不严谨)
print("ADC Value:", adc_value, adc_ev)

关于这个模块的使用,以及原理,很多文章都带着看数据手册了,我就不重复了。

大体说一下有关上面代码都干了什么。以及模块工作的一些内容。

先说一下通信,这个模块用的是4线spi,里面有8个寄存器,也就是8个存放数据的地方。根据官方手册上讲的,如果想要读取或者写入某一个寄存器,那么得先通知通信寄存器一声。也就是说,如果我想写设置寄存器,那么正确的流程是先通过mosi这个引脚告诉通信寄存器“我要写设置寄存器”这条指令,然后再通过mosi这个引脚再发送想要写的内容。那么如果我想读数据寄存器,那么就得先通过mosi告诉通信寄存器“我要读数据寄存器”指令,然后在miso引脚等待模块把数据发送过来。

了解了通信方式之后,根据官方文档就能查出不同指令如何用mosi引脚发送,也就是二进制的指令。但是,这个模块不是通电就能用,如果不初始化就会出现网上说的drdy引脚一直是高电平的情况。

初始化的具体方法在官方文档后面几页,内容大概就是,先得操控复位引脚,以某种规律高低高低。。。;然后同步spi接口时序,文档中说的是输入32个1;然后写时钟寄存器;然后写设置寄存器;校准等等(注意不管写还是读哪个寄存器都是两步,也就是先得写通信寄存器)。

初始化完成之后,模块就开始正常工作了,这时模块在不断读取外接模拟输入,量化之后把结果写入数据寄存器,对于我们来说只能读数据寄存器,开发板是不能写数据寄存器的。根据官方文档提到过,当drdy引脚处于低电平则说明,用户可以读取数据了。

另外,不知为何,我使用硬件spi时,返回值固定为65535,是波特率设置的问题吗?还是我不会用相关方法,总之就是得不到想要的结果。还请厉害的大佬指点一二。

参考

esp32官网的文档,参考了管脚布局

ad7705芯片的官方英文数据手册

有关论坛的讨论

TM7705中文数据手册

micropython中文社区的一个求助

另外,我想说一下我参考的最后一个连接,就是求助的那个,这个里面的代码逻辑是对的,与C语言的驱动一样的处理方法(当然我的也是,都是按官方文档来的),但是这个用的是pyb模块,而且驱动里面是self。什么,由于我没学过代码所以并不明白这样写的优点。主要问题是里面有几个数写错了,也就是引脚的工作状态和延时,导致初始化没完成。再就是数据处理我没看懂什么意思,应该也是对的。说了这么些主要是想说这个驱动写的完善一些,有需要的可以对照我上面的代码改一下,我试过了可行。不过改的地方实在有些多,而且很多函数我看不懂就直接给他换了,最后就没有问题了。不过在这里我就不放改后的代码了,涉及一些问题。完善好之后确实比我写的要好,规范。有需要可以自己搞一下,过程也不算难。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值