TI 模数ADC128S022芯片的应用例程

最近接触了TI的ADC128S022的ADC采样芯片,芯片集成了8个模拟输入通道,支持12位的采样精度,转换过程时钟平率可达1~3.2MHZ,非常高效,因此在手持终端,便携式系统,医疗器械领域,导航等领域里有广泛的应用,3.3v /5V的输入电压均可,与主控制器支持通过SPI的方式实现交互通信;
通过对地址的寄存器的解读可以知道每个通道的地址信息:
ADC128S_Channel_ADRR[8]={0x0000,0x0800,0x1000,0x1800,0x2000,0x2800,0x3000,0x3800};//8个通道对应的地址
在应用的时候只用了前四个通道; 在这里插入图片描述
了解一下工作时序:
在这里插入图片描述
片选CS端,既有使能工作关开关的作用,也可以在置为高电平的时候有低功耗的作用,由时序关系可以看出在片选使能之后,在SCK下降沿下有数据输出,在上升沿的时候读输入数据(主要为地址信息),0通道为默认选项,可以在0通道转换的时候输入后一个周期希望输出的通道地址;
我的做法是采用软件模拟SPI,用mod 3 的方式在实现对芯片的读写功能操作:
首先是对管脚做配置:

  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;                        //MISO
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;                        //sclk  
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;	 
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  GPIO_Init(GPIOB,&GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;	  
	GPIO_Init(GPIOE,&GPIO_InitStructure); 
	ADC128S_CS=1;                                                           //选择模式1的方式进入trace  
	ADC128S_SCLK=1;
	AI_ReceiveBuf.new_buff=AI_ReceiveBuffArr;               //数据操作结构体的成员量定义和赋值
	AI_ReceiveBuf.pre_buff=AI_ReceivePreBuffArr;
	AI_ReceiveBuf.AI_ReceiveFlag=0;
   AI_ReceiveBuff_PTR=&AI_ReceiveBuf;	

我的读取操作是每次轮询四个通道,并做N此的均值处理,提高采样的稳定性能,直接读取的过程:
void YF_ADC128S_ReadADValue(_AI_ReceiveBuff_PTR ptr,u16* read_addre,u8 total_channels)
{
static u8 AI_CycleCount=0;
u16 so_date=0;
u16 si_date=0;
if(AI_CycleCount<ADC128S_CycleSUM)
{
ADC128S_SCLK=1;
ADC128S_CS=1;
delay_us(1);
ADC128S_CS=0;
delay_us(1);
for(int i=0;i<total_channels;i++)
{
si_date=read_addre[i+1]; //下次循环转换通道选择 需要在这次写到寄存器中
// if(i==total_channels-1)si_date=read_addre[0];
for(int j=0;j<16;j++)
{
ADC128S_SCLK=0;
delay_nsx6(5);
if(ADC128S_MISO) //下降沿接收数据接收数据 默认首个字节接收到的数据是channel 0通道
{
so_date|=0x01;
}
if(si_date&0x8000)
{
ADC128S_MOSI=1;
}else
{
ADC128S_MOSI=0;
}
delay_nsx6(2);
ADC128S_SCLK=1;
delay_nsx6(5);
si_date<<=1;
if(j<15)
{
so_date<<=1;
}
}
ai_receivebuffarr[i]+=so_date&0x0fff;
so_date=0;
}
ADC128S_SCLK=1;
ADC128S_CS=1;
delay_us(1);
AI_CycleCount++;
}
if(AI_CycleCount=ADC128S_CycleSUM)
{
for(int k=0;k<4;k++)
{
ptr->new_buff[k]=(u16)(ai_receivebuffarr[k]/ADC128S_CycleSUM);
ai_receivebuffarr[k]=0;
}
ADC128S_VoltageConversion(ptr->new_buff,total_channels); //把数字量转换为输入的模拟电压值
if(Beyond_FristAI=0)
{
ptr->pre_buff[0]=ptr->new_buff[0];
ptr->pre_buff[1]=ptr->new_buff[1];
ptr->pre_buff[2]=ptr->new_buff[2];
ptr->pre_buff[3]=ptr->new_buff[3];
ptr->AI_ReceiveFlag=1;
Beyond_FristAI=1;
}
if(IS_AIReceiveValid(ptr)!=0) //输入是否在所需的精度内
{
ptr->pre_buff[0]=ptr->new_buff[0];
ptr->pre_buff[1]=ptr->new_buff[1];
ptr->pre_buff[2]=ptr->new_buff[2];
ptr->pre_buff[3]=ptr->new_buff[3];
ptr->AI_ReceiveFlag=1;
}
AI_CycleCount=0;
}
}
在调试过程中对芯片的采样精度感觉还满意,基本在±20mv内波动。
由此,基本结束芯片的应用,在应用的时候直接在所在的结构体中查看BUFF中的数据即为实时的转换数据!
以上为自己的调试过程心得,欢迎交流!Q:1436015419

  • 17
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值