ADS8688 STM32 HAL库 驱动和使用方法

使用HAL库

先贴上ADS8688驱动

C文件ADS8688.c

#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"
#include "ads8688.h"
void ADS8688_IO_Init(void)	   //ADS8688 IO口初始化
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  __HAL_RCC_GPIOC_CLK_ENABLE();	 //使能端口时钟
  __HAL_RCC_GPIOE_CLK_ENABLE();

  GPIO_InitStructure.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 		 //推挽输出
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = GPIO_PIN_13;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

  DAISY_L;
  CS_H;
  RST_H;
  CLK_L;
  delay_ms(5);
}

void ADS8688_Init(uint8_t ch_en)	   //ADS8688初始化
{
  ADS8688_IO_Init();
  SOFT_RESET(); //复位
  delay_ms(25);
  Set_Auto_Scan_Sequence(ch_en);//使能通道
  ADS8688_WriteReg(CH_PD,~ch_en);//通道退出低功耗状态 通道上电
  delay_ms(50);
  while(ADS8688_ReadReg(AUTO_SEQ_EN)!=ch_en)//是否使能成功
    {
      Set_Auto_Scan_Sequence(ch_en);//使能通道
      ADS8688_WriteReg(CH_PD,~ch_en);//通道退出低功耗状态 通道上电
      delay_ms(50);
    }
}

uint8_t ADS8688_SPI_Read8Bit(void)
{
  uint8_t i=0;
  uint8_t read=0;
  for(i=0; i<8; i++)
    {
      read<<=1;
      CLK_H;
      delay_us(2);
      if(READ_SDO) read++;
      CLK_L;
      delay_us(2);
    }
  return read;
}

void ADS8688_SPI_Write8Bit(uint8_t data)
{
  uint8_t i=0;
  CS_L;
  for(i=0; i<8; i++)
    {
      if(data&0x80)	SDI_H;
      else	SDI_L;
      data<<=1;
      CLK_H;
      delay_us(2);
      CLK_L;
      delay_us(2);
    }
}

void ADS8688_WriteCmd(uint16_t cmd)//写ADS8688命令寄存器
{
  CS_L;
  ADS8688_SPI_Write8Bit(cmd>>8 & 0XFF);
  ADS8688_SPI_Write8Bit(cmd & 0XFF);
  ADS8688_SPI_Write8Bit(0X00);
  ADS8688_SPI_Write8Bit(0X00);
  CS_H;
}


void SOFT_RESET(void)//软件复位
{
  ADS8688_WriteCmd(RST);
}


void AUTO_RST_Mode(void)//自动扫描模式
{
  ADS8688_WriteCmd(AUTO_RST);
}

void MAN_CH_Mode(uint16_t ch)//手动模式
{
  ADS8688_WriteCmd(ch);
}


uint8_t ADS8688_ReadReg(uint8_t addr)
{
  uint8_t data = 0;
  CS_L;
  ADS8688_SPI_Write8Bit(addr<<1);
  data = ADS8688_SPI_Read8Bit();
  data = ADS8688_SPI_Read8Bit();
  CS_H;
  return data;
}

void ADS8688_WriteReg(uint8_t addr,uint8_t data)
{
  CS_L;
  ADS8688_SPI_Write8Bit(addr<<1| 0X01);
  ADS8688_SPI_Write8Bit(data);
  CS_H;
}

void Set_Auto_Scan_Sequence(uint8_t seq)
{
  ADS8688_WriteReg(AUTO_SEQ_EN, seq);
}

void Set_CH_Range(uint8_t ch,uint8_t range)
{
  ADS8688_WriteReg(ch,range);
}


void Get_AUTO_RST_Mode_Data(uint16_t *data, uint8_t chnum)
{
  uint8_t i=0,datal=0,datah=0;
  for (i=0; i<chnum; i++)
    {
      CS_L;
      ADS8688_SPI_Write8Bit(0X00);
      ADS8688_SPI_Write8Bit(0X00);
      datah = ADS8688_SPI_Read8Bit();
      datal = ADS8688_SPI_Read8Bit();
      //delay_ms(1);
      CS_H;
      *(data+i) = datah<<8 | datal;
    }
}

