mangbudie 发表于 2014-7-23 13:28:05

TDC-GP21时间芯片应用(外部脉冲时间测量)

本帖最后由 mangbudie 于 2014-7-23 13:32 编辑

前年的时候,懵懵懂懂的,不知阿莫是干嘛的,没舍得入坛。
去年的的时候,只需要30元就能拿到邀请码,没舍得入坛。
再想入的时候,已经涨到60大洋了。肉不割,不行啊。
--------------------------------------------------------------------------------------------------------------
前一段时间,由于公司项目需求,提出了更高的时间测量精度要求。急切的需要一种方案对公司的声波仪器改型升级。于是便接触到了TDC-GP21这款产于德国的高精度时间数字转换芯片。

一、首先,说一下这块芯片特性。
芯片技术背景:为了替代机械式热量计。cacm公司开发了这款芯片,提供了单芯片超声波热量表解决方案。


mangbudie 发表于 2014-7-23 13:36:06

芯片的控制方式为4线制spi接口。先贴一下模拟spi接口程序吧。
void sendzero(void)//·¢ËÍ0
{
SCK=1;
DelayNS(1);
SI=0;
DelayNS(1);
SCK=0;
DelayNS(1);
return;
}
void sendone(void) //·¢ËÍ1
{
SCK=1;
DelayNS(1);
SI=1;
DelayNS(1);
SCK=0;
DelayNS(1);
return;
}
/////////////////////////////////////////////////////////////
/*.............SPIͨÐÅÅäÖÃgp22_opcode_data24write..................................*/
void gp21_opcode8_data32write(unsigned char opcode_address,unsigned long data_buf_32bit)
{
           unsigned char cnt;       
        data_buf_32bit=data_buf_32bit;
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=8;cnt>0;cnt--)                             //·¢ËÍopcode_address²Ù×÷Ö¸Áî
        {   
             if((opcode_address&0x80)==0)
             sendzero(); //·¢ËÍ
             else
             sendone();//·¢ËÍ1               
             opcode_address=(opcode_address<<1);   
        }
        for(cnt=32;cnt>0;cnt--)
        {
          if((data_buf_32bit&0x80000000)>0)   
      {
      sendone();
      }
      else
      {
          sendzero();       
          }
          data_buf_32bit=(data_buf_32bit<<1);
   }
        DelayNS(1);
        DelayNS(1);
        SSN=1;
}
/////////////////////////////////////////////////////////////
/*.............SPIͨÐÅÅäÖÃgp22_opcode_data24write..................................*/
void gp21_opcode8_data24write(unsigned char opcode_address,unsigned long data_buf_32bit)
{
           unsigned char cnt;       
        data_buf_32bit=(((long)opcode_address<<24)|data_buf_32bit);
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=32;cnt>0;cnt--)
        {
          if((data_buf_32bit&0x80000000)>0)   
      {
      sendone();
      }
      else
      {
          sendzero();       
          }
          data_buf_32bit=(data_buf_32bit<<1);
   }
        DelayNS(1);
        DelayNS(1);
        SSN=1;
}
/////////////////////////////////////////////////////////////
/*.............SPIͨÐÅÅäÖÃgp22_opcode_data8read..................................*/
unsigned char gp21_opcode8_data8read(unsigned char opcode_address)
{
           unsigned char cnt;          
        unsigned char dataread=0x00;
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=8;cnt>0;cnt--)                             //·¢ËÍopcode_address²Ù×÷Ö¸Áî
        {   
             if((opcode_address&0x80)==0)
             sendzero(); //·¢ËÍ
             else
             sendone();//·¢ËÍ1               
             opcode_address=(opcode_address<<1);   
        }
        for(cnt=8;cnt>0;cnt--)                             //¶ÁÈ¡²Ù×÷Ö¸Áî¶ÔÓ¦µÄ·µ»ØÊý¾Ý
    {   
          SCK=1;   
          DelayNS(1);
                dataread=dataread<<1;
                SCK=0;   
          DelayNS(1);
          if(SO==1)   
          {
                dataread|=0X01;   
                }
                else
                {
                dataread&=~0X01;   
                }   
    }
        DelayNS(1);
        DelayNS(1);
    SSN=1;
    return dataread;
}
/////////////////////////////////////////////////////////////
/*.............SPIͨÐÅÅäÖÃgp21_opcode_data8read..................................*/
unsigned int gp21_opcode8_data16read(unsigned char opcode_address)
{
           unsigned char cnt;          
        unsigned int dataread=0x00;
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=8;cnt>0;cnt--)                             //·¢ËÍopcode_address²Ù×÷Ö¸Áî
        {   
             if((opcode_address&0x80)==0)
             sendzero(); //·¢ËÍ
             else
             sendone();//·¢ËÍ1               
             opcode_address=(opcode_address<<1);   
        }
        for(cnt=16;cnt>0;cnt--)                             //¶ÁÈ¡²Ù×÷Ö¸Áî¶ÔÓ¦µÄ·µ»ØÊý¾Ý
    {   
          SCK=1;   
          DelayNS(1);
                dataread=dataread<<1;
                SCK=0;   
          DelayNS(1);
          if(SO==1)   
          {
                dataread|=0X0001;   
                }
                else
                {
                dataread&=~0X0001;   
                }   
    }
        DelayNS(1);
        DelayNS(1);
    SSN=1;
    return dataread;
}
/////////////////////////////////////////////////////////////
/*.............SPIͨÐÅÅäÖÃgp22_opcode_data8read..................................*/
/////////////////////////////////////////////////////////////
void gp21_opcode8(unsigned char data_buf_8)
{
        unsigned char cnt,tmp=0x80;
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=8;cnt>0;cnt--)   
        {   
             if((data_buf_8&tmp)==0)      // tmp=tmp>>1; //tmp ÓÒÒÆһλ   
             sendzero(); //·¢ËÍ
             else
             sendone();//·¢ËÍ1               
             data_buf_8=(data_buf_8<<1);
        }   
        DelayNS(1);
        DelayNS(1);
        SSN=1;
        return;   
}
/*.............SPIͨÐÅÅäÖÃgp22_opcode_data8read..................................*/
unsigned long gp21_opcode8_data32read(unsigned char opcode_address)
{
           unsigned char cnt;          
    unsigned long Data_32_tmp=0x00000000;
        SSN=0;
        DelayNS(1);
        DelayNS(1);
        for(cnt=8;cnt>0;cnt--)                             //·¢ËÍopcode_address²Ù×÷Ö¸Áî
        {   
             if((opcode_address&0x80)==0)
             sendzero(); //·¢ËÍ
             else
             sendone();//·¢ËÍ1               
             opcode_address=(opcode_address<<1);   
        }
        for(cnt=32;cnt>0;cnt--)   
        {
              SCK=1;   
              DelayNS(1);
                 DelayNS(1);
                  Data_32_tmp=(Data_32_tmp<<1);
                  SCK=0;   
              DelayNS(1);
                 DelayNS(1);
               if(SO==1)
                  {               
              Data_32_tmp|=0X00000001;
                  }   
                  else
                  {
              Data_32_tmp&=~0X00000001;
                  }
              DelayNS(1);
                 DelayNS(1);
        }   
        DelayNS(1);
        DelayNS(1);
    SSN=1;
    return(Data_32_tmp);
}
/////////////////////////////////////////////////////////////

