STM32F4探索者,基于SPI实现AD7606信号串行采集

目录

1 基本特性

2.模块

3.接线

3.转换时序

4.读取时序

5.转换期间读取

6.读取的16位二进制与电压值的转换

7.spi读取

8.对采样率有要求时


工程压缩包:https://download.csdn.net/download/binocthrx/88222511?spm=1001.2014.3001.5503

  1. 1 基本特性

模块名称:AD7606 多通道AD 数据采集模块

模块尺寸:50mm * 48mm

模块供电:5V

模块输入电压范围:±5V,±10V(由RANGE 引脚的逻辑电平决定,该引脚与逻辑高

电平连接时,所有通道模拟输入范围为±10V。该引脚与逻辑低

电平连接时,所有通道模拟输入范围为±5V。程序默认±5V)

输入阻抗:1MΩ

内部基准电压源:2.5V(可自行配置外部基准电压)

模拟输入箝位保护:±16.5V

模块采样率:200KSPS(所有8 个通道)

模块分辨率:16 bit

模块接口:SPI 接口或16 位并口(模块默认SPI 串口)

模拟输入滤波器带宽:23KHz(-3dB,±10V 范围)

15KHz(-3dB,±5V 范围)

信噪比:90dB(典型值,无过采样,±10V)

89dB(典型值,无过采样,±5V)

2.模块

3.接线

AD_CS-----PC12

AD_RESET-----PC10

AD_CONVST-----PC13  (板子上的CA/CB)

AD_RANGE------PC8 

AD_OS0-----PC4

AD_OS1-----PC5

AD_OS2-----PC6

AD_BUSY-----PA5(不用可以不接)

SPI接线

具体为

SCK-----PB3       (板子上的RD口)

MISO----PB4  (板子上的D7口)

MOSI没用上不接

 3.转换时序

 

CONVST A和CONVST B连在一起,t5接近于0,此时为串行8路采样,CONVST A和CONVST B平时为高电平,转换时拉低至少50ns。转换时BUSY被拉高,转换结束被拉低,转换时间tconv在无过采样时典型值为4ns。

4.读取时序

串行模式转换之后读取是,待BUSY被拉低后,可以将CS拉低控制SCLK时钟信号进行数据的读取,先读出的为高位。读出一个完整通道需要16位,读出8个通道依次16次读取循环8次即可,对于DA口,读取的顺序为通道1、2、3、4、5、6、7、8,对于DB口读取的顺序为通道5、6、7、8、1、2、3、4,两个端口同步输出。若只需一个通道,那么仅读取一次即可。根据DA\DB读取顺序的不同,我们可以两个端口同时读取,一次读取两个通道值,只需读4次即可读完8个通道值。

转换及读取代码如下

uint16_t ADRED_AD7606(){

	uint16_t data;
		AD_CS_LOW();
		
		data=SPI1_ReadWriteByte(0xff);

		AD_CS_HIGH();
		ad7606_StartConv();
		return data;
}

5.转换期间读取

当BUSY为高电平,转换正在进行时,也可以从AD7606/AD7606-6/AD7606-4读取数据。这几乎不会影响转换器的性能,而且可以实现更快的吞吐速率。转换期间可以执行并行、并行字节或串行读取,可以使用或不用过采样。图3显示并行或串行模式下BUSY为高电平时读取操作的时序图。转换期间执行读取使得使用串行接口且VDRIVE高于4.75V时也可以达到最高吞吐速率。DRIVE在BUSY下降沿时,输出数据寄存器会被新转换数据更新,除外之外的任何时候都可以从AD7606读取数据。对于t6,最后CS上升沿与BUSY下降沿之间的最长时间为25ns。

6.读取的16位二进制与电压值的转换

 

此模块REF为2.5V,范围为10V时,对于正电压,输入电压VIN=CODE*10/32678。

对于负电压,可以看出输出的CODE为补码,负数补码的源码是符号位不变,其余位取反后加一,原码的首位仍为符号位,在此案例中获得其绝对值可以对其全部取反后加一即可,最后将转换的CODE手动加上负号。代码如下:

	sampdata=ADRED_AD7606();
if(sampdata<32768){
  dataVol=((sampdata)*10.0 * 1000 ) / 32768; 
  }
else {
  sampdata = (~sampdata)+1;
	dataVol=((sampdata)*10.0 * -1000 ) / 32768;
  }

转换后的电压值负号为mV。

7.spi读取

使用STM32F4自带的spi通信,参考正点原子的spi通信实验的代码,因为是146位ADC,我们直接配置16位的spi,配置如下:

void SPI1_Init(void)

{    

  GPIO_InitTypeDef  GPIO_InitStructure;

  SPI_InitTypeDef  SPI_InitStructure;

      

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟



  //GPIOFB3,4,5初始化设置

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5复用功能输出

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化

      

       GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3复用为 SPI1

       GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4复用为 SPI1

       GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5复用为 SPI1



       //这里只针对SPI口初始化

       RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1

       RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1



       SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工

       SPI_InitStructure.SPI_Mode = SPI_Mode_Master;          //设置SPI工作模式:设置为主SPI

       SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;            //设置SPI的数据大小:SPI发送接收8位帧结构

       SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;           //串行同步时钟的空闲状态为高电平

       SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样

       SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;           //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制

       SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;          //定义波特率预分频的值:波特率预分频值为64

       SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;       //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始

       SPI_InitStructure.SPI_CRCPolynomial = 7;       //CRC值计算的多项式

       SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器



       SPI_Cmd(SPI1, ENABLE); //使能SPI外设



       SPI1_ReadWriteByte(0xff);//启动传输              

}  

然后利用此函数进行数据通信:

u16 SPI1_ReadWriteByte(u16 TxData)

{                                



  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空 

      

       SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte  数据

             

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte 



       return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据   

                

}

最后这是利用信号发生器发出的1HZ正弦波交流信号采集后利用excel画出的波形

8.对采样率有要求时

利用定时器,可控制采样率,此处利用TME3定时器,设置时长为0.5ms,也就是2K左右的采样率(2K实际值为2048),若设置为1ms那也就是大概1K

TIM3_Int_Init(500-1,84-1);    //定时器时钟84M,分频系数84,所以84M/84=1000Khz的计数频率,计数500次为0.5ms  

 对于定时器初始化代码

void TIM3_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟
	
  TIM_TimeBaseInitStructure.TIM_Period = arr; 	//自动重装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
	TIM_Cmd(TIM3,ENABLE); //使能定时器3
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}

在中断函数中调用转换函数,注意此处不要有过多操作,仅读取即可,否则影响采样率精度,个人的操作方式是,采集够数据量时临时暂停一下定时器,在主函数中对数据操作完成后继续定时采集。

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
//		LED1=!LED1;//DS1翻转
		ad_sampdata[ad_times++]=ADRED_AD7606();
		if(ad_times>=CA_SIZE){
			ad_times=0;
			AD_FULL=1;
			ad7606_StopRecord();
		}
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

  • 10
    点赞
  • 118
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值