uint16_t Get_MAN_CH_Mode_Data(void)
{
  u8 datah=0,datal=0;
  CS_L;
  ADS8688_SPI_Write8Bit(0X00);
  ADS8688_SPI_Write8Bit(0X00);
  datah = ADS8688_SPI_Read8Bit();
  datal = ADS8688_SPI_Read8Bit();
  CS_H;
  return (datah<<8 | datal);
}

头文件ADS8688.h

#ifndef __ADS8688_H
#define __ADS8688_H
#include "sys.h"
#include "stm32f4xx_hal.h"

//命令寄存器
#define NO_OP			0x0000 /*在选定模式下继续操作  
													在设备操作期间将SDI线连续保持为低电平(相当于向所有16位写入0)将继续在最后选择的模式(STDBY,PWR_DN或AUTO_RST,MAN_Ch_n)下进行设备操作。
													在这种模式下,设备将遵循程序寄存器(地址01h至3Ch)中已配置的相同设置。*/
#define STDBY			0x8200 /*待机模式   
													器件支持低功耗待机模式(STDBY),在该模式下,仅部分电路断电。
													内部基准电压源和缓冲器未断电,在退出STDBY模式时,可以在20 μs内为器件加电。退出STDBY模式时,程序寄存器不会复位为默认值。*/
#define PWR_DN  	0x8300/*掉电模式(PWR_DN)
													器件支持硬件和软件掉电模式(PWR_DN),在该模式下,所有内部电路均被掉电,包括内部基准电压源和缓冲器。
													如果设备在内部参考模式下运行(REFSEL = 0),则退出PWR_DN模式后,设备加电并转换所选模拟输入通道至少需要15 ms的时间。
													设备的硬件电源模式在RST / PD(输入)部分中说明。
													硬件和软件掉电模式之间的主要区别在于,当设备从硬件掉电唤醒时,程序寄存器会重置为默认值,但是当设备从软件唤醒时,程序寄存器的先前设置会保留掉电。*/
#define RST				0x8500/*重置程序寄存器(RST)
													器件支持硬件和软件复位(RST)模式,在该模式下,所有程序寄存器均复位为其默认值。也可以使用硬件引脚将设备置于RST模式*/
#define AUTO_RST	0xA000/*自动通道启用
													自动扫描所有模拟信道上的输入信号。自动扫描的通道序列可由程序寄存器中的自动扫描顺序控制寄存器(01h至02h)配置;请参阅程序寄存器映射部分。
													在此模式下,设备以升序连续循环通过所选通道,从最低通道开始,转换程序寄存器中选择的所有通道。
													序列完成后,设备返回到程序寄存器中的最低计数通道,并重复该序列。通过设置程序寄存器的范围选择寄存器,可以配置自动扫描序列中每个通道的输入电压范围。*/
#define MAN_CH_1	0xC000/**/
#define MAN_CH_2	0xC400/**/
#define MAN_CH_3	0xC800/**/
#define MAN_CH_4	0xCC00/**/
#define MAN_CH_5	0xD000/**/
#define MAN_CH_6	0xD400/**/
#define MAN_CH_7	0xD800/**/
#define MAN_CH_8	0xDC00/*手动通道n选择(MAN_Ch_n)
												通过在手动通道n扫描模式(MAN_Ch_n)中进行操作,可以对设备进行编程以转换特定的模拟输入通道。通过在命令寄存器中写入有效的手动通道n选择命令(MAN_Ch_n)来完成该编程*/
#define MAN_AUX		0XE000/*AUX通道*/

//程序寄存器
#define AUTO_SEQ_EN	0x01	/*自动扫描序列使能寄存器
													该寄存器选择单个通道以在AUTO_RST模式下进行排序。 
													该寄存器的默认值为FFh,这意味着在默认条件下所有通道都包含在自动扫描序列中。*/
#define CH_PD				0x02	/*通道掉电寄存器
													该寄存器关闭掉AUTO_RST模式下不包含的单个通道的电源。 该寄存器的默认值为00h,这意味着在默认条件下所有通道均已上电。*/
