适用于树莓派的高精密模数转换器
功能引脚 | 树莓派接口(BCM) | 树莓派接口(WiringPi) | 描述 |
DRDY | P17 | P0 | ADS1263数据就绪输出,低电平有效 |
RESET | P18 | P1 | ADS1263复位输入 |
CS | P22 | P3 | ADS1263片选,低电平有效 |
DIN | P10 | P12 | SPI数据输入 |
DOUT | P9 | P13 | SPI数据输出 |
SCK | P11 | P14 | SPI时钟信号 |
本模块默认为单端测量模式,即AVDD连接5V,AVSS连接GND,并将COM口配置成负端输入且连接到GND。
所以此时您可以直接引出GND(或COM)和任意IN至测量目标处测量电压。
如果您想使用差分输入测量,请按照以下方式操作硬件:
如果您需要使用RTD功能,请按照以下方式操作硬件:
本模块使用的通信类型为SPI通信,具体描述可以查阅数据手册Page 11-12
SPI通信部分在手册中的时序图如下图所示:
CS为从机片选, 仅当CS为低电平时,芯片才会被使能;
SCLK为SPI通信时钟;
DIN为数据输入即MOSI,主设备数据输出,从设备数据输入;
DOUT为数据输出即MISO,主设备数据输入,从设备数据输出;
DRDY,为数据准备状态输出脚,当ADC1的数据准备就绪时DRDY会输出低电平。
对于SPI通信而言,数据是有传输时序的,即数据的捕获需要时钟信号的某个边沿触发,而这个边沿就是由时钟极性(CPOL)与时钟相位(CPHA)的组合决定的:
CPOL的高低决定串行同步时钟的空闲状态电平,CPOL = 0,为低电平;CPOL = 1,为高电平。
CPHA的高低决定串行同步时钟是在第一时钟跳变沿还是第二个时钟跳变沿数据被采集, 当CPHA = 0,在第一个跳变沿进行数据采集;CPHA = 1,在第二个跳变沿进行数据采集。
从图中可以看出,SCL空闲时是低电平,在第二个边沿时开始传输数据,所以是模式一(0x01),一个时钟周期传输8bit数据,按位传输,高位在前,低位在后(MSB)。
提供C语言与python例程
- sudo raspi-config
- 选择Interfacing Options -> SPI -> Yes 开启SPI接口
- sudo reboot
请确保SPI没有被其他的设备占用,你可以在/boot/config.txt中间检查
- wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz
- tar zxvf bcm2835-1.68.tar.gz
- cd bcm2835-1.68/
- sudo ./configure && sudo make && sudo make check && sudo make install
- # 更多的可以参考官网:http://www.airspayce.com/mikem/bcm2835/
- sudo apt-get install wiringpi
- #对于树莓派2019年5月之后的系统(早于之前的可不用执行),可能需要进行升级:
- wget https://project-downloads.drogon.net/wiringpi-latest.deb
- sudo dpkg -i wiringpi-latest.deb
- gpio -v
- # 运行gpio -v会出现2.52版本,如果没有出现说明安装出错
- sudo apt-get update
- sudo apt-get install ttf-wqy-zenhei
- sudo apt-get install python-pip
- sudo pip install RPi.GPIO
- sudo pip install spidev
在树莓派终端运行:
- sudo apt-get install p7zip-full
- wget http://www.waveshare.net/w/upload/6/64/High-Pricision_AD_HAT_Code.7z
- 7z x High-Pricision_AD_HAT_Code.7z -r -o./High-Pricision_AD_HAT_Code
- cd High-Pricision_AD_HAT_Code/
以下命令请在 High-Pricision_AD_HAT_Code/ 下执行,否则找不到目录
- cd c
- sudo make clean
- sudo make
- sudo vim Makefile
- 将 line 13-15 的 USELIB_RPI 的注释切换即可
- sudo ./main
- cd python
- sudo python main.py
- or
- sudo python3 main.py
为了方便后续阅读,简单介绍一下硬件。
本模块使用的ADC是ADS1263,使用的SPI通信,需要关注的是模式(模式一)、速率(最大8M)、数据格式(MSB),在可以正常通信后就可以开始实现功能了。
控制主要分为发送命令和读写寄存器,命令表和寄存器表都可以在数据手册中找到。
常用的命令就是开始/结束ADC转换、读/写寄存器、重启等;寄存器主要是用来写入配置参数,程序的核心就是读写寄存器。
PS:读/写寄存器是一种特殊的命令,普通的命令是单字节的,读/写寄存器是多字节的,即读/写寄存器命令 + 需要写入/接收的数据。
因为C例程和Python例程的函数和功能是一模一样的,所以放在一起讲解。
下面以 ADS1263.c 的代码为例,在也 ADS1263.py 可以找到对应的函数:
复位函数,DEV_RST_PIN 为IC复位引脚,低电平有效,每次使用前需要进行复位操作,复位后寄存器配置会恢复默认值,需要重新配置。
- static void ADS1263_reset(void)
这三个函数分别为写命令、写寄存器、读取寄存器,每次SPI操作需要拉低DEV_CS_PIN(片选,CS)引脚,读写寄存器因为命令是两个字节所以需要发送一次0x00
- static void ADS1263_WriteCmd(UBYTE Cmd)
- static void ADS1263_WriteReg(UBYTE Reg, UBYTE data)
- static UBYTE ADS1263_Read_data(UBYTE Reg)
数据校验函数——和校验函数,本例程的读取数据都使用了和校验,也可以通过寄存器配置CRC校验
和校验主要原理是取数据的低八位相加,最后加上一个固定参数,取和后的低八位与读取到的校验字节异或,如果数据读取正确返回0(相同异或为零)
- static UBYTE ADS1263_Checksum(UDOUBLE val, UBYTE byt)
数据等待函数,DEV_DRDY_PIN为DRDY引脚,在ADC1进行数据转换时有效,在数据准备好之后会发送一个低电平
PS:ADC2不适用
- static void ADS1263_WaitDRDY(void)
芯片校验函数,返回值为1则IC为ADS1263,0为ADS1262
- UBYTE ADS1263_ReadChipID(void)
模式设置函数,1为差分模式,默认为0单端模式
- void ADS1263_SetMode(UBYTE Mode)
ADC设置函数,设置ADC的速率、PGA增益倍数、参考电压等。
具体寄存器信息都可以查表确认,需要配置其他寄存器最好按例程方式每次写入后再读取验证。
为保证数据稳定减少多通道及两个ADC之间的串扰,例程使用的数据转换延时较大且转换速率较慢,如果有速度需要可以自行修改。
PS:ADC1在使用单端测量时不建议开启PGA(默认关闭)。
- void ADS1263_ConfigADC1(ADS1263_GAIN gain, ADS1263_DRATE drate)
- void ADS1263_ConfigADC2(ADS1263_ADC2_GAIN gain, ADS1263_ADC2_DRATE drate)
芯片初始化函数,包括复位、验证、配置ADC步骤。
- UBYTE ADS1263_init(void)
选择通道函数,在需要切换ADC通道前先调用该函数。
- static void ADS1263_SetChannal(UBYTE Channal)
- static void ADS1263_SetChannal_ADC2(UBYTE Channal)
- void ADS1263_SetDiffChannal(UBYTE Channal)
- void ADS1263_SetDiffChannal_ADC2(UBYTE Channal)
读取ADC数据函数,ADC1返回值为32位数据,ADC2为24位数据。
- static UDOUBLE ADS1263_Read_ADC1_Data(void)
- static UDOUBLE ADS1263_Read_ADC2_Data(void)
获取指定通道的数据,根据模式的不同会有不同的效果,包含设置通道,读取数据操作。
- UDOUBLE ADS1263_GetChannalValue(UBYTE Channel)
- UDOUBLE ADS1263_GetChannalValue_ADC2(UBYTE Channel)
获取所有通道的数据,封装供其他文件调用,循环获取指定数量通道的数据。
获取到32位或24位的原始数据,如果要得到电压数据需要先将原始数据除以最大量程然后乘上参考电压。
而例程使用的树莓派5V(实测5.08V),因此最终电压数据为:ADC[i]/0x7fffffff*REF,负电压同理。
- void ADS1263_GetAll(UDOUBLE *ADC_Value)
- void ADS1263_GetAll_ADC2(UDOUBLE *ADC_Value)
RTD测试函数,包含了RTD的寄存器配置、ADC1的数据转换及读取。
要得到温度数据需要先算出热电阻的阻值,根据 R=U/I,将两个电阻(热电阻、参考电阻)相除化简可得:R(热电阻)/R(参考电阻) = U(热电阻) * U(参考电阻) * 2
所以 RES = (ADC[0] / 0x7fffffff * 1) * 1 * 2 * 2000
最后根据热电阻公式可得温度,例程使用的是Pt100
因此 TEMP = (RES/100 - 1) / 0.00385
- UDOUBLE ADS1263_RTD(ADS1263_DELAY delay, ADS1263_GAIN gain, ADS1263_DRATE drate)
DAC测试函数,电压设置、输出引脚设置(正负极性)、打开或关闭。
- void ADS1263_DAC(ADS1263_DAC_VOLT volt, UBYTE isPositive, UBYTE isOpen)
在main文件中,可以通过宏定义来快速修改需要进行的试验(ADC/RTD),REF 为参考电压如果需要精确测量可能需要您根据实际使用情况进行修改。