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