您现在的位置是:首页 >其他 >TM7707 评估前做的功课网站首页其他

TM7707 评估前做的功课

mainbanp 2024-07-09 18:01:02
简介TM7707 评估前做的功课

目录

硬件

模拟输入范围

转换速度与有效位数

数字电平匹配

建立时间

基准电压

软件

寄存器


硬件

        MCU 3.3V 平台;

        ADC mclk 2.4576mhz

模拟输入范围

在非缓冲模式下,共模输入范围是从 GND V DD 。模拟输入电压的绝对值处在
GND-30mV V DD +30mV 之间。
在缓冲模式下,模拟输入端能处理更大的电
源阻抗,但绝对输入电压范围被限制在 GND+50 mV V DD +30mV 之间。

转换速度与有效位数

        3.3V

        约13位有效位数@500Hz

        5.0V 

        13位有效位数@500Hz

       

数字电平匹配

        这里主要看MCU3.3V,ADC5V情况的适配情况

        MCLK如果是外部提供一定要注意电平

         3.3V端接受5V端电平,可以接个分压电阻。

         5V端接受3.3V电平,可以直连。

 

建立时间

这里主要讲2个通道切换时,需要建立的时间。

在TM7707的数据手册上我并没有直接找到直接描述建立时间。下面是在ADI的一篇文档中的描写

01 (analog.com)

 简单理解成切换通道需要的建立时间是3个转换周期吧。

基准电压

 

软件

寄存器

这里重点讲下面这个寄存器,在看到这个手册时,我以为TM7707没有时钟分频,外部时钟最大2.

5mhz.FS111~8 也没有介绍真奇怪。

但是在一些帖子上看到别人使用TM7707 这部分的配置按照TM7705可以正常工作,我又找到了AD7707,结合网友的实测,应该可以得出一些结论了。

TM7707

 

