嵌入式linux使用python进行ADC并行模式数据采集

问题:

        最近做项目遇到一个问题,就是在嵌入式linux系统中使用python编写时序逻辑借助AD7606进行模拟信号数据采集。AD7606网上可以搜索到使用stm32的项目程序也有fpga项目程序,但是对于在嵌入式linux系统中直接编写采集程序的还是比较少。具体来说需要根据AD7606产品手册来定义采集时序。

解决方法:

        通过并行的方式进行采集,笔者也尝试过通过串行方式采集数据,但是效果并不好,因为串行需要时钟信号输入。用户空间中的时钟信号很难满足要求,如果直接通过系统内核模块方式调用系统时钟虽然可以达到ns级别的延时,但是一旦调用usb设备就会出现死机的状况,cpu的利用率也会急剧飙升。

step1:观察产品手册时序图

        以上时序图笔者主要参照图2和图4,其中图2是CONVST时序转换之后再读取,其中当busy为高电平时表示数据正在进行转换,当其为低电平时表示可以进行数据读取。图4表示当CS为低电平时,RD处于低电平时启用总线输出。FD标识V1通道数据。

step2:按照电路原理图修改焊接引脚

        默认情况下AD7606是串行模式,所以焊接的是R1,而我们需要选择的是并行模式,所以需要焊接R2而不是R1,因此需要进行硬件电路的修改。

step2:按照产品手册时序定义时序逻辑

        1.代码如下:

# -*- coding: utf-8 -*-
'''ADC并行串口读取程序,并将读取到的数据转换为16进制和10进制,并保存到相应的文件中
作者:rank_pearl
日期:2024/05/21
'''
from ctypes import *
import pandas as pd
import os
import sys
from time import sleep

# 导入公共模块路径
public_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + "/../public")
sys.path.append(public_path)
from librockmong import *
from usb_device import *
from gpio import *