#define F_S					0X03	/*器件功能选择控制寄存器
													该寄存器中的位可用于配置菊花链操作的设备ID,并配置SDO上的输出位格式。*/

//各通道范围选择寄存器	默认值为00h
#define CHIR_1		0x05/**/
#define CHIR_2		0x06/**/
#define CHIR_3		0x07/**/
#define CHIR_4		0x08/**/
#define CHIR_5		0x09/**/
#define CHIR_6		0x0A/**/
#define CHIR_7		0x0B/**/
#define CHIR_8		0x0C/**/

#define CMD_READ	0x3F	/*命令回读寄存器
												该寄存器允许用户读取设备的操作模式。 执行此命令后,设备将输出在前一个数据帧中执行的命令字。
												有关命令寄存器的所有信息在前8位中包含,并且后8位为0。*/

/*************************************************************************************************************/
#define CH8_EN  0X80
#define CH7_EN  0X40
#define CH6_EN  0X20
#define CH5_EN  0X10
#define CH4_EN  0X08
#define CH3_EN  0X04
#define CH2_EN  0X02
#define CH1_EN  0X01

#define REF 4096
//输入范围
#define ADS8688_IR_N2_5V    0x00  //±2.5*ref  ref=4.096V  ±10.24V
#define ADS8688_IR_N1_25V   0x01  //±1.25*ref    ±5.12V
#define ADS8688_IR_N0_625V  0x02  //±0.625*ref   ±2.56V
#define ADS8688_IR_2_5V   	0x05  //0-2.5*ref      0-10.24V
#define ADS8688_IR_1_25V    0x06  //0-1.25*ref     0-5.12V

//不同量程的1个ADC值对应的电压值,即分辨率
#define CONST_N2_5V_LSB_mV  	2.5*2*REF/65535     //约为0.3mV
#define CONST_N1_25V_LSB_mV  	1.25*2*REF/65535		//约为0.156mV
#define CONST_N0_625V_LSB_mV  0.625*2*REF/65535		//约为0.078mV
#define CONST_2_5V_LSB_mV  		2.5*REF/65535				//约为0.156mV
#define CONST_1_25V_LSB_mV 	 	1.25*REF/65535			//约为0.078mV

#define SDI_H			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET)//串行通信数据输入
#define RST_H			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET)//复位
#define DAISY_H		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET)//以菊花链模式连接串行通信期间的数据输入
#define CLK_H			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_SET)//串行通信时钟输入
#define CS_H			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_SET)//片选
#define SDI_L			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET)
#define RST_L			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET)//>400ns
#define DAISY_L		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_RESET)
#define CLK_L			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_RESET)
#define CS_L			HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_RESET)
#define READ_SDO	HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)

void ADS8688_IO_Init(void);	   //ADS8688 IO口初始化
void ADS8688_Init(uint8_t ch_en);	   //ADS8688初始化

uint8_t ADS8688_SPI_Read8Bit(void);//读8个bit数据
void ADS8688_SPI_Write8Bit(uint8_t com);//写8个bit数据

void ADS8688_WriteCmd(uint16_t cmd);//写ADS8688命令寄存器

void SOFT_RESET(void);//软件复位
void AUTO_RST_Mode(void);//自动扫描模式
void MAN_CH_Mode(uint16_t ch);//手动单次扫描模式通道选择

uint8_t ADS8688_ReadReg(uint8_t addr);//读指定的寄存器
void ADS8688_WriteReg(uint8_t addr,uint8_t data);//写指定的寄存器

void Set_Auto_Scan_Sequence(uint8_t seq);//设置自动扫描序列通道
void Set_CH_Range(uint8_t ch,uint8_t range);//设置指定通道测量范围

u16 Get_MAN_CH_Mode_Data(void);//读取手动模式AD值

void Get_AUTO_RST_Mode_Data(uint16_t* outputdata, uint8_t chnum);//读取自动扫描模式AD值



#endif

该驱动所包含头文件sys.h中,只需要delay相关函数。

驱动拿来不能直接用(在引脚和我不一样的情况下),初始化引脚可以根据自己具体接的线来修改驱动文件。