mangbudie 发表于 2014-7-23 13:40:03

操作这款片子,第一步,就是需要spi测试。芯片的第五个寄存器提供了数据读回功能。具体请查datasheet。
测试程序如下:
                                rxd_pk.command=0x00;               
                                GPIO_init();GP2_RESET(); //初始化引脚//GP2上电复位程序                                
                                gp21_opcode8(0X70); DelayNS(5);                        //初始化 TDC
                                EN_START=1;SendData(testcomunication(rxd_pk.payload));//使能START//通过串口返回spi测试结果


调用函数如下:
void GPIO_init(void)
{
START=0;//上电输出低
STOP=0;

EN_START=0;
EN_STOP1=0;
EN_STOP2=0;
            
SCK=0;
SSN=1;                //空闲为高
}
/////////////////////////////////////////////////////////////
//===========GP2 上电复位程序==================//   
void GP2_RESET(void)   
{   
RSTN=1;   
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
RSTN=0;
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
RSTN=1;   
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
DelayNS(1); DelayNS(1); DelayNS(1); DelayNS(1);
}
/*************************************************/
//功能:时间测量状态寄存器判断程序
//时间:2014.5.29.16
/*************************************************/
unsigned int GP2_TMSTAT()   
{   
unsigned long A;
unsigned char BZ1=0;
A=gp21_opcode8_data16read(0xb4);
//B=A;
//SendData('F') ; SendData('L') ;SendData('A') ;SendData('G') ;        SendData(':') ;
//for(t=0;t++;t<=15)
//{
//C=B&0X01;
//B=B>>1;
//SendData(C+0x30) ;
//}
//
DelayNS(5);
if((A&0x0600)==0)                        //状态寄存器的第九位为1表示TDC溢出,第十位为1表示计数器溢出
BZ1 |=0XFE;                                //没有溢出
else
BZ1 |=0X01;                                //置溢出预计数器或溢出TDC标志
return BZ1;
}
/*************************************************/
//功能:spi通信测试
//时间:2014.5.29.15
/*************************************************/
unsigned char testcomunication(unsigned char buf)   
{
unsigned char tmp=0x80;   
unsigned char test_reg=0xb5; //读结果寄存器5,反映寄存器1 的高8 位   
gp21_opcode8_data24write(0x81,((unsigned long)buf<<16));          
DelayNS(5);
return gp21_opcode8_data8read(test_reg);
}       
/////////////////////////////////////////////////////////////

