TM7705(AD7705)驱动调试-stm32f103zet6-填坑日记
一句话说明白,
TM7705是一个外置16位分辨率双通道ADC芯片,SPI通信协议,采用Σ-∆转换技术。
价格便宜,对标同型号AD7705,基本能直接替换,程序基本通用。
- AD7705和TM7705功能区别:
AD7705是美国模拟器件公司生产的。15元左右。
TM7705 是深圳天微生产的,引脚和功能和AD7705完全兼容。可以替代AD7705。价格比进口的便宜几倍。5元左右。
(1)TM7705多一个内部2.48V参考电压,可以通过写测试寄存器开启(默认不开启)
(2)TM7705多一种时钟设置方法,可以提高精度。时钟寄存器的ZERO 3个bit位中最高位=1来启用。这种模式下,数据刷新率变低(每秒10个样本),精度变高。
在文末放好调试成功的工程完整文件链接。
这两篇文章是讲解的比较详细的,
ADC芯片——AD7705最详细讲解(STM32)http://t.csdn.cn/UbXjw
STM32F103ZET6驱动TM7705(AD7705)代码加心得http://t.csdn.cn/lWMiE
不过,都没有解决一个实际性的问题,怎么用起来 这个adc
- 第一篇,提供了完整工程链接下载,接口也方便,点赞
下载收费积分都是次要的。
最重要的一点是,代码问题重重。
经常TIME OUT ,超时
初始化,以及获取一次ADC需要大概10秒。
似乎是偶尔运行成功一样。
程序是存在问题的。
和作者评论区讨论未果,也许年代久远,作者也难在实际调试
此代码实际运行视频我会放在文末链接中。
- 第二篇,ADC芯片——AD7705最详细讲解(STM32)
驱动原理讲解确实很详细,建议学习时,仔细阅读。点赞
却只给出了C,H文件,
加入工程并不难,不过,代码简单明了,适合老手进阶使用。
缺乏通用性,代码编程风格相比于前一个文章以及安富莱电子得代码来说,规范性上差太多了。
另外,每次获取值,都要初始化一次。似乎存在重复操作。
adc数据可以获取到,但是TM7705模块DRDY电平一直为高的问题,始终存在。
经过对数据手册的仔细阅读,程序大体流程如下:
大概可以理解成分布式的寄存器结构。
通信寄存器就是那个大哥,你要动他哪个小弟,怎么动,你都得先告诉他,有的小弟打完了还要告诉大哥结果怎们样。
不多废话了。直接上代码。
优化后,是网上代码-STM32F103ZET6驱动TM7705(AD7705)代码加心得代码修改而来。采用硬件SPI.
另外,自己也写了一个适合更改单片机引脚的软件SPI程序。
工程以及主要代码分享,另外,附带演示视频。
百度云https://pan.百度.com/s/1W1pj8wGVMaSwfc3mdO-0ZQ?pwd=6666
链接:https://pan.百度.com/s/1W1pj8wGVMaSwfc3mdO-0ZQ?pwd=6666
提取码:6666
MAIN.C
-
-
-
-
-
-
-
-
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=] v1:]mv",adc1,volt1);
-
printf("CH1=] v1:]mv\r\n",adc1,volt1);
-
-
-
LCD_ShowString(60,154,200,16,16,BUFFER);
-
-
sprintf(BUFFER,"CH2=] v2:]mv",adc2,volt2);
-
printf("CH2=] v2:]mv\r\n",adc2,volt2);
-
-
LCD_ShowString(60,170,200,16,16,BUFFER);
-
}
-
}
-
-
-
-
-
/*
-
TM7705模块可以直接插到STM32f103战舰开发板模块的排母接口上。
-
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
-
*/
-
-
-
-
-
-
-
/*================下面为芯片的驱动数据定义============================*/
-
/* 通信寄存器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引脚输出时钟以省电 */
-
-
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,
-
-
-
ZERO_0 = 0x00,
-
ZERO_1 = 0x80
-
};
-
-
static void TM7705_ResetHard(void); //硬件复位
-
static void TM7705_SyncSPI(void);
-
static uint16_t TM7705_Read2Byte(void);
-
-
/*====================芯片的驱动数据定义到此结束==========================*/
-
-
void TM7705_Init(void) //初始化函数
-
{
-
uint16_t read = 0;
-
-
/*==信号引脚初始化==*/
-
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_IPU; //PG8 输入 DRAY
-
GPIO_Init(GPIOG, &GPIO_InitStructure);
-
GPIO_ResetBits(GPIOG,GPIO_Pin_8 );
-
-
-
-
-
-
SPI2_Init(); //初始化SPI2外设,在drv_spi.h中实现
-
SPI2_SetSpeed(SPI_BaudRatePrescaler_4);//设置为时钟
-
-
TM7705_CS = 1; //TM7705初始化不选中
-
-
TM7705_ResetHard(); //硬件复位
-
-
-
TM7705_SyncSPI(); //同步SPI接口时序
-
-
-
-
/*配置时钟寄存器*/
-
TM7705_CS = 0;
-
SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_1); //先写通信寄存器,下一步写时钟寄存器
-
-
SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_50HZ ); //刷新速率250HZ
-
-
-
-
SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_2); //先写通信寄存器,下一步写时钟寄存器
-
-
SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_50HZ ); //刷新速率250HZ
-
-
TM7705_CS = 1;
-
-
-
SPI2_ReadWriteByte(REG_SETUP | WRITE |CH_1); //先写通信寄存器,下一步写设置寄存器
-
-
SPI2_ReadWriteByte(MD_NORMAL | GAIN_1 | UNIPOLAR |BUF_EN |FSYNC_0 ); //写设置寄存器正常模式,增益为1、dan极性、有缓冲、滤波器工作、
-
-
/*每次上电进行一次自校准*/
-
TM7705_CalibSelf(1); //内部自校准
-
-
-
SPI2_ReadWriteByte(REG_SETUP | WRITE |CH_2); //先写通信寄存器,下一步写设置寄存器
-
-
SPI2_ReadWriteByte(MD_NORMAL | GAIN_1 | UNIPOLAR |BUF_EN |FSYNC_0 ); //写设置寄存器正常模式,增益为1、dan极性、有缓冲、滤波器工作、
-
-
-
TM7705_CalibSelf(2); //内部自校准
-
-
// SPI2_ReadWriteByte(0x39);
-
// read = TM7705_Read2Byte();
-
-
-
-
}
-
-
/*===硬件复位Tm7705芯片,无出入参数===*/
-
static void TM7705_ResetHard(void) //硬件复位
-
{
-
TM7705_RST = 1;
-
delay_ms(1);
-
TM7705_RST = 0;
-
delay_ms(20);
-
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;
-
delay_ms(1);
-
-
}
-
/*====================================================================
-
=功能说明: 等待内部操作完成,自校准时间较长,需要等待
-
=参 数: 无
-
======================================================================*/
-
static void TM7705_WaitDRDY(void)
-
{
-
delay_ms(40);
-
-
while(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_8==1)){}//待数据准备好AdDrdy=0,0代表数据准备好了。1的时候没准备好,等待
-
}
-
-
-
-
/*====================================================================
-
= 功能说明: 启动自校准. 内部自动短接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、滤波器工作、自校准
-
-
delay_ms(190);
-
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); /* 启动自校准 */
-
delay_ms(190);
-
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)
-
{
-
SPI2_ReadWriteByte(0x38);
-
-
}
-
else if (_ch == 2)
-
{
-
-
SPI2_ReadWriteByte(0x39);
-
-
}
-
-
read = TM7705_Read2Byte();
-
}
-
return read;
-
-
-
-
}
-
-
-
-
-
-
-
-
void TM7705_CalibSelf(uint8_t _ch); //启动自校准
-
void TM7705_Init(void); //初始化函数
-
uint16_t TM7705_ReadAdc(uint8_t _ch);//读值
-
-
-
-
-
-
//SPI口初始化
-
//这里针是对SPI2的初始化
-
-
-
-
void SPI2_Init(void)
-
{
-
GPIO_InitTypeDef GPIO_InitStructure;
-
SPI_InitTypeDef SPI_InitStructure;
-
-
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
-
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能
-
-
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出
-
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
-
-
GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉
-
-
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
-
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
-
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
-
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
-
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
-
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
-
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //定义波特率预分频的值:波特率预分频值为256
-
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
-
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
-
SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
-
-
SPI_Cmd(SPI2, ENABLE); //使能SPI外设
-
-
SPI2_ReadWriteByte(0xff);//启动传输
-
-
-
}
-
//SPI 速度设置函数
-
//SpeedSet:
-
//SPI_BaudRatePrescaler_2 2分频
-
//SPI_BaudRatePrescaler_8 8分频
-
//SPI_BaudRatePrescaler_16 16分频
-
//SPI_BaudRatePrescaler_256 256分频
-
-
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
-
{
-
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//检测传递给函数的参数是否是有效的参数
-
SPI2->CR1&=0XFFC7;
-
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
-
SPI_Cmd(SPI2,ENABLE);
-
-
}
-
-
//SPIx 读写一个字节
-
//TxData:要写入的字节
-
//返回值:读取到的字节
-
u8 SPI2_ReadWriteByte(u8 TxData)
-
{
-
u8 retry=0;
-
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
-
{
-
retry ;
-
if(retry>200)return 0;
-
}
-
SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
-
retry=0;
-
-
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
-
{
-
retry ;
-
if(retry>200)return 0;
-
}
-
return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据
-
}
-
-
-
-
-
-
-
void SPI2_Init(void); //初始化SPI口
-
void SPI2_SetSpeed(u8 SpeedSet); //设置SPI速度
-
u8 SPI2_ReadWriteByte(u8 TxData);//SPI总线读写一个字节
-
-
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhejcgbe
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01