if __name__ == '__main__':
    # 定义设备序列号数组
    SerialNumbers = (c_int * 20)()
    sn = 0

    # 用于存储读取的数据
    data = []

    # 扫描设备
    ret = UsbDevice_Scan(byref(SerialNumbers))
    if ret <= 0:
        print(f"Error: {ret}" if ret < 0 else "No device!")
        exit()

    for i in range(ret):
        print(f"Dev{i} SN: {SerialNumbers[i]}")
    
    # 选择设备0
    sn = SerialNumbers[0]

    # 初始化引脚为输出模式,并设置引脚对应的端口
    # 数据引脚
    ret = IO_InitPin(sn, 25, 0, 2)  # d14
    ret = IO_InitPin(sn, 26, 0, 2)  # d12
    ret = IO_InitPin(sn, 27, 0, 2)  # d10
    ret = IO_InitPin(sn, 28, 0, 2)  # d8
    ret = IO_InitPin(sn, 29, 0, 2)  # d6
    ret = IO_InitPin(sn, 30, 0, 2)  # d4
    ret = IO_InitPin(sn, 31, 0, 2)  # d2
    ret = IO_InitPin(sn, 40, 0, 2)  # d0
    ret = IO_InitPin(sn, 17, 0, 2)  # d15
    ret = IO_InitPin(sn, 18, 0, 2)  # d13
    ret = IO_InitPin(sn, 19, 0, 2)  # d11
    ret = IO_InitPin(sn, 20, 0, 2)  # d9
    ret = IO_InitPin(sn, 21, 0, 2)  # d7
    ret = IO_InitPin(sn, 22, 0, 2)  # d5
    ret = IO_InitPin(sn, 23, 0, 2)  # d3
    ret = IO_InitPin(sn, 32, 0, 2)  # d1

    # 控制引脚
    ret = IO_InitPin(sn, 42, 1, 2)  # CS (片选)
    ret = IO_InitPin(sn, 43, 1, 2)  # RST (复位)
    ret = IO_InitPin(sn, 44, 1, 2)  # CA (转换启动A)
    ret = IO_InitPin(sn, 33, 1, 2)  # FD (帧数据)
    ret = IO_InitPin(sn, 34, 0, 2)  # BUSY (忙状态)
    ret = IO_InitPin(sn, 35, 1, 2)  # SLK/RD (时钟/读取)
    ret = IO_InitPin(sn, 36, 1, 2)  # SLK/RD (时钟/读取)
    ret = IO_InitPin(sn, 37, 1, 2)  # RANGE (量程选择)
    ret = IO_InitPin(sn, 45, 1, 2)  # OS2 (超采样2)
    ret = IO_InitPin(sn, 46, 1, 2)  # OS0 (超采样0)
    ret = IO_InitPin(sn, 38, 1, 2)  # OS1 (超采样1)

    # 初始配置
    ret = IO_WritePin(sn, 37, 0)
    if ret < 0:
        print(f"error: {ret}")

    # 定义并初始化多引脚读取结构
    io_count = 16
    IO_ReadMulti_TxStruct = (IO_ReadMulti_TxStruct_t * io_count)()
    IO_ReadMulti_RxStruct = (IO_ReadMulti_RxStruct_t * io_count)()
    pins_to_read = [40, 32, 31, 23, 30, 22, 29, 21, 28, 20, 27, 19, 26, 18, 25, 17]
    for i, pin in enumerate(pins_to_read):
        IO_ReadMulti_TxStruct[i].Pin = pin

    # 定义并初始化多引脚写入结构
    io_count_manu = 6
    IO_WriteMulti_TxStruct = (IO_WriteMulti_TxStruct_t * io_count_manu)()
    IO_WriteMulti_RxStruct = (IO_WriteMulti_RxStruct_t * io_count_manu)()

    def set_manu(rst, ca, cb, cs, rd, fd):
        settings = [(43, rst), (44, ca), (36, cb), (42, cs), (35, rd), (33, fd)]
        for i, (pin, state) in enumerate(settings):
            IO_WriteMulti_TxStruct[i].Pin = pin
            IO_WriteMulti_TxStruct[i].PinState = state
        ret = IO_WriteMultiPin(sn, IO_WriteMulti_TxStruct, IO_WriteMulti_RxStruct, io_count_manu)

    # 主循环
    sleep(3)  # 初始延迟
    set_manu(0, 1, 1, 1, 1, 0)
    sleep(0.1)

    for _ in range(100):
        set_manu(0, 1, 1, 1, 1, 0)
        set_manu(1, 1, 1, 1, 1, 0)  # 复位
        set_manu(0, 1, 1, 1, 1, 0)
        set_manu(0, 0, 0, 1, 1, 0)  # 设置CA, CB
        set_manu(0, 1, 1, 1, 1, 0)
        set_manu(0, 1, 1, 0, 1, 0)  # 设置CS

        for j in range(8):
            set_manu(0, 1, 1, 0, 0, 1 if j < 1 else 0)
            ret = IO_ReadMultiPin(sn, IO_ReadMulti_TxStruct, IO_ReadMulti_RxStruct, io_count)
            if ret < 0:
                for i in range(io_count):
                    print(f"error: {IO_ReadMulti_RxStruct[i].Ret}")

            binary_str = "".join(str(IO_ReadMulti_RxStruct[i].PinState) for i in range(io_count - 1, -1, -1))
            decimal_value = int(binary_str, 2)
            hex_value = hex(decimal_value).upper()

            # 打印输出
            print(f"Decimal value: {decimal_value}")
            print(f"Hex value: {hex_value}")
            data.append(decimal_value)

        set_manu(0, 0, 0, 1, 1, 0)
        set_manu(0, 1, 1, 1, 1, 0)

    # 创建DataFrame并保存到excel
    df = pd.DataFrame(data, columns=["Decimal Value"])
    df.to_excel("io_values.xlsx", index=False)

         2.控制时序测试结果如下:

        3.运行效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值