具体要修改的地方在void ADS8688_IO_Init(void)和void ADS8688_Init(uint8_t ch_en);

使用方法

ADS8688分两种模式,手动扫描和自动扫描。

说明:

        自动扫描模式下,该模块一次性扫描八个通道,所以用户需要定义一个类型为uint16_t的数组,含八个数。如果用户只定义了一个数,那么在自动扫描的模式下,该数会按照从AIN0~AIN7采集到的数值来变化。

        手动扫描模式(只能这样翻译了)。在该模式下,根据你所选用的通道来调用函数,函数返回值只读取该通道采样值。如果你没有用满八个通道,那么该模式更加节省资源,采样速率更快。

自动扫描模式
delay_init(168);我用的F4,主频最高位168MHz。
ADS8688_Init(CH7_EN);
Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);
AUTO_RST_Mode();

while(1)
{
    Get_AUTO_RST_Mode_Data(value_8688,8);
    Us=(value_8688[6]-32767)*CONST_N2_5V_LSB_mV;
}

直接调用即可。

说明:初始化函数参数可以写成形如(...CH7_EN|CH8_EN)形式,初始化你选用的通道。

Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);设置量程

Get_AUTO_RST_Mode_Data(value_8688,8);该函数要循环调用,更新采样值。

手动模式
delay_init(168);
ADS8688_Init(CH0_EN);//ADS8688初始化
Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);


while(1)
{
    MAN_CH_Mode(MAN_CH_0);//选择通道
    value[0]=Get_MAN_CH_Mode_Data();//读取通道数据,
}

同理,具体参数看头文件说明。

总结

到此模块可以正常使用;

ADS8688是一个很好用的模块,电赛神器;但是在实际使用的过程中经常会碰到令程序跑飞的情况,没想明白。

  • 8
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
这段代码定义了一系列的宏和一个函数 `ADS8688_SPI_WB`,用于通过 SPI 总线向 ADS8688 设备写入数据。 让我们逐一解释这些宏和函数的作用: 1. 宏 `DAISY_IN_H` 和 `DAISY_IN_L`:用于将 GPIO 引脚 PD9 设置为高电平和低电平,控制 DAISY_IN 引脚的状态。 2. 宏 `SCLK_H` 和 `SCLK_L`:用于将 GPIO 引脚 PD10 设置为高电平和低电平,控制 SCLK 引脚的状态。 3. 宏 `nCS_H` 和 `nCS_L`:用于将 GPIO 引脚 PD11 设置为高电平和低电平,控制 nCS (片选信号)引脚的状态。 4. 宏 `RST_PD_H` 和 `RST_PD_L`:用于将 GPIO 引脚 PD13 设置为高电平和低电平,控制 RST_PD 引脚的状态。 5. 宏 `SDI_H` 和 `SDI_L`:用于将 GPIO 引脚 PD15 设置为高电平和低电平,控制 SDI 引脚的状态。 6. 宏 `SDO`:用于读取 GPIO 引脚 PD8 的输入状态,获取 SDO 引脚的值。 7. 函数 `ADS8688_SPI_WB(uint8_t com)`:这个函数用于通过 SPI 总线向 ADS8688 设备写入数据。它接受一个 `uint8_t` 类型的参数 `com`,表示要发送的命令。 - 首先,它将命令 `com` 复制到临时变量 `com_temp` 中。 - 然后,将片选信号引脚 `nCS_L` 置低,选择 ADS8688 设备。 - 接下来,通过循环依次发送命令的每一位: - 如果 `com_temp` 的最高位为 1,则将 SDI 引脚置高。 - 否则,将 SDI 引脚置低。 - 将 SCLK 引脚置高,表示数据有效。 - 将 `com_temp` 左移一位,准备发送下一位。 - 将 SCLK 引脚置低,表示数据传输完成。 - 最后,函数结束前将片选信号引脚 `nCS_H` 置高,取消选择 ADS8688 设备。 综合起来,这段代码定义了一些控制引脚状态的宏和一个通过 SPI 总线向 ADS8688 设备写入数据的函数。这些宏和函数的具体用途和功能需要结合 ADS8688 设备的规格和应用来理解。如果还有其他问题,请随时提问。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值