外设驱动库开发笔记6:AD719x系列ADC驱动

2023-10-26

前面我们讨论了AD7705这种ADC器件的驱动开发,在实际中我们使用更多的是AD719x系列的ADC芯片、包括有AD7191AD7192AD7193等。接下来我们就来设计并开发AD719x的驱动程序。

1、功能概述

AD7192是一款适合高精密测量应用的低噪声完整模拟前端,内置一个低噪声、 24 Σ-Δ型模数转换器 (ADC)。片内低噪声增益级意味着可直接输入小信号。

1.1、硬件结构

AD7192可配置为两路差分输入或四路伪差分输入。片内通道序列器可以使能多个通道,AD7192 按顺序在各使能通道上执行转换,这可以简化与器件的通信。 片内 4.92 MHz时钟可以用作 ADC 的时钟源; 或者也可以使用外部时钟或晶振。 该器件的输出数据速率可在 4.7 Hz 4.8 kHz 的范围内变化。

AD7192提供两种数字滤波器选项。 滤波器的选择会影响以编程输出数据速率工作时的均方根噪声和无噪声分辨率、建立时间以及 50 Hz/60 Hz 抑制。 针对要求所有转换均需建立的应用, AD7192 具有零延迟特性。

其功能结构图如下:

1.2、内部寄存器

AD7192内部具有多个寄存器,对AD7192的操作就是通过这些片内寄存器进行控制和数据寄存器/数据寄存器加状态信息配置。这些寄存器包括:通信寄存器、状态寄存器、模式寄存器、配置寄存器、ID寄存器、GPOCON寄存器、失调寄存器以及满量程寄存器。其中通信寄存器和状态寄存器共享地址,读操作时针对的是状态寄存器,写操作时针对的是通讯寄存器。对任何寄存器的操作都是从写通讯寄存器开始。

1.2.1、通信寄存器

通信寄存器是一个 8 位只写寄存器。与该器件的所有通信均必须以对通信寄存器的写操作开始。写入通信寄存器的数据决定下一个操作是读操作还是写操作,以及此操作发生在哪一个寄存器。通讯寄存器的格式如下:

其中RS2RS1RS0这些位用于指示下一次操作的寄存器是哪一个寄存器,具体如下:

我们使用比较多的就是状态寄存器、模式寄存器、配置寄存器以及数据寄存器。后续会进一步了解这些寄存器。

1.2.2、状态寄存器

状态寄存器是一个8位只读寄存器。要访问ADC状态寄存器,用户必须写入通信寄存器,选择下一个操作为读操作,并将 0 载入位RS2、位RS1 和位RS0。状态寄存器的格式如下:

CHD0CHD1CHD2这些位指示哪一通道对应数据寄存器的内容。这些位不是指示目前正在转换哪一通道,而是指示产生数据寄存器所含转换结果时选定了哪一通道。

1.2.3、模式寄存器

模式寄存器是一个24位寄存器,可以从中读取数据,也可以将数据写入其中。此寄存器用来选择工作模式、输出数据速率和时钟源。模式寄存器的格式如下:

AD7192的工作模式有模式寄存器的MD2MD1MD0这几位来决定。具体的配置如下:

我们配置什么样的工作模式决定了后续的操作。默认情况下为连续模式,应用比较多的有单次模式、校准模式等。

1.2.4、配置寄存器

配置寄存器是一个 24 位寄存器,可以从中读取数据,也可以将数据写入其中。此寄存器用来配置 ADC 的单极性或双极性模式,使能或禁用缓冲器,使能或禁用激励电流,选择增益,以及选择模拟输入通道。

其中G2G1G0等位用于配置通道的增益。可以实现1倍、8倍、16倍、32倍、64倍、128倍等增益,输入的范围也对应调整,具体如下:

CH7CH6CH5CH4CH3CH2CH1CH0用于设置使用的通道。每一位对应一个通道,具体配置方式如下:

其中CH0CH4CH5不可同时使用,CH1CH6CH7不能同时使用。CH0CH1是差分输入,CH4CH5CH6CH7是单端输入。

余下的ID寄存器、GPOCON寄存器、失调寄存器以及满量程寄存器比较容易理解不再说明。

2、驱动设计与实现