AD7707

 

 安富莱的驱动代码(这里需要注意FS_500HZ = 0x04, 是错误的按照数据手册 正确的是FS_500HZ = 0x03

tm7705.h

#ifndef __TM7705_H
#define __TM7705_H

#include "main.h"



#define TM_CS_H HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,1);
#define TM_CS_L HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,0);
#define TM_RST_H HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,1);
#define TM_RST_L HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,0);


void InitTM7705(void);
void TM7705_CalibSelf(uint8_t _ch);
void TM7705_SytemCalibZero(uint8_t _ch);
void TM7705_SytemCalibFull(uint8_t _ch);
uint16_t TM7705_ReadAdc(uint8_t _ch);


#endif



tm7705.c 

#include "tm7705.h"
#include "main.h"

/***********************以下为TM7705的标准库*****************************/
/************************************************************************/



/* 通道1和通道2的增益,输入缓冲,极性 */
#define __CH1_GAIN_BIPOLAR_BUF	(GAIN_1 | UNIPOLAR | BUF_NO)
#define __CH2_GAIN_BIPOLAR_BUF	(GAIN_1 | UNIPOLAR | BUF_NO)

/*
	TM7705模块可以直接插到STM32-V5开发板nRF24L01模块的排母接口上。

    TM7705模块   STM32F407开发板
      SCK   ------  PB3/SPI3_SCK
      DOUT  ------  PB4/SPI3_MISO
      DIN   ------  PB5/SPI3_MOSI
      CS    ------  PF7/NRF24L01_CSN
      DRDY  ------  PH7/NRF24L01_IRQ
      RST   ------  PA4/NRF905_TX_EN/NRF24L01_CE/DAC1_OUT	(复位 RESET)
*/




/* 通信寄存器bit定义 */
enum
{
	/* 寄存器选择  RS2 RS1 RS0  */
	REG_COMM	= 0x00,	/* 通信寄存器 */
	REG_SETUP	= 0x10,	/* 设置寄存器 */
	REG_CLOCK	= 0x20,	/* 时钟寄存器 */
	REG_DATA	= 0x30,	/* 数据寄存器 */
	REG_ZERO_CH1	= 0x60,	/* CH1 偏移寄存器 */
	REG_FULL_CH1	= 0x70,	/* CH1 满量程寄存器 */
	REG_ZERO_CH2	= 0x61,	/* CH2 偏移寄存器 */
	REG_FULL_CH2	= 0x71,	/* CH2 满量程寄存器 */

	/* 读写操作 */
	WRITE 		= 0x00,	/* 写操作 */
	READ 		= 0x08,	/* 读操作 */

	/* 通道 */
	CH_1		= 0,	/* AIN1+  AIN1- */
	CH_2		= 1,	/* AIN2+  AIN2- */
	CH_3		= 2,	/* AIN1-  AIN1- */
	CH_4		= 3		/* AIN1-  AIN2- */
};

/* 设置寄存器bit定义 */
enum
{
	MD_NORMAL		= (0 << 6),	/* 正常模式 */
	MD_CAL_SELF		= (1 << 6),	/* 自校准模式 */
	MD_CAL_ZERO		= (2 << 6),	/* 校准0刻度模式 */
	MD_CAL_FULL		= (3 << 6),	/* 校准满刻度模式 */

	GAIN_1			= (0 << 3),	/* 增益 */
	GAIN_2			= (1 << 3),	/* 增益 */
	GAIN_4			= (2 << 3),	/* 增益 */
	GAIN_8			= (3 << 3),	/* 增益 */
	GAIN_16			= (4 << 3),	/* 增益 */
	GAIN_32			= (5 << 3),	/* 增益 */
	GAIN_64			= (6 << 3),	/* 增益 */
	GAIN_128		= (7 << 3),	/* 增益 */

	/* 无论双极性还是单极性都不改变任何输入信号的状态,它只改变输出数据的代码和转换函数上的校准点 */
	BIPOLAR			= (0 << 2),	/* 双极性输入 */
	UNIPOLAR		= (1 << 2),	/* 单极性输入 */

	BUF_NO			= (0 << 1),	/* 输入无缓冲(内部缓冲器不启用) */
	BUF_EN			= (1 << 1),	/* 输入有缓冲 (启用内部缓冲器) */

	FSYNC_0			= 0,
	FSYNC_1			= 1		/* 不启用 */
};

/* 时钟寄存器bit定义 */
enum
{
	CLKDIS_0	= 0x00,		/* 时钟输出使能 (当外接晶振时,必须使能才能振荡) */
	CLKDIS_1	= 0x10,		/* 时钟禁止 (当外部提供时钟时,设置该位可以禁止MCK_OUT引脚输出时钟以省电 */

	/*
		2.4576MHz(CLKDIV=0 )或为 4.9152MHz (CLKDIV=1 ),CLK 应置 “0”。
		1MHz (CLKDIV=0 )或 2MHz   (CLKDIV=1 ),CLK 该位应置  “1”
	*/
	CLK_4_9152M = 0x08,
	CLK_2_4576M = 0x00,
	CLK_1M 		= 0x04,
	CLK_2M 		= 0x0C,

	FS_50HZ		= 0x00,
	FS_60HZ		= 0x01,
	FS_250HZ	= 0x02,
	FS_500HZ	= 0x03,

	/*
		四十九、电子秤应用中提高TM7705 精度的方法
			当使用主时钟为 2.4576MHz 时,强烈建议将时钟寄存器设为 84H,此时数据输出更新率为10Hz,即每0.1S 输出一个新数据。
			当使用主时钟为 1MHz 时,强烈建议将时钟寄存器设为80H, 此时数据输出更新率为4Hz, 即每0.25S 输出一个新数据
	*/
	ZERO_0		= 0x00,
	ZERO_1		= 0x80
};

static void TM7705_SyncSPI(void);



static void TM7705_WriteByte(uint8_t _data);

static void TM7705_Write3Byte(uint32_t _data);
static uint8_t TM7705_ReadByte(void);
static uint16_t TM7705_Read2Byte(void);
static uint32_t TM7705_Read3Byte(void);
static void TM7705_WaitDRDY(void);
static void TM7705_ResetHard(void);
static void TM7705_Delay(void);

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{		
		    uint8_t Rxdata;
    while(HAL_SPI_TransmitReceive(&hspi2,&TxData,&Rxdata,1, 1000)!=HAL_OK)
		{
			HAL_Delay(1);
		}    
    return Rxdata;   
	
	

				    
}

//写入1个字节。带CS控制
static void TM7705_WriteByte(uint8_t _data)
{

TM_CS_L;	
	SPI1_ReadWriteByte(_data);
TM_CS_H;
}

/***********************以下为TM7705的移植函数***************************/
/************************************************************************/
void InitTM7705(void)
{
 int k=0;

TM7705_ResetHard();//rest
	
	TM7705_WriteByte(REG_CLOCK | WRITE | CH_1);			/* 先写通信寄存器,下一步是写时钟寄存器 */

	TM7705_WriteByte(CLKDIS_0 | CLK_4_9152M | FS_50HZ);	/* 刷新速率50Hz */


}

//硬件复位TM7705
static void TM7705_ResetHard(void)
{
TM_RST_H;
	HAL_Delay(1);
TM_RST_L;
	HAL_Delay(2);
TM_RST_H;
	HAL_Delay(1);
}

//同步TM7705芯片SPI接口时序
static void TM7705_SyncSPI(void)
{
	/* AD7705串行接口失步后将其复位。复位后要延时500us再访问 */
TM_CS_L;
	SPI1_ReadWriteByte(0xFF);
	SPI1_ReadWriteByte(0xFF);
	SPI1_ReadWriteByte(0xFF);
	SPI1_ReadWriteByte(0xFF);	

TM_CS_H;
}


//写入3个字节。带CS控制
static void TM7705_Write3Byte(uint32_t _data)
{
TM_CS_L;
	SPI1_ReadWriteByte((_data >> 16) & 0xFF);
	SPI1_ReadWriteByte((_data >> 8) & 0xFF);
	SPI1_ReadWriteByte(_data);
TM_CS_H;
}

//从AD芯片读取一个字(16位)
static uint8_t TM7705_ReadByte(void)
{
	uint8_t read;
TM_CS_L;
read = SPI1_ReadWriteByte(0xff);

	TM_CS_H;
	return read;
}

//读2字节数据
static uint16_t TM7705_Read2Byte(void)
{
	uint16_t read=0;

TM_CS_L;
	read = SPI1_ReadWriteByte(0xff);
	read <<= 8;
	read += SPI1_ReadWriteByte(0xff);
	TM_CS_H;

	return read;
}


//读3字节数据
static uint32_t TM7705_Read3Byte(void)
{
	uint32_t read;

//	CS_0();
//	read = TM7705_Recive8Bit();
//	read <<= 8;
//	read += TM7705_Recive8Bit();
//	read <<= 8;
//	read += TM7705_Recive8Bit();
//	CS_1();
	return read;
}

//等待内部操作完成。 自校准时间较长,需要等待。
static void TM7705_WaitDRDY(void)
{
	uint32_t i;

	for (i = 0; i < 1000; i++)
	{
		HAL_Delay(1);
		if (0==HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_8))
		{
			break;
		}
	}
	if (i >= 1000)
	{
		printf("TM7705_WaitDRDY() Time Out ...
");		/* 调试语句. 用语排错 */
	}
}

//写指定的寄存器,_RegID : 寄存器ID,寄存器值。 对于8位的寄存器,取32位形参的低8bit
void TM7705_WriteReg(uint8_t _RegID, uint32_t _RegValue)
{
	uint8_t bits;

	switch (_RegID)
	{
		case REG_COMM:		/* 通信寄存器 */		
		case REG_SETUP:		/* 设置寄存器 8bit */
		case REG_CLOCK:		/* 时钟寄存器 8bit */
			bits = 8;
			break;

		case REG_ZERO_CH1:	/* CH1 偏移寄存器 24bit */
		case REG_FULL_CH1:	/* CH1 满量程寄存器 24bit */
		case REG_ZERO_CH2:	/* CH2 偏移寄存器 24bit */
		case REG_FULL_CH2:	/* CH2 满量程寄存器 24bit*/
			bits = 24;
			break;

		case REG_DATA:		/* 数据寄存器 16bit */
		default:
			return;
	}

	TM7705_WriteByte(_RegID | WRITE);	/* 写通信寄存器, 指定下一步是写操作,并指定写哪个寄存器 */

	if (bits == 8)
	{
		TM7705_WriteByte((uint8_t)_RegValue);
	}
	else	/* 24bit */
	{
		TM7705_Write3Byte(_RegValue);
	}
}

//读指定的寄存器,_RegID : 寄存器ID,寄存器值。 对于8位的寄存器,取32位形参的低8bit
uint32_t TM7705_ReadReg(uint8_t _RegID)
{
	uint8_t bits;
	uint32_t read;

	switch (_RegID)
	{
		case REG_COMM:		/* 通信寄存器 */
		case REG_SETUP:		/* 设置寄存器 8bit */
		case REG_CLOCK:		/* 时钟寄存器 8bit */
			bits = 8;
			break;

		case REG_ZERO_CH1:	/* CH1 偏移寄存器 24bit */
		case REG_FULL_CH1:	/* CH1 满量程寄存器 24bit */
		case REG_ZERO_CH2:	/* CH2 偏移寄存器 24bit */
		case REG_FULL_CH2:	/* CH2 满量程寄存器 24bit*/
			bits = 24;
			break;

		case REG_DATA:		/* 数据寄存器 16bit */
		default:
			return 0xFFFFFFFF;
	}

	TM7705_WriteByte(_RegID | READ);	/* 读通信寄存器, 指定下一步是读操作,并指定写哪个寄存器 */

	if (bits == 16)
	{
		read = TM7705_Read2Byte();
	}
	else if (bits == 8)
	{
		read = TM7705_ReadByte();
	}
	else	/* 24bit */
	{
		read = TM7705_Read3Byte();
	}
	return read;
}

//启动自校准. 内部自动短接AIN+ AIN-校准0位,内部短接到Vref 校准满位。此函数执行过程较长,实测约 180ms
void TM7705_CalibSelf(uint8_t _ch)
{
	if (_ch == 1)
	{
		
		/* 自校准CH1 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_1);	/* 写通信寄存器,下一步是写设置寄存器,通道1 */		
		TM7705_WriteByte(MD_CAL_SELF | __CH1_GAIN_BIPOLAR_BUF | FSYNC_0);/* 启动自校准 */
		TM7705_WaitDRDY();	/* 等待内部操作完成 --- 时间较长,约180ms */
	}
	else if (_ch == 2)
	{
		
		/* 自校准CH2 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_2);	/* 写通信寄存器,下一步是写设置寄存器,通道2 */
		TM7705_WriteByte(MD_CAL_SELF | __CH2_GAIN_BIPOLAR_BUF | FSYNC_0);	/* 启动自校准 */
		TM7705_WaitDRDY();	/* 等待内部操作完成  --- 时间较长,约180ms */
	}
	
}

//启动系统校准零位. 请将AIN+ AIN-短接后,执行该函数。校准应该由主程序控制并保存校准参数。
void TM7705_SytemCalibZero(uint8_t _ch)
{
	if (_ch == 1)
	{
		TM7705_WaitDRDY();	/* 等待内部操作完成 */
		/* 校准CH1 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_1);	/* 写通信寄存器,下一步是写设置寄存器,通道1 */
		TM7705_WriteByte(MD_CAL_ZERO | __CH1_GAIN_BIPOLAR_BUF | FSYNC_0);/* 启动自校准 */
		
	}
	else if (_ch == 2)
	{
		
		TM7705_WaitDRDY();	/* 等待内部操作完成 */
		/* 校准CH2 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_2);	/* 写通信寄存器,下一步是写设置寄存器,通道1 */
		TM7705_WriteByte(MD_CAL_ZERO | __CH2_GAIN_BIPOLAR_BUF | FSYNC_0);	/* 启动自校准 */
		
	}
}

//启动系统校准满位. 请将AIN+ AIN-接最大输入电压源,执行该函数。校准应该由主程序控制并保存校准参数
//执行完毕后。可以通过 TM7705_ReadReg(REG_FULL_CH1) 和  TM7705_ReadReg(REG_FULL_CH2) 读取校准参数。
void TM7705_SytemCalibFull(uint8_t _ch)
{
	if (_ch == 1)
	{
		TM7705_WaitDRDY();	/* 等待内部操作完成 */
		/* 校准CH1 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_1);	/* 写通信寄存器,下一步是写设置寄存器,通道1 */
		TM7705_WriteByte(MD_CAL_FULL | __CH1_GAIN_BIPOLAR_BUF | FSYNC_0);/* 启动自校准 */
		
	}
	else if (_ch == 2)
	{
		
		TM7705_WaitDRDY();	/* 等待内部操作完成 */
		/* 校准CH2 */
		TM7705_WriteByte(REG_SETUP | WRITE | CH_2);	/* 写通信寄存器,下一步是写设置寄存器,通道1 */
		TM7705_WriteByte(MD_CAL_FULL | __CH2_GAIN_BIPOLAR_BUF | FSYNC_0);	/* 启动自校准 */
		
	}
}

//读通道1或2的ADC数据
uint16_t TM7705_ReadAdc(uint8_t _ch)
{
	uint16_t read = 0,i=0;

	/* 为了避免通道切换造成读数失效,读2次 */

		for(i=0;i<2;i++)
			{

		if (_ch == 1)
		{
			TM7705_WaitDRDY();		/* 等待DRDY口线为0 */		
			TM7705_WriteByte(0x38);
			read = TM7705_Read2Byte();
		}
		else if (_ch == 2)
		{
			TM7705_WaitDRDY();	
			TM7705_WriteByte(0x39);
			read = TM7705_Read2Byte();
		}
	
	}
	return read;	
}

//CLK之间的延迟,时序延迟. 用于STM32F407  168M主频  改为STM32F103ZET6主频变为72M延时数相应减少
static void TM7705_Delay(void)
{
	uint16_t i;
	for (i = 0; i < 3; i++);
}

main.c

	InitTM7705();                //FS_50HZ
	TM7705_CalibSelf(1);		/* 自校准。执行时间较长,约180ms */	
	adc1 = TM7705_ReadAdc(1);		

	TM7705_CalibSelf(2);		/* 自校准。执行时间较长,约180ms */
	adc2 = TM7705_ReadAdc(2);	
	printf("初始化TM7705 OK! adc1=%d adc2=%d
",adc1,adc2);

 while (1)
  {


        /* 双通道切换采样,执行一轮实际那约 160ms */	
    	adc1 = TM7705_ReadAdc(1);	/* 执行时间 80ms */			
		adc2 = TM7705_ReadAdc(2);	/* 执行时间 80ms */
		
  }

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。