ADS1220开发-----驱动代码
最近收到学长的要求,开发一个24bit ADC------ADS1220,记录一下开发的过程
数据手册概览
通信引脚及其协议
- 通信协议->SPI,且仅支持SPI模式1
- 引脚分配
- cs:片选,拉低使能通信
- SCLK:SPI的时钟引脚
- DOUT/DRDY:SPI的MISO
- DIN:SPI的MOSI
- DRDY:当ADS1220完成数据转换以后就会产生下降沿跳变,处理器(MCU)可以将其接到对应的外部中断脚上来读取ADS1220是否准备好数据
ADS1220的通信命令
- RESET:复位设备-> 0x06
- START:开启设备转换,如果是单次转化,则每次转化前需要发送该命令,如果是连续转化,则需要在使能连续转化位(CM),开启转化->0x08
- POWERDOWN:进入掉电模式(为低功耗设计)->0x02
- RDATA:单次转化完成后,如若需要读取数据,则需要发送该指令,连续转化则不需要->0x10
- RREG:读取某个寄存器上的某的数值->0x2?
- WREG:将数据写入某一个寄存器->0x4?
注意:?是指低4位的设定,因为其中rr表示配置寄存器,nn表示待发送到该寄存器的寄存器的字节数-1
ADS1220通信时序图
数据手册里面指明了单次模式和连续转化模式,但是手册里也指明,时序图中都没有使用RDATA命令,所以实际上在使用的时候,读取数据前需要使用该命令。
所以单次转化读取数据的过程是:
数据完成->发送RDATA命令->连续读取三个字节->开启下次转化
连续转化:
数据完成->发送RDATA命令->连续读取三个字节
由此可见,其实单次转化和连续转化其实没有太大区别,我这里就直接使用的单次转化
相关配置寄存器
配置寄存器0
- MUX:主要是选择输入引脚的,有单端输入也有差分输入
- GAIN:增益配置
- PGA:没理解干啥的,但是我是单端,1倍增益,我就直接将该位禁用了
配置寄存器1
- DR:选择转化速率,我选择45PS
- MODE:选择工作模式,我选择正常模式
- CM:转化模式选择,我选择单次
- TS:温湿度传感器,我不用直接禁用
- BCS:这个我直接关断了
配置寄存器2
- VERF:基准电压选择,我使用内部基准电压
- FIR:滤波器频率选择,我这里不滤波
- PSW:底层电源开关,直接断开就行
- IDAC:激励电流,不用管
配置寄存器3
- l1MUX:不用管
- I2MUX:不用管
- DRDYM:选择0,使用专门的DRDY引脚来表示数据完成
驱动代码概览
使用Cubemx直接生成代码
复位指令和读取和写入的指令的宏
#define ADS1220_RESET 0X06
#define ADS1220_START 0X08
#define ADS1220_POWERDOWN 0X02
#define ADS1220_RDATA 0X10
#define ADS1220_RREG 0X20
#define ADS1220_WREG 0X40
#define ADS1220_CS_LOW() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET)
#define ADS1220_CS_HIGH() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET)
ADS1220的写入和接收函数封装
void ADS1220_Write(uint8_t dat)
{
HAL_SPI_Transmit(&hspi2, &dat, 1, 10);
}
uint8_t ADS1220ReceiveByte()
{
uint8_t SData = 0xff, Result = 0;
HAL_SPI_TransmitReceive(&hspi2, &SData, &Result, 1, 10);
return Result;
}
ADS1220写寄存器函数封装
void ADS1220_WriteRegister(int StartAddress, int NumRegs, uint8_t * pData)
{
int i;
ADS1220_CS_LOW();
/* send the command byte */
ADS1220_Write( ADS1220_WREG | (((StartAddress << 2) & 0x0c) | ((NumRegs - 1) & 0x03)));
/* send the data bytes */
for(i = 0; i < NumRegs; i++)
{
ADS1220_Write(*pData++);
}
ADS1220_CS_HIGH();
}
ADS1220初始化函数
void ADS1220_Init(void)
{
uint8_t config_0 = 0x81;
uint8_t config_1 = 0x20;
uint8_t config_2 = 0x00;
uint8_t config_3 = 0x00;
ADS1220_CS_LOW();
ADS1220_Write(ADS1220_RESET);
HAL_Delay(10);
ADS1220_CS_HIGH();
//写入配置寄存器0,使用AIN0,AIN1,1倍增益,禁用PGA
ADS1220_WriteRegister(0x00, 1, &config_0);
//写入配置寄存器1,使用正常工作模式,单次转模式,
ADS1220_WriteRegister(0x01, 1, &config_1);
//写入配置寄存器2,使用内部基准,无滤波
ADS1220_WriteRegister(0x02, 1, &config_2);
//写入配置寄存器3,使用设置独立的DRY引脚
ADS1220_WriteRegister(0x03, 1, &config_3);
ADS1220_CS_LOW();
ADS1220_Write(ADS1220_START);
}
中断函数里面开始读取数据
long Data;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
Data = 0x00000000;
ADS1220_CS_LOW();
ADS1220_Write(ADS1220_RDATA);
Data = ADS1220ReceiveByte();
Data = (Data << 8) | ADS1220ReceiveByte();
Data = (Data << 8) | ADS1220ReceiveByte();
/* sign extend data */
if (Data & 0x800000)
Data |= 0xff000000;
ADS1220_Write(ADS1220_START);
}
使用说明
对应引脚连接上,这里贴一份数据手册里的说明图
如果喜欢,请收藏加关注哦!