我们已经了解AD7192的基本情况,接下来我们将据此来开发AD7192的驱动程序。

2.1、对象设计

我们的驱动程序依然设计为基于对象的操作。所以首先我们需要先设计对象。而关于对象的设计过程包括两方面内容:对象类型的定义;对象的初始化。

2.1.1、抽象对象类型

对于一个AD7192对象,我们首先考虑到它有8个寄存器,这些寄存器决定了它的操作特性,所以我们记录这些寄存器的值用以标识它的状态。此外增益与极性虽然存在于配置寄存器中,但我们希望在初始化的时候明确的指定它,所以我们也将其作为属性以标识AD7192对象的配置状态。

而对于片选信号的控制、转换就绪信号的读取,总线数据的输入输出这些依赖于硬件电路的操作,我们都将其作为对象的操作来实现。此外,延时操作在不同的硬件平台、有无操作系统的情况下,实现方式大相径庭,因此我们也将其作为对象的操作以便灵活处理。

据此我们可以抽象得AD7192对象类型为:

/*定义用于操作的结构体*/
typedef struct Ad7192Object {
  uint32_t polar;                            //通道的极性
  uint32_t gain;                     //通道增益
  uint32_t Registers[8];         //存放寄存器值的数组
  void (*ReadWrite)(uint8_t *wData,uint8_t *rData,uint16_t size);            //实现读写操作
  void (*ChipSelect)(AD7192CSType cs);                     //实现片选
  uint16_t (*GetReadyInput)(void);                                      //实现Ready状态监视
  void (*Delay)(volatile uint32_t nTime);               //实现ms延时操作
}Ad7192ObjectType;

2.1.2、初始化函数

在使用AD7192前先对其实行初始化,所以我们需要一个对象初始化函数。初始化函数主要包括三个方面的内容:检查对象即各种初始输入是否有效;为对象的属性赋初值以及为操作指定函数指针;对AD7192做前期配置。

关于AD7192的前期配置,首先是软件复位,连续写入401就可对AD7192实现复位。复位完成后,对零点和量程进行校准。而后获取各寄存器的当前状态。初始化函数的具体实现代码如下:

/*AD7192初始化配置*/
AD7192ErrorType AD7192Initialization(Ad7192ObjectType *adObj,
                                      uint32_t Channels,
                                      AD7192PolarType polar,
                                      AD7192GainType gain,
                                      AD7192ReadWriteType readWrite,
                                      AD7192ChipSelectType cs,
                                      AD7192GetReadyInputType ready,
                                      AD7192DelaymsType delayms)
{
       uint32_t polarity[]={UB_UNI,UB_BI};
       uint32_t gains[]={GAIN_1,GAIN_8,GAIN_16,GAIN_32,GAIN_64,GAIN_128};
      
       if((adObj==NULL)||(readWrite==NULL)||(ready==NULL)||(delayms==NULL))
       {
              return AD7192_InitError;
       }
      
       if(cs==NULL)
       {
              adObj->ChipSelect=AD719xChipSelect;
       }
       else
       {
              adObj->ChipSelect=cs;
       }
      
       adObj->polar=polarity[polar];
       adObj->gain=gains[gain];
      
       adObj->Registers[REG_COM_STA]=0x00;
       adObj->Registers[REG_MODE]=0x00;
       adObj->Registers[REG_CONF]=0x00;
       adObj->Registers[REG_DATA]=0x00;
       adObj->Registers[REG_ID]=0x00;
       adObj->Registers[REG_GPOCON]=0x00;
       adObj->Registers[REG_OFFSET]=0x00;
       adObj->Registers[REG_FS]=0x00;
      
       adObj->ReadWrite=readWrite;
       adObj->GetReadyInput=ready;
       adObj->Delay=delayms;
      
       AD7192SoftwareReset(adObj);
       adObj->Delay(1);
       AD7192InternalZeroScaleCalibration(adObj,Channels);
       adObj->Delay(1);
       AD7192InternalFullScaleCalibration(adObj,Channels);

       /*读取并存储全部寄存器的值*/
       ReadAD7192Register(adObj,REG_COM_STA, 8, REG_COM_STA);

       return AD7192_OK;
}

2.2、对象操作

