AD7606与STM32F103ZET6的串行通信

  本文是AD7606与STM32的串行通信的学习心得,可帮助你快速入门AD7606。

时序图的理解

  图一
在这设定片描述
  图二
在这里插入图片描述
  图三
在这里插入图片描述
  图四
在这里插入图片描述
  根据图一,一些引脚在置高或置低时的上升或下降沿会受时间影响,因此在编写代码时,一些对引脚的操作需要放在一起,且延时函数不能随意使用。
  图二是整体的一个时序框图,大体的逻辑就是在使用AD7606之前要先复位一下,复位信号是高电平有效,时间至少为50ns。然后就是对采样速率和量程的配置,也就是对OS0,OS1,OS2和RANGE脚的配置,然后再对一些引脚进行一些初始化(也可以直接在GPIO配置的时候进行初始化)。之后就是发送启动信号,也就是将CVA,CVB同时拉低至少25ns后再拉高(启动信号上升沿有效)。之后AD7606开始转换,BUSY信号线自动拉高,如果BUSY信号线拉低则表明转换已经完成。转换完成后将CS片选信号线拉低才可以进行数据读取,读取完成后将CS片选信号线拉高即可。(还有一种是在转换时进行数据读取的,由于对于采样速率要求并不是特别的高,所以也没有深入研究)
  图三是串行通讯对数据进行读取的时序框图,讲的是在AD7606转换完成后将CS片选信号拉低后的操作。转换完成后CS片选信号拉低,开始读取数据。由于是16位8通道ADC,一次读取一个字节,所以一个通道需要读取两次数据。因为是高位在前低位在后所以就是先读取的是MSB,后读取的LSB,数据需要SCLK下降沿有效。经过16*8 = 128个SCLK读取后已经全部将ADC转换的数据全部读取完了,之后就可以将CS片选信号拉高了(由于串行通讯FRSTDATA数据线可以不接,所以并没有用到这个脚)。
  图四是对一个字节的读取,顺序也就是现将时钟线拉高后拉低然后读取一下当前的值然后拉高,重复八次就是一个字节的读取。(MSB的最高位为符号位,若为1则数据为负数,若为0则数据为正数)

计算公式的理解

在这里插入图片描述
  图上为计算公式,VIN为输入量,REF为ADC所选择的基准电压,一般使用内部基准电压REF=2.5V。上下两公式的选择,是由J2所接量程所决定。
  在程序中的计算公式:
在这里插入图片描述
  DB data[i]为AD所输出的二进制补码,可通过此方式计算出输入电压。

硬件电路连接

  串行工作方式:
在这里插入图片描述
  串行模式工作时,相关引脚连接方式:

rst复位引脚
convstB可以接在一起,当同时置低时 进行模拟量采样并处理
convstA
STby控制工作模式,正常工作时一般直接接高电平
OS12用于选择过采样倍率
OS11
OS10
busy标志位,标志AD正在进行模拟量采样并处理
cs片选信号,置低后标志可以开始输出模拟量
rdCS置低后的每一个上升沿输出每一位模拟量
DoutA(DB7)数据输出线
D15直接接地
SER连接3.3 ,用于设定ADC为串行工作模式
5V
GND
RANGEJ2用于选择输入电压的范围,影响计算公式
PB7数据口,ADC最终通过此口给单片机发送数据

实物连接图

在这里插入图片描述

软件设计

  部分参数的定义

uint8_t read_flag=1;
s16	 DB_data[8]={0};
u8 i;
int32_t line=0;
int32_t reminder[32][32]={0};
uint8_t  temp;

  初始化函数

void AD7606_Init(void)
{
	convstA_Set;//同时拉高
	convstB_Set;
	delay_ms(1);
	STby_Set;//一直置高
	
	
	clk1_Set;//针对CLK和CS的操作尽可能地放在一起
	cs1_Set;	
	clk2_Set;//根据自己的需求连接几个CS和CLK 这里使用了四个ADC
	cs2_Set;
	clk3_Set;
	cs3_Set;
	clk4_Set;
	cs4_Set;
	
	
 	OS10_Reset;//过采样模式的初始化
	OS11_Reset;
	OS12_Reset;
	AD7606_reset();  
	delay_ms(1);
	AD7606_startconvst();	
}

  开始转化函数
  COA 与COB均是上升沿触发,因此需要同时拉低再拉高。

