qingchen 发表于 2024-1-16 11:38:44

求助树莓派驱动AD7606

最近尝试树莓派4b驱动AD7606,但对python语法不是很了解,只能网上找了找例子试了试,但感觉最后采样传回的数据不正常。我想让ad7606可以一直工作,采样两个通道传回的模拟信号,用spi传回显示就行,请大佬帮忙看看该怎么改一下。

代码如下:

import RPi.GPIO as GPIO, numpy as np, spidev, time, sys
#导入gpio库(操作gpio)、numpy用于数值计算,spidev用于SPI通信,time用于时间控制,sys用于系统参数和功能
GPIO.setwarnings(False) #关闭io警告,避免操作过程出现不必要的警告

SAMPLING_POINTS = 10000 #采样点数
nums = 0 #初始化变量,记录采样的数量

# 定义引脚
AD_CS_PIN = 3 #低有效
AD_RESET_PIN = 5
AD_CONVST_PIN = 7 #pwm控制转换启动
AD_RANGE_PIN = 11
AD_OS0_PIN = 13
AD_OS1_PIN = 15
AD_OS2_PIN = 31
AD_BUSY_PIN = 29
GPIO.setmode(GPIO.BOARD) #物理引脚
GPIO.setup(AD_CS_PIN, GPIO.OUT)
GPIO.setup(AD_RESET_PIN, GPIO.OUT)
GPIO.setup(AD_OS0_PIN, GPIO.OUT)
GPIO.setup(AD_OS1_PIN, GPIO.OUT)
GPIO.setup(AD_OS2_PIN, GPIO.OUT)
GPIO.setup(AD_RANGE_PIN, GPIO.OUT)
GPIO.setup(AD_CONVST_PIN, GPIO.OUT)
GPIO.setup(AD_BUSY_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) #启用上拉电阻,低表示正在转换

num_rows = 8 #定义数据矩阵的行数
num_columns = SAMPLING_POINTS #定义数据矩阵的列数,与采样点数一致

#SPI 通信设备初始化,设置spi通信参数
spi = spidev.SpiDev() #spi是SPI通信的设备对象
spi.open(0, 0) #打开SPI接口,使用总线0,设备0
spi.max_speed_hz = 8000000 #设置SPI通信速度为8MHz
spi.mode = 0b00 #设置SPI模式,采用cpol=0,cpha=0的模式

ad7606SamplingDoneFlag = 0

data2 = np.zeros((8, 1000))

def AD7606_Raspberry_Pi(RANGE =1, OS = 0): #定义了一个函数AD7606_Raspberry_Pi(RANGE = 1, OS = 0),用于控制AD7606的采样
    global AD_CS_PIN, AD_RESET_PIN, AD_CONVST_PIN, AD_OS0_PIN, AD_OS1_PIN, AD_OS2_PIN, AD_RANGE_PIN, ad7606SamplingDoneFlag
    # Initialize CS pin
    GPIO.output(AD_CS_PIN, GPIO.LOW) #初始化片选信号低电平

    # Reset AD7606 #重置AD7606芯片
    GPIO.output(AD_RESET_PIN, GPIO.LOW)# 将RESET引脚拉低
    time.sleep(0.001) # 等待一段时间,以确保复位操作完成
    GPIO.output(AD_RESET_PIN, GPIO.HIGH) # 将RESET引脚拉高,完成复位操作
    time.sleep(0.001)# 再次等待一段时间,以确保复位操作完成
    GPIO.output(AD_RESET_PIN, GPIO.LOW)# 将RESET引脚再次拉低

    # PWM 通过PWM信号启动AD7606的转换。PWM信号的频率为100000Hz,占空比为99%
    PWM0 = GPIO.PWM(AD_CONVST_PIN, 100000)
    PWM0.start(99)

    # 设置OS(过采样)模式 根据输入参数OS,确定OS引脚的模式。遍历三个OS引脚,根据计算结果设置它们的电平状态
    MODE = OS # 获取OS参数的值
    M = # 初始化一个长度为3的列表,用于存储OS参数的每一位值
    for i in range(3):# 循环3次,因为OS参数有3位
      M = MODE % 2 # 取模2操作,判断OS参数的每一位是0还是1
      MODE = MODE // 2# 整除2操作,将OS参数右移一位,为下一次循环准备
    if M == 1:# 如果OS参数的最高位是1
      GPIO.output(AD_OS0_PIN, GPIO.HIGH) # 将OS0引脚设置为高电平
    else:
      GPIO.output(AD_OS0_PIN, GPIO.LOW)
    if M == 1:# 如果OS参数的次高位是1
      GPIO.output(AD_OS0_PIN, GPIO.HIGH)
    else:
      GPIO.output(AD_OS0_PIN, GPIO.LOW)
    if M == 1:# 如果OS参数的最低位是1
      GPIO.output(AD_OS0_PIN, GPIO.HIGH)
    else:
      GPIO.output(AD_OS0_PIN, GPIO.LOW)
      
    if RANGE == 1: #根据输入参数RANGE,设置量程。如果RANGE为1,则设置范围为±10V
      GPIO.output(AD_RANGE_PIN, GPIO.HIGH)
    else:
      GPIO.output(AD_RANGE_PIN, GPIO.LOW)
#等待采样完成
    while True:#进入无限循环,等待AD7606完成采样
      if ad7606SamplingDoneFlag: #如果采样完成标志ad7606SamplingDoneFlag被设置,则关闭PWM信号,停止转换过程
            PWM0.ChangeDutyCycle(0)#PWM0.stop()
            GPIO.output(AD_CS_PIN, GPIO.HIGH)
            ad7606SamplingDoneFlag = 1 #之后将采样完成标志重置为未完成
            GPIO.cleanup() #清理GPIO设置
            break #退出循环
#回调函数部分
def call_back(channel):
    global AD_CS_PIN, array, nums, ad7606SamplingDoneFlag # # 声明全局变量
    if nums < SAMPLING_POINTS:# 如果采样点数小于设定的最大采样点数
      ad7606SamplingDoneFlag = 0 #重置采样完成标志
      for i in range(8):#对每个通道进行采样
            GPIO.output(AD_CS_PIN, GPIO.LOW)# 将片选信号拉低,选中AD7606
            rx_data = spi.xfer2() # 从SPI接口读取数据
            first_bit = (rx_data >> 7) & 1 # 获取数据的最高位是否为1
            data = (rx_data << 8) | rx_data# 重组数据,得到完整的16位数据
            if first_bit == 1: # 根据最高位来决定数据的处理方式
                data2 = int(data) / 65535 * 2 * 10 - 20 # 如果最高位为1,则将数据转换为温度值并存储到data2矩阵中
            else:
                data2 = int(data)/ 65535 * 2 * 10 # 如果最高位不为1,则直接将数据存储到data2矩阵中
            
            print(i,":",data2)#如果当前通道是第一个通道,则打印该通道的数据
            GPIO.output(AD_CS_PIN, GPIO.HIGH)# 将片选信号拉高,取消选中AD7606
      nums = nums + 1# 增加采样点数计数器
    else:
      ad7606SamplingDoneFlag = 1   # 如果采样点数不小于设定的最大采样点数,则设置采样完成标志为已完成


if __name__ == "__main__": # 主执行部分:设置事件检测并初始化AD7606 ADC
    GPIO.add_event_detect(AD_BUSY_PIN, GPIO.FALLING, callback=call_back) # 当AD_BUSY_PIN引脚状态发生变化时,触发回调函数call_back()
    AD7606_Raspberry_Pi(RANGE=1, OS=0)

页: [1]
查看完整版本: 求助树莓派驱动AD7606