对象初始化后就可对其进行操作。我们无论对AD7192进行何种操作,其目的都是为了得到我们想要的数据。而从AD7192读取转换的结果有2种方式:单次获取和连续获取。接下来我们就按此来说明AD7192的驱动设计。

2.2.1、实现单次数据转换

单次转换模式下,AD7192 在完成转换后处于关断模式。 将模式寄存器中的MD2MD1MD0分别设置为001,便可启动单次转换,此时AD7192将上电,执行单次转换,然后返回关断模式。时序图如下所示:

单次转换数据获取具体实现代码如下:

/*单次转换数据获取*/
uint32_t GetSingleConvertionValue(Ad7192ObjectType *adObj,uint32_t Channels)
{
  uint32_t dataCode=0;
  AD7192StartSingleConvertion(adObj,Channels);
 
  adObj->Delay(1);
 
  dataCode = AD7192ReadConvertingData(adObj);
  dataCode =dataCode & 0x00FFFFFF;

  ReadAD7192Register(adObj,REG_DATA, 1,REG_DATA);
 
  return dataCode;
}

2.2.2、实现连续数据转换

连续转换模式是上电后的默认转换模式。AD7192连续转换,每次完成转换后,状态寄存器中的RDY位变为低电平。如果CS为低电平,则完成一次转换时,DOUT/RDY 线路也会变为低电平。若要读取转换结果,用户需要写入通信寄存器,指示下一操作为读取数据寄存器。从数据寄存器中读取数据字后,DOUT/RDY变为高电平。时序图如下所示:

连续转换数据获取具体实现代码如下:

/*连续转换数据获取,dataCodes为8个元素的数组对应8个通道*/
void GettContinuousConvertionValue(Ad7192ObjectType *adObj,uint32_t Channels,uint32_t *dataCodes,int number)
{
  uint32_t dataCode=0;
  uint8_t status=255;
  AD7192StartContinuousConvertion(adObj,Channels);
 
  for(int i=0;i<number;i++)
  {
    dataCode = AD7192ReadConvertingData(adObj);
    status=((uint8_t)dataCode)&0x07;
    dataCode =(dataCode>>8) & 0x00FFFFFF;
    dataCodes[status]=dataCode;
  }
}

2.2.3、零点和量程校准

零点和量程校准包括内部校准和外部校准,我们这里使用内部校准。

/*内部零点校准*/
static void AD7192InternalZeroScaleCalibration(Ad7192ObjectType *adObj,uint32_t Channels)
{
  //配置寄存器:斩波禁用,基准电压1,AI1-AI4单通道4路,禁用激励电流,禁用基准电压检测,禁用缓冲器
  adObj->Registers[REG_CONF] = 0;
  adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|adObj->polar|adObj->gain;
  WriteAD7192Register(adObj,REG_CONF,1);

  //模式寄存器:内部零点校准,禁用状态同传,内部时钟输出,斩波4,使能奇偶校验,不分频,仅用单周期转换使能,禁用60Hz陷波,FS=128
  adObj->Registers[REG_MODE] = 0;
  adObj->Registers[REG_MODE] = MODE_INZCL|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
  WriteAD7192Register(adObj,REG_MODE, 1);

  adObj->ChipSelect(AD7192CS_Enable);
  while(adObj->GetReadyInput()== 1){;}               //等待RDY为0;
  adObj->ChipSelect(AD7192CS_Disable);
}

/*内部量程校准*/
static void AD7192InternalFullScaleCalibration(Ad7192ObjectType *adObj,uint32_t Channels)
{
  //配置寄存器:斩波禁用,基准电压1,AI1-AI4单通道4路,禁用激励电流,禁用基准电压检测,禁用缓冲器
  adObj->Registers[REG_CONF] = 0;
  adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|adObj->polar|adObj->gain;
  WriteAD7192Register(adObj,REG_CONF, 1);
 
  //模式寄存器:内部量程校准,禁用状态同传,内部时钟输出,斩波4,使能奇偶校验,不分频,禁用单周期转换使能,禁用60Hz陷波,FS=128
  adObj->Registers[REG_MODE] = 0;
  adObj->Registers[REG_MODE] = MODE_INFCL|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_2|SINGLECYCLE_DIS|REJ60_DIS|0x080;             
  WriteAD7192Register(adObj,REG_MODE, 1);

  adObj->ChipSelect(AD7192CS_Enable);
  while(adObj->GetReadyInput()== 1){;}               //等待RDY为0;
  adObj->ChipSelect(AD7192CS_Disable);
}

