- /*===================================================
- = 模块名称:TM7705 驱动模块(2通道带PGA的16位ADC)
- = 说明:使用芯片自带的SPI2驱动
- = 作者:xcm
- = 版本:V1.0
- =======================================================*/
- #include <drv_tm7705.h>
- #include <drv_spi.h>
- #include <delay.h>
- #include <lcd.h>
- /*
- TM7705模块可以直接插到STM32f103开发板nRF24L01模块的排母接口上。
- TM7705模块 STM32F103开发板
- SCK ------ PB13/SPI2_SCK
- DOUT ------ PB14/SPI2_MISO
- DIN ------ PB15/SPI3_MOSI
- CS ------ PG7/NRF24L01_CS
- DRDY ------ PG8/NRF24L01_IRQ
- RST ------ PG6/NRF_CE
- */
- #define TM7705_CS PGout(7) //CS片选宏定义,低电平有效
- #define TM7705_RST PGout(6) //RST使能复位宏定义,低电平有效
- #define TM7705_DRDY PGin(8) //DRDY,低电平时表示TM7705可读
- /*================下面为芯片的驱动数据定义============================*/
- /* 通信寄存器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_20HZ = 0X00,
- FS_25HZ = 0x01,
- FS_100HZ = 0x20,
- FS_200HZ = 0x03,
- FS_50HZ = 0x04,
- FS_60HZ = 0x05,
- FS_250HZ = 0x06,
- FS_500HZ = 0x07,
- /*
- 四十九、电子秤应用中提高TM7705 精度的方法
- 当使用主时钟为 2.4576MHz 时,强烈建议将时钟寄存器设为 84H,此时数据输出更新率为10Hz,即每0.1S 输出一个新数据。
- 当使用主时钟为 1MHz 时,强烈建议将时钟寄存器设为80H, 此时数据输出更新率为4Hz, 即每0.25S 输出一个新数据
- */
- ZERO_0 = 0x00,
- ZERO_1 = 0x80
- };
- static void TM7705_ResetHard(void); //硬件复位
- static void TM7705_SyncSPI(void);
- /*====================芯片的驱动数据定义到此结束==========================*/
- void TM7705_Init(void) //初始化函数
- {
- /*==信号引脚初始化==*/
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG, ENABLE); //使能PB,G端口时钟
-
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PB12上拉 防止W25X的干扰
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化指定IO
- GPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PG 7 推挽 CS
- GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IO
- GPIO_SetBits(GPIOG,GPIO_Pin_7);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PG6 推挽 RST
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IO
- GPIO_ResetBits(GPIOG,GPIO_Pin_6 );
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PG8 输入 DRAY
- //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PG8 输入 DRAY 两种方式亲测都可以
- GPIO_Init(GPIOG, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOG,GPIO_Pin_8 );
-
-
-
-
-
- SPI2_Init(); //初始化SPI2外设,在drv_spi.h中实现
- SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
-
- TM7705_CS = 1; //TM7705初始化不选中
- TM7705_RST = 0;
- delay_ms(10);
- TM7705_ResetHard(); //硬件复位
- delay_ms(5);
-
- TM7705_SyncSPI(); //同步SPI接口时序
- delay_ms(10);
-
- /*配置时钟寄存器*/
- TM7705_CS = 0;
- SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_1); //先写通信寄存器,下一步写时钟寄存器
- delay_ms(10);
- SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_100HZ ); //刷新速率250HZ
- delay_ms(10);
- SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_2); //先写通信寄存器,下一步写时钟寄存器
- delay_ms(10);
- SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_100HZ ); //刷新速率250HZ
- delay_ms(10);
- TM7705_CS = 1;
- /*下面注释内容在TM7705_CalibSelf(1);函数中集成实现*/
- // SPI2_ReadWriteByte(REG_SETUP | WRITE |CH_1); //先写通信寄存器,下一步写设置寄存器
- // delay_ms(10);
- // SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | BIPOLAR |BUF_EN |FSYNC_0 ); //写设置寄存器,双极性、有缓冲、增益为1、滤波器工作、自校准
- // delay_ms(5 00);
- /*每次上电进行一次自校准*/
- TM7705_CalibSelf(1); //内部自校准
- TM7705_CalibSelf(2); //内部自校准
- delay_ms(5);
- }
- /*===硬件复位Tm7705芯片,无出入参数===*/
- static void TM7705_ResetHard(void) //硬件复位
- {
- TM7705_RST = 1;
- delay_ms(1);
- TM7705_RST = 0;
- delay_ms(2);
- TM7705_RST = 1;
- delay_ms(1);
- }
- /*=============================================
- = 功能:同步TM7705芯片SPI接口时序
- = 说明:连续发送32个1即可,不同步会发生数据错位
- ==============================================*/
- static void TM7705_SyncSPI(void) //同步SPI接口时序
- {
- TM7705_CS = 0;
- SPI2_ReadWriteByte(0xFF);//32个1
- SPI2_ReadWriteByte(0xFF);
- SPI2_ReadWriteByte(0xFF);
- SPI2_ReadWriteByte(0xFF);
-
- TM7705_CS = 1;
- }
- /*====================================================================
- =功能说明: 等待内部操作完成,自校准时间较长,需要等待
- =参 数: 无
- ======================================================================*/
- static void TM7705_WaitDRDY(void)
- {
- uint32_t i;
- for(i = 0; i<4000000; i++)
- {
- if(TM7705_DRDY == 0)
- {
- break;
- }
-
- }
- if(i >=4000000 )
- {
- LCD_ShowString(50,100,200,16,16,"TM7705 WAIT TIME OUT !!!");
-
- }
- }
- /*====================================================================
- = 功能说明: 启动自校准. 内部自动短接AIN+ AIN-校准0位,内部短接到Vref
- 校准满位。此函数执行过程较长,实测约 180ms
- = 形 参: _ch : ADC通道,1或2
- =====================================================================*/
- void TM7705_CalibSelf(uint8_t _ch)
- {
- if (_ch == 1)
- {
- /* 自校准CH1 */
- SPI2_ReadWriteByte(REG_SETUP | WRITE | CH_1); /* 写通信寄存器,下一步是写设置寄存器,通道1 */
- SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | UNIPOLAR |BUF_EN |FSYNC_0);/* 启动自校准 *///写设置寄存器,单极性、有缓冲、增益为1、滤波器工作、自校准
- //SPI2_ReadWriteByte(0x4C);
- TM7705_WaitDRDY(); /* 等待内部操作完成 --- 时间较长,约180ms */
- }
- else if (_ch == 2)
- {
- /* 自校准CH2 */
- SPI2_ReadWriteByte(REG_SETUP | WRITE | CH_2); /* 写通信寄存器,下一步是写设置寄存器,通道2 */
- SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | UNIPOLAR |BUF_EN |FSYNC_0); /* 启动自校准 */
- //SPI2_ReadWriteByte(0x44);
- TM7705_WaitDRDY(); /* 等待内部操作完成 --- 时间较长,约180ms */
- }
- }
- /*=====================================================================
- =功能说明:读到一个8位数据
- =参 数:返回读到的值
- =====================================================================*/
- static uint8_t TM7705_ReadByte(void)
- {
- uint8_t read = 0;
- TM7705_CS = 0;
- read = SPI2_ReadWriteByte(0xFF);
- TM7705_CS = 1;
-
- return read;
- }
- /*=====================================================================
- =功能说明:读到一个16位数据(半字)
- =参 数:返回读到16位数据的值
- =====================================================================*/
- static uint16_t TM7705_Read2Byte()
- {
- uint16_t read = 0;
-
- TM7705_CS =0 ;
- read = SPI2_ReadWriteByte(0xFF);
- read <<=8;
- read += SPI2_ReadWriteByte(0xFF);
- TM7705_CS =1 ;
- return read;
-
- }
- /*=====================================================================
- =功能说明:读到一个24位数据(3字节)
- =参 数:返回读到24位数据的值
- =====================================================================*/
- static uint16_t TM7705_Read3Byte(void)
- {
- uint32_t read = 0;
- TM7705_CS = 0;
- read = SPI2_ReadWriteByte(0xFF);
- read <<=8;
- read += SPI2_ReadWriteByte(0xFF);
- read <<=8;
- read += SPI2_ReadWriteByte(0xFF);
- TM7705_CS =1 ;
-
- return read;
-
- }
- /*=====================================================================
- =功能说明:读取采样电压值
- =参 数:返回采样值
- =====================================================================*/
- uint16_t TM7705_ReadAdc(uint8_t _ch)
- {
- uint8_t i;
- uint16_t read = 0;
-
- /* 为了避免通道切换造成读数失效,读2次 */
- for (i = 0; i < 2; i++)
- {
- TM7705_WaitDRDY(); /* 等待DRDY口线为0 */
- if (_ch == 1)
- {
- TM7705_CS = 0;
- SPI2_ReadWriteByte(0x38);
- TM7705_CS = 1;
- }
- else if (_ch == 2)
- {
- TM7705_CS = 0;
- SPI2_ReadWriteByte(0x39);
- TM7705_CS = 1;
- }
- //TM7705_WaitDRDY(); /* 等待内部操作完成 --- 时间较长,约180ms */
- read = TM7705_Read2Byte();
- }
- return read;
- }
复制代码
#include <delay.h>
#include <sys.h>
#include <usart.h>
#include <lcd.h>
#include <drv_spi.h>
#include <drv_tm7705.h>
char BUFFER[200];
int main(void)
{
int volt1,volt2;
uint16_t adc1,adc2;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVUC中断分组为2
uart_init(115200);
delay_init();
LCD_Init();
POINT_COLOR = RED;
TM7705_Init();
TM7705_CalibSelf(1); //自校准
adc1 = TM7705_ReadAdc(1);
TM7705_CalibSelf(2); //自校准
adc2 = TM7705_ReadAdc(2);
while(1)
{
adc1 = TM7705_ReadAdc(1);
adc2 = TM7705_ReadAdc(2);
volt1 = (adc1 * 5000) / 65535;
volt2 = (adc2 * 5000) / 65535;
sprintf(BUFFER,"CH1=%5d v1:%5dmv",adc1,volt1);
LCD_ShowString(60,154,200,16,16,BUFFER);
sprintf(BUFFER,"CH2=%5d v2:%5dmv",adc2,volt2);
LCD_ShowString(60,170,200,16,16,BUFFER);
}
}
Keil代码下载:
Keil代码.7z
(238.86 KB, 下载次数: 27)
|