void AD7606_startconvst(void)
{  
	convstA_Reset;	
	convstB_Reset;	
	delay_us (1);
	convstA_Set;
	convstB_Set;
}

  复位函数
  REST是上升沿触发,因此先拉低再拉高再拉低。

void AD7606_reset(void) 
{ 
	rst_Reset;
	delay_us (1);
	rst_Set; 
	delay_us(1);
	rst_Reset; 
}  

  读数据函数,此处定义STM32的CO口与单片机的PB7数据线相连,读取AD转换的数据。

void  AD7606_read_data1(s16 * DB_data) 
{  
	u8 i,j; 	
	for(i=0;i<8;i++)  //循环8次是因为有8个通道
	{
		u16 DB_data1 = 0;//用于存储读出引脚的值
		cs1_Reset; //CS和CLK的引脚控制函数尽量放在一起
	  delay_us(1);	
		for(j=0;j<16;j++)//循环16次是因为寄存器可以存16位
		{		
		clk1_Reset;//CLK拉低开始输出
		delay_us(1);			
		DB_data1 = ((u16)(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0))<< (15-j)) + DB_data1 ;//AD输出为二级制补码,此处涉及部分寄存器的知识
	  	clk1_Set;
		delay_us(1);				
		}		
		cs1_Set;	
		DB_data[i] = (u16)DB_data1;//此处大致意思为将AD通道输出的值赋给一个存储内容为8的数组
	}	
	read_flag++;//多ADC使用时的标志位
} 

  遍历ADC函数
  注:1.此处的函数是使用一块STM32驱动四块AD7606,read_flag的使用是为了使相应的AD7606工作,如果你使用一块AD7606那么你看一个if里的函数就足够了。
  2.函数中包含的部分变量为全局变量,因此没有在函数的局部进行定义。

void throught_all(void)
{
		AD7606_startconvst();						
		temp = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5);	//判断BUSY线的反馈的值来决定对AD的操作
	  while(temp == 0)	
		{
			delay_us(1);
			temp = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5);	
		}
	if(read_flag==1)
		{
			AD7606_read_data1(DB_data); //此函数返回一个数组,此数组的每一位中存放着相应通道采样的值,之后对该数组进行相应操作即可
								for(i=0;i<8;i++)
						{
							delay_us(100);
												line=2*i+1;/
												if(flag==0)
												{
												column=m+1;
												}
												if(flag==1)
												{
												column=m+17;
												}
										
													reminder[line-1][column-1]=(DB_data[i]*10000.0/32768);//计算公式的体现
						}	
			
		}
			if(read_flag==2)//以下为其他3个AD的操作程序
		{
			AD7606_read_data2(DB_data);
			
								for(i=0;i<8;i++)
						{
							delay_us(100);
											
												line=2*i+17;
												if(flag==0)
												{
												column=m+1;
												}
												if(flag==1)
												{
												column=m+17;
												}
										
													reminder[line-1][column-1]=(DB_data[i]*10000.0/32768);
											
						}
				
		}
	
			if(read_flag==3)
		{
			AD7606_read_data3(DB_data); 
			
								for(i=0;i<8;i++)
						{
							delay_us(100);
											
												line=2*i+2;
												if(flag==0)
												{
												column=m+1;
												}
												if(flag==1)
												{
												column=m+17;
												}
												
													reminder[line-1][column-1]=(DB_data[i]*10000.0/32768);
											
						}
							
		}
	
			if(read_flag==4)
		{
			AD7606_read_data4(DB_data); 
			
								for(i=0;i<8;i++)
						{

							delay_us(100);
											
												line=2*i+18;
												
												
												if(flag==0)
												{
												column=m+1;
												}
												if(flag==1)
												{
												column=m+17;
												}
											
												reminder[line-1][column-1]=(DB_data[i]*10000.0/32768);					
						}
								
		}
}
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