咚咚咚————【封装驱动】ADS1256驱动程序,分享交流自己编写的程序。
注意此程序好像还有一些BUG,我读取出来的电压比万用表测的低0.3V左右
这个是ADS1256我查手册总结的编程注意事项
tCLKIN = 1/7.680000MHz = 130ns
tDATA = 1/Data Rate Max = 30KHz
SCLK Period Min =4tCLKIN =520ns
SCLK Period Max =10tDATA
SCLK High Min =200ns
SCLK High Max =9tDATA
SCLK Low Min =200ns
以SCLK Period Min=600ns来计算,SCLK频率不要超过1.66MHz
以SCLK Period Min=800ns来计算,SCLK频率不要超过1.25MHz
以Data Rate Max=30KHz来计算tDATA=33.3us
SCLK频率不能低于3KHz
SCLK高电平时间不能超过300us
DIN setup time =50ns
DIN setup hold =50ns
SCLK复位模式
一、first high pulse = 39us-65us
二、second high pulse = 72us-97us
三、third high pulse = 137us-162us
四、every low pulse > 0.65us
每个操作/命令需要间隔 50tCLKIN = 6.5us
注意:
nnnn =需要读/写的寄存器数量-1
rrrr =需要读/写的寄存器地址
例如,读或者写三个寄存器,nnnn就是3-1 = 2 即(0010)。
CS线不能随便拉高拉低,执行完一套动作前拉低,一套动作执行完再拉高。
/********************************************
主控芯片:STM32 Controller
模块型号:ADS1256
通讯方式:SPI串口通信
作者:苏夏雨
授权:未经作者允许,禁止转载
********************************************/
//定义模块头文件名称
#ifndef _ADS1256_H
#define _ADS1256_H
//定义模块使用头文件
#include "sys.h"
#include "delay.h"
#include "usart.h"
//定义模块使用的引脚
#define DRDY HAL_GPIO_ReadPin(GPIOI,GPIO_PIN_2)
#define CS_H HAL_GPIO_WritePin(GPIOI,GPIO_PIN_1,GPIO_PIN_SET)
#define CS_L HAL_GPIO_WritePin(GPIOI,GPIO_PIN_1,GPIO_PIN_RESET)
#define RESET_H HAL_GPIO_WritePin(GPIOI,GPIO_PIN_0,GPIO_PIN_SET)
#define RESET_L HAL_GPIO_WritePin(GPIOI,GPIO_PIN_0,GPIO_PIN_RESET)
//定义模块使用的函数
void ADS1256_Init(void);
void ADS1256_Read(u8 MUX);
//定义模块寄存器地址
/*ADS1256寄存器地址*/
#define REG_STATUS 0x00 //状态寄存器
#define REG_MUX 0x01 //通道寄存器
#define REG_ADCON 0x02 //AD控制寄存器
#define REG_DRATE 0x03 //采样速率寄存器
#define REG_IO 0x04 //IO控制寄存器
#define REG_OFC0 0x05 //OFC校准寄存器:offset calibration
#define REG_OFC1 0x06 //OFC
#define REG_OFC2 0x07 //OFC
#define REG_FSC0 0x08 //FSC校准寄存器:full-scale calibration
#define REG_FSC1 0x09 //FSC
#define REG_FSC2 0x0A //FSC
/*ADS1256寄存器命令*/
#define CMD_RDATA 0x01 //单次读取数据
#define CMD_RDATAC 0x03 //连续读取数据
#define CMD_SDATAC 0x0F //停止连续读取
#define CMD_RREG 0x10 //写寄存器
#define CMD_WREG 0x50 //读寄存器
#define CMD_SELFCAL 0xf0 //偏移增益自动校准
#define CMD_SELFOCAL 0xf1 //抵消自动校准
#define CMD_SELFGCAL 0xf2 //获取自动校准
#define CMD_SYSOCAL 0xf3 //系统偏移校准
#define CMD_SYSGCAL 0xf4 //系统增益校准
#define CMD_SYNC 0xfc //同步AD转换
#define CMD_STANDBY 0xfd //待机
#define CMD_WAKEUP 0x00 //唤醒
#define CMD_RESET 0xfe //复位
/*ADS1256放大器设置*/
#define PGA_1 0x00 //量程±5.000000V
#define PGA_2 0x01 //量程±2.500000V
#define PGA_4 0x02 //量程±1.250000V
#define PGA_8 0x03 //量程±0.625000V
#define PGA_16 0x04 //量程±0.312500V
#define PGA_32 0x05 //量程±0.156250V
#define PGA_64 0x06 //量程±0.078125V
/*ADS1256采样速率设置*/
#define DRATE_30000SPS 0xF0 //速率30000次/秒
#define DRATE_15000SPS 0xE0 //速率15000次/秒
#define DRATE_7500SPS 0xD0 //速率7500次/秒
#define DRATE_3750SPS 0xC0 //速率3750次/秒
#define DRATE_2000SPS 0xB0 //速率2000次/秒
#define DRATE_1000SPS 0xA1 //速率1000次/秒
#define DRATE_500SPS 0x92 //速率500次/秒
#define DRATE_100SPS 0x82 //速率100次/秒
#define DRATE_60SPS 0x72 //速率60次/秒
#define DRATE_50SPS 0x63 //速率50次/秒
#define DRATE_30SPS 0x53 //速率30次/秒
#define DRATE_25SPS 0x43 //速率25次/秒
#define DRATE_15SPS 0x33 //速率15次/秒
#define DRATE_10SPS 0x23 //速率10次/秒
#define DRATE_5SPS 0x13 //速率5次/秒
#define DRATE_2SPS 0x03 //速率2次/秒
/*ADS1256复用器通道选择*/
#define MUXP_AIN0 0x00 //正极=AIN0
#define MUXP_AIN1 0x10 //正极=AIN1
#define MUXP_AIN2 0x20 //正极=AIN2
#define MUXP_AIN3 0x30 //正极=AIN3
#define MUXP_AIN4 0x40 //正极=AIN4
#define MUXP_AIN5 0x50 //正极=AIN5
#define MUXP_AIN6 0x60 //正极=AIN6
#define MUXP_AIN7 0x70 //正极=AIN7
#define MUXP_AINCOM 0x80 //正极=ACOM
#define MUXN_AIN0 0x00 //负极=AIN0
#define MUXN_AIN1 0x01 //负极=AIN1
#define MUXN_AIN2 0x02 //负极=AIN2
#define MUXN_AIN3 0x03 //负极=AIN3
#define MUXN_AIN4 0x04 //负极=AIN4
#define MUXN_AIN5 0x05 //负极=AIN5
#define MUXN_AIN6 0x06 //负极=AIN6
#define MUXN_AIN7 0x07 //负极=AIN7
#define MUXN_AINCOM 0x08 //负极=ACOM
#endif
/********************************************
主控芯片:STM32 Controller
模块型号:ADS1256
通讯方式:SPI串口通信
作者:苏夏雨
授权:未经作者允许,禁止转载
********************************************/
#include "ads1256.h"
SPI_HandleTypeDef SPI2_Handler;//SPI2句柄
/**************************SPI配置程序**************************/
void SPI2_Init(void)//SPI2初始化
{
SPI2_Handler.Instance=SPI2; //SP2
SPI2_Handler.Init.Mode=SPI_MODE_MASTER; //设置SPI工作模式,设置为主模式
SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES; //设置SPI单向或者双向的数据模式:SPI设置为双线模式
SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平
SPI2_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI2_Handler.Init.NSS=SPI_NSS_SOFT; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI2_Handler.Init.NSSPMode=SPI_NSS_PULSE_DISABLE; //NSS信号脉冲失能
SPI2_Handler.Init.MasterKeepIOState=SPI_MASTER_KEEP_IO_STATE_ENABLE; //SPI主模式IO状态保持使能
SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64;//定义波特率预分频的值:波特率预分频值为64
SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE; //关闭TI模式
SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
SPI2_Handler.Init.CRCPolynomial=7; //CRC值计算的多项式
HAL_SPI_Init(&SPI2_Handler);
__HAL_SPI_ENABLE(&SPI2_Handler); //使能SPI2
}
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)//SPI2底层服务函数
{
GPIO_InitTypeDef GPIO_Initure;
RCC_PeriphCLKInitTypeDef SPI2ClkInit;
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOF时钟
__HAL_RCC_SPI2_CLK_ENABLE(); //使能SPI2时钟
//设置SPI2的时钟源
SPI2ClkInit.PeriphClockSelection=RCC_PERIPHCLK_SPI2; //设置SPI2时钟源
SPI2ClkInit.Spi123ClockSelection=RCC_SPI123CLKSOURCE_PLL; //SPI2时钟源使用PLL1Q
HAL_RCCEx_PeriphCLKConfig(&SPI2ClkInit);
//PB13,14,15
GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH; //快速
GPIO_Initure.Alternate=GPIO_AF5_SPI2; //复用为SPI2
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化
}
/**************************ADS1256程序**************************/
u8 ADS1256_ReadWrite(u8 TxData)
{
u8 Rxdata;
delay_us(10);
HAL_SPI_TransmitReceive(&SPI2_Handler,&TxData,&Rxdata,1,1000);
delay_us(10);
return Rxdata; //返回收到的数据
}
void ADS1256_Write_Reg(u8 reg,u8 cmd)//写一个寄存器
{
CS_L;delay_us(2);
while(DRDY){};
delay_us(10);
ADS1256_ReadWrite(CMD_WREG | (reg & 0x0F));
delay_us(10);
ADS1256_ReadWrite(0);
delay_us(10);
ADS1256_ReadWrite(cmd);
delay_us(10);
//CS_H;delay_us(2);
}
u8 ADS1256_Read_Reg(u8 reg)
{
u8 temp=0;
CS_L;delay_us(2);
while(DRDY){};
delay_us(10);
ADS1256_ReadWrite(CMD_RREG | (reg & 0x0F));
delay_us(10);
ADS1256_ReadWrite(0);
delay_us(10);
temp=ADS1256_ReadWrite(0);
delay_us(10);
//CS_H;delay_us(2);
return temp;//返回数据
}
void ADS1256_Init(void)
{
//配置GPIO设置
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOI_CLK_ENABLE(); //开启GPIOI时钟
GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_0; //CS/RESET
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH; //高速
HAL_GPIO_Init(GPIOI,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_2; //DRDY
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入模式
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH; //高速
HAL_GPIO_Init(GPIOI,&GPIO_Initure);
SPI2_Init(); //初始化SPI2
delay_init(400); //延时初始化
uart_init(921600); //串口初始化
CS_L;
RESET_L;
delay_us(100);
RESET_H;
delay_us(100);
while(DRDY);
delay_us(10);
ADS1256_Write_Reg(REG_STATUS,0x04);//关闭缓冲器,打开自校准,输出高位先输出
delay_us(10);
ADS1256_Write_Reg(REG_MUX,MUXP_AIN0|MUXN_AINCOM);//通道复用器(P=AIN0,N=COM4)
delay_us(10);
ADS1256_Write_Reg(REG_ADCON,PGA_1);//PGA放大倍数=1(5.000000V)
delay_us(10);
ADS1256_Write_Reg(REG_DRATE,DRATE_1000SPS);//采样速率2000Hz,每通道250Hz
CS_H;
delay_us(10);
}
void ADS1256_Read(u8 MUX)
{
/* u8 Result=0;
u8 buf[12]={" \r\n"};
Result = ADS1256_Read_Reg(REG_MUX);
buf[0]=(u8)(Result%1000/100)+0x30;
buf[1]=(u8)(Result%100/10)+0x30;
buf[2]=(u8)(Result%10/1)+0x30;
HAL_UART_Transmit(&UART1_Handler,buf,sizeof(buf),1000);*/
u8 buf[12]={"0.0000V "};
u32 Result=0;
u32 Data1,Data2,Data3;
double Data;
CS_L;delay_us(2);
while(DRDY);
delay_us(10);
ADS1256_Write_Reg(REG_MUX,MUX);
delay_us(10);
ADS1256_ReadWrite(CMD_SYNC);
delay_us(10);
ADS1256_ReadWrite(CMD_WAKEUP);
delay_us(10);
while(DRDY);
delay_us(10);
ADS1256_ReadWrite(CMD_RDATA);
delay_us(10);
Data1 = ADS1256_ReadWrite(0);
delay_us(10);
Data2 = ADS1256_ReadWrite(0);
delay_us(10);
Data3 = ADS1256_ReadWrite(0);
delay_us(10);
CS_H;delay_us(2);
Result = (Data1<<16) | (Data2<<8) | Data3;
Data = Result/1.6777215;
Result = Data;
buf[0]=(u8)(Result/1000000)+0x30;
buf[2]=(u8)(Result%1000000/100000)+0x30;
buf[3]=(u8)(Result%100000/10000)+0x30;
buf[4]=(u8)(Result%10000/1000)+0x30;
HAL_UART_Transmit(&UART1_Handler,buf,sizeof(buf),1000);
}