mangbudie 发表于 2014-7-23 13:40:34

第一次贴自己的源码,贻笑大方了。

scadu 发表于 2014-7-23 14:42:55

mark.GP22都有了.

mangbudie 发表于 2014-7-23 14:52:28

差别不大,也就是offset升级。个别功能升级。那不是重点。

leiyin 发表于 2014-9-2 15:07:07

呵呵,小丁!忙不迭。

mangbudie 发表于 2014-9-9 14:17:38

leiyin 发表于 2014-9-2 15:07
呵呵,小丁!忙不迭。

雷哥,你好!

hemeizhi 发表于 2014-9-9 15:11:10

mark一下

ddddddd 发表于 2014-9-18 09:24:21

这个芯片不错,以前在激光测距上用过

zolo 发表于 2015-2-16 20:19:41

请问各位,在矫正的时候从oxB0读出来粉校准结果应该为多少啊?我怎么为0x00,是不是程序写错了?

LMLUNTAN 发表于 2015-11-2 09:38:14

啥时候在啊,有关TDC-GP21问题请教啊,qq:771849605

加油——蜗牛 发表于 2015-11-28 13:19:30

您好,我正在用TDC-GP2测量时间,出现的问题是TDC-GP2每隔30s才可以测量六个数据,我是在一直给测量的时间脉冲的,我是用测量模式1,外部给start信号,stop2测量的时间减去stop1测量的时间,得出我需要的时间,请教一下问题是出在那

13608330527 发表于 2019-6-30 16:47:23

请教;GP21手册上说32.768K晶振已集成在芯片内部了,也就是说外围可不用这个晶振了,但有些例程在开始都说;'32.768K晶振集成在芯片内部了',但后面给出的外围电路又加有32.768K的晶振,这是咋回事呢?

mangbudie 发表于 2019-7-15 21:47:35

13608330527 发表于 2019-6-30 16:47
请教;GP21手册上说32.768K晶振已集成在芯片内部了,也就是说外围可不用这个晶振了,但有些例程在开始都说;'32 ...

这个片子太久了,也懒得翻手册了。
外部37.768K晶振ppm较高(不容易受环境影响),与外部4M晶振粗细配合,提高测量精度。
我记得是没有集成的。假如集成,也建议使用外部晶振。

wowangru 发表于 2019-8-5 14:02:30

如何触发?   触发信号延迟不低啊
页: [1]
查看完整版本: TDC-GP21时间芯片应用(外部脉冲时间测量)