2.2.4、实现内部温度转换

AD7192内置一个温度传感器。利用配置寄存器中的CH2位可以选择温度传感器。如果CH2位设置为1,就会使能温度传感器。使用温度传感器并选择双极性模式时,如果温度为0K,器件应返回0x800000码。为使传感器发挥最佳性能,需要执行单点校准。因此,应记录25°C 时的转换结果并计算灵敏度。 灵敏度约为2815 /°C。温度传感器的计算公式为

温度 (K) = ( 转换结果 – 0x800000)/2815 K

温度 (°C) = 温度 (K) – 273

单点校准之后,内部温度传感器的精度典型值为 ±2°C。具体的实现代码如下:

/*读取内部温度数据,返回摄氏度温度*/
float GetTemperatureValue(Ad7192ObjectType *adObj)
{
  uint32_t temperatureCode=0;
  float temp = 0.0;
  //模式寄存器:单次转换模式,禁用状态同传,内部时钟输出,斩波4,使能奇偶校验,不分频,禁用单周期转换使能,禁用60Hz陷波,FS=128
  adObj->Registers[REG_MODE] = 0;
  adObj->Registers[REG_MODE] = MODE_SING|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
  WriteAD7192Register(adObj,REG_MODE, 1);
  //配置寄存器:斩波禁用,基准电压1,内部温度,禁用激励电流,禁用基准电压检测,禁用缓冲器
  adObj->Registers[REG_CONF] = 0; 
  adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|TEMP|BURN_DIS|REFDET_DIS|BUF_DIS|UB_BI|GAIN_1;
  WriteAD7192Register(adObj,REG_CONF, 1);

  temperatureCode = AD7192ReadConvertingData(adObj);
  temp = (temperatureCode-0x800000)/2815.0-273;
  return temp;
}

3、驱动的使用

我们已经设计并实现了AD7192模数转换器的驱动。现在我们将考虑如何使用这一驱动实现基于AD7192模数转换器的简单应用。

3.1、声明并初始化对象

使用基于对象的操作我们需要先得到这个对象,所以我们先要使用前面定义的AD7192模数转换器对象类型声明一个AD7192模数转换器对象变量,具体操作格式如下:

Ad7192ObjectType ad7192;

声明了这个对象变量并不能立即使用,我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下:

Ad7192ObjectType *adObj,所要初始化的对象变量

uint32_t Channels,需要初始化的通道

AD7192PolarType polar,通道初始化的极性

AD7192GainType gain,通道的增益

AD7192ReadWriteType readWrite,读写操作函数

AD7192ChipSelectType cs,片选信号操作函数

AD7192GetReadyInputType ready,就绪信号检测函数

AD7192DelaymsType delayms,毫秒延时函数

对于这些参数,对象变量我们已经定义了。所需要初始化的通道、通道的信号极性、采用的增益倍数根据实际情况选择,通道为宏定义、极性和增益为枚举。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:

/*定义读写操作函数指针类型*/
typedef void (*AD7192ReadWriteType)(uint8_t *wData,uint8_t *rData,uint16_t size);

/*实现片选*/
typedef void (*AD7192ChipSelectType)(AD7192CSType cs);

/*实现Ready状态监视*/
typedef uint16_t (*AD7192GetReadyInputType)(void);

/*实现ms延时操作*/
typedef void (*AD7192DelaymsType)(volatile uint32_t nTime);

对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。片选操作函数用于多设备需要软件操作时,如采用硬件片选可以传入NULL即可。具体函数定义如下:

/*定义读写操作函数指针类型*/
void AD7192ReadWrite(uint8_t *wData,uint8_t *rData,uint16_t size)
{
       HAL_SPI_TransmitReceive(&ad77192hspi,wData,rData,size,1000);
}

/*实现片选*/
void AD7192ChipSelect(AD7192CSType cs)
{
       if(AD7192CS_Enable==cs)
       {
              HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);
       }
       else
       {
              HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);
       }
}

