标题:
采用STM32F103ZET6驱动TM7705或者AD7705程序
[打印本页]
作者:
51黑电子论坛51
时间:
2023-3-30 17:08
标题:
采用STM32F103ZET6驱动TM7705或者AD7705程序
/*===================================================
= 模块名称: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)
2023-3-30 17:20 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1