/*实现Ready状态监视*/
uint16_t AD7192GetReadyInput(void)
{
       return HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_0);
}

对于延时函数我们可以采用各种方法实现。我们采用的STM32平台和HAL库则可以直接使用HAL_Delay()函数。于是我们可以调用初始化函数如下:

AD7192Initialization(&ad7192AIN1_AIN2|AIN3_AIN4AD7192_UnipolarAD7192Gain1AD7192ReadWriteAD7192ChipSelectAD7192GetReadyInputHAL_Delay);

3.2、基于对象进行操作

我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。在驱动中我们已经封装了单次或是连续获取某一通道模数转换数据的函数。接下来我们就采用我们封装的AD7192数模转换其的驱动获取通道的数据。

/* 单次获取两个差分通道的值 */
void GetDifferentialData(void)
{
       uint16_t dataCode[2];
      
       dataCode[0]=GetSingleConvertionValue(&ad7192,AIN1_AIN2);

       dataCode[1]=GetSingleConvertionValue(&ad7192,AIN3_AIN4);
}

因为初始化函数初始化为两个差分通道,所以我们的函数就是获取了两个差分通道的转换值。获取了ADC的数据后就可以根据每个通道所对应的物理量量程范围计算得到物理量值。

4、应用总结

在这一篇中我们设计并实现了AD7192数模转换器的驱动程序。并使用这一驱动程序实现了单次获取两个差分通道转换数据的简单应用。得到了我们想要的结果,这说明我们的驱动设计是正确的。

在使用驱动时需要注意。选择通道时,由于可以是2个差分通道和4个单端通道,所以差分通道一不可以与AIN1AIN2同时使用,同样的差分通道二不能与AIN3AIN4同时使用。

在使用驱动时需注意,采用SPI接口的器件需要考虑片选操作的问题。如果片选信号是通过硬件电路来实现的,我们在初始化时给其传递NULL值。如果是软件操作片选则传递我们编写的片选操作函数。

完整的源代码可在GitHub下载:https://github.com/foxclever/ExPeriphDriver

欢迎关注:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

外设驱动库开发笔记6:AD719x系列ADC驱动 的相关文章

  • SPI通信方式总结

    SPI xff08 Serial Peripheral interface xff09 是一种同步串行传输规范 xff0c 也是单片机外设芯片串行外设扩展接口 xff0c 该接口是一种高速 xff0c 全双工 xff0c 同步的通信总线 x
  • 一文搞懂——软件模拟SPI

    关于stm32通信协议 xff1a 软件模拟SPI 软件模拟I2C的总结 xff08 fishing 8 xff09 To be a fisher的博客 CSDN博客 stm32 软件spi 发现一篇写的软件模拟SPI的比较容易理解的博客
  • stm32 操作W25Q256 W25Q16 spi flash

    硬件连接 本函数库来自正点原子官方 xff0c 本人稍作修改和添加注释 W25Q16 2M Byte W25Q256 32M Byte spi 配置 2022 7 27 经过测试 华邦的 W25Q256JV 32M 字节 容量的spi fl
  • SPI 通讯协议

    Cuitbasics 汽车ECU设计 2 2 当您将微控制器连接到传感器 xff0c 显示器或其他模块时 xff0c 您是否考虑过这两种设备是如何相互通信的 xff1f 他们到底在说什么 xff1f 事实上电子设备之间的通信就像人类之间的交
  • pixhawk px4 spi设备驱动

    此篇blog是以nuttx官网介绍为出发点 xff0c 先分析如何初始化的 xff0c 再分析如何读取传感器数据的 xff0c 最后对比了字符型设备操作和spi驱动的实现方式的差别 如有错误还请指正 6 字符型设备 所有的结构体和API都在
  • Orin + SC16IS752+SP3072 SPI转串口485

    文章目录 1 前言 2 修改过程 2 1 sc16is752 芯片 2 1 1引脚说明 2 1 2 设备树配置 2 2 1 源码分析 3 调试 1 前言 Orin 有四路串口 对于多数设备来说已经够用 通过SPI 转串口再转RS485在Or
  • STM32F4 SPI RX/TX DMA 读写FLASH数据

    STM32 使用DMA读写FLASH数据需要注意以下几点 xff1a 1 SPI全双工模式下 xff0c 无论读写FLASH数据均需要同时使能RX TX DMA 2 写数据时回读数据应当丢弃 xff0c 读数据时应当发送0xff来启动SPI
  • UART、RS232、RS485、I2C和SPI的介绍

    基本知识 串行通信 xff1a 多个数据通过一条数据线 xff0c 依次传输并行通信 xff1a 多个数据通过多条数据线 xff0c 一次性传输单工通信 xff1a 只能接收数据或者发送数据 xff08 遥控器 收音机 xff09 半双工通
  • rk3399下spi驱动

    SPI 使用 Note xff1a 本文从firefly wiki截取 SPI是一种高速的 xff0c 全双工 xff0c 同步串行通信接口 xff0c 用于连接微控制器 传感器 存储设备等 Firefly RK3399 开发板提供了 SP
  • UART,SPI,IIC,RS232通信时序和规则

    一 UART 1 串口通信方式 2 串口通信步骤 注意 xff1a 串口协议规定 xff0c 闲置时必须是高电平 校验位 xff1a 是使用奇偶校验 停止位必须高电平 一个0和多个0区分是靠掐时间 异步通信 xff1a 时钟各不一样 二 I
  • 【STM32】HAL库-SPI

    3线全双工同步传输 带或不带第三根双向数据线的双线单工同步传输 8或16位传输帧格式选择 主或从操作 支持多主模式 8个主模式波特率预分频系数 最大为fPCLK 2 从模式频率 最大为fPCLK 2 主模式和从模式的快速通信 主模式和从模式
  • RT-Thread记录(十六、SFUD组件 — SPI Flash的读写)

    从本文开始 测试学习一些 RT Thread 常用的组件与软件包 先从刚学完的 SPI 设备开始 目录 前言 一 SFUD 组件简介 1 1 基本简介 1 2 SFUD 对 Flash 的管理 二 SFUD 组件操作函数 2 1 初始化相关
  • 使用Linux内核里的spi屏驱动-fbtft

    Linux内核里已经提供spi接口小屏的设备驱动 在内核的配置选项 make menuconfig ARCH arm CROSS COMPILE arm linux gnueabihf Device Drivers gt Graphics
  • 各种通信接口的简单对比

    对比表 同步方式与异步方式的主要区别在于 是否传输时钟信号 只要是通訊前雙方需要設定相同波特率的 都是異步傳輸方式 异步传输 Asynchronous Transmission 每次异步传输的信息都以一个起始位开头 它通知接收方数据已经到达
  • 【RTT驱动框架分析07】- adc驱动框架分析+adc中断唤醒adc驱动

    ADC adc应用开发 访问 ADC 设备 应用程序通过 RT Thread 提供的 ADC 设备管理接口来访问 ADC 硬件 相关接口如下所示 函数 描述 rt device find 根据 ADC 设备名称查找设备获取设备句柄 rt a
  • Java SPI机制

    一 SPI机制简介 SPI的全名为Service Provider Interface java spi机制的思想 系统里抽象的各个模块 往往有很多不同的实现方案 在面向的对象的设计里 一般推荐模块之间基于接口编程 模块之间不对实现类进行硬
  • CH347读写SPI Flash

    前面耽搁了几天 今天终于把CH347 SPI接口调试好了 CH347动态库中SPI接口函数如下 typedef struct SPI CONFIG UCHAR iMode 0 3 SPI Mode0 1 2 3 UCHAR iClock 0
  • SD卡系列之---SD初始化(SPI)

    SD卡分为SDIO模式与SPI模式 SDIO模式使用SD总线协议 使用4根数据线进行数据传输 SPI使用1收1发2根数据线数据传输 理论上SDIO模式会比SPI模式速度快4倍 但SDIO模式还牵扯到CRC校验位的计算 所以 如果使用CPU有
  • 在 ARM 处理器上执行存储在外部 SPI 闪存中的程序

    我有一个 ARM 处理器 能够与外部闪存芯片连接 写入芯片的是为 ARM 架构编译的程序 可供执行 我需要知道如何将这些数据从外部闪存获取到 ARM 处理器上以供执行 我可以提前运行某种复制例程 将数据复制到可执行内存空间吗 我想我可以 但
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