TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记模块对输入电压进行了 0 5 倍的分压 才进入芯片采集

大家好,欢迎来到IT知识分享网。

  1. 目录

    AD7705简介

    ADC芯片——AD7705最详细讲解(STM32)http://t.csdn.cn/UbXjw

    工程以及主要代码分享,另外,附带演示视频。


    AD7705简介

  • TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

  • TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记
  • TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记
  • 模块对输入电压进行了0.5倍的分压,才进入芯片采集。
  • TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

一句话说明白,

TM7705是一个外置16位分辨率双通道ADC芯片,SPI通信协议,采用Σ-∆转换技术。

价格便宜,对标同型号AD7705,基本能直接替换,程序基本通用。

  • AD7705和TM7705功能区别:

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

在文末放好调试成功的工程完整文件链接。

在CSDN上,搜索TM7705

这两篇文章是讲解的比较详细的,

ADC芯片——AD7705最详细讲解(STM32)http://t.csdn.cn/UbXjw

STM32F103ZET6驱动TM7705(AD7705)代码加心得http://t.csdn.cn/lWMiE

不过,都没有解决一个实际性的问题,怎么用起来 这个adc

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

  1.  第一篇,提供了完整工程链接下载,接口也方便,点赞

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

下载收费积分都是次要的。

最重要的一点是,代码问题重重。

经常TIME OUT ,超时

初始化,以及获取一次ADC需要大概10秒。

似乎是偶尔运行成功一样。

程序是存在问题的。

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

和作者评论区讨论未果,也许年代久远,作者也难在实际调试

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

 此代码实际运行视频我会放在文末链接中。

  •  第二篇,ADC芯片——AD7705最详细讲解(STM32)

驱动原理讲解确实很详细,建议学习时,仔细阅读。点赞

却只给出了C,H文件,

加入工程并不难,不过,代码简单明了,适合老手进阶使用。

缺乏通用性,代码编程风格相比于前一个文章以及安富莱电子得代码来说,规范性上差太多了。

另外,每次获取值,都要初始化一次。似乎存在重复操作。

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

 TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

总之,在CSDN上,代码存在超时问题,一直未得到解决,

adc数据可以获取到,但是TM7705模块DRDY电平一直为高的问题,始终存在。

经过对数据手册的仔细阅读,程序大体流程如下:

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

 

大概可以理解成分布式的寄存器结构。

通信寄存器就是那个大哥,你要动他哪个小弟,怎么动,你都得先告诉他,有的小弟打完了还要告诉大哥结果怎们样。

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

 

不多废话了。直接上代码。

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

 优化后,是网上代码-STM32F103ZET6驱动TM7705(AD7705)代码加心得代码修改而来。采用硬件SPI.

另外,自己也写了一个适合更改单片机引脚的软件SPI程序。

工程以及主要代码分享,另外,附带演示视频

百度云https://pan.baidu.com/s/1W1pj8wGVMaSwfc3mdO-0ZQ?pwd=6666 

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记

TM7705(AD7705)驱动调试总结-基于stm32f103zet6-填坑日记 

 MAIN.C

 #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(); 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); printf("CH1=%5d v1:%5dmv\r\n",adc1,volt1); LCD_ShowString(60,154,200,16,16,BUFFER); sprintf(BUFFER,"CH2=%5d v2:%5dmv",adc2,volt2); printf("CH2=%5d v2:%5dmv\r\n",adc2,volt2); LCD_ShowString(60,170,200,16,16,BUFFER); } } 
#include <drv_tm7705.h> #include <drv_spi.h> #include <delay.h> #include <lcd.h> /* 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 */ #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引脚输出时钟以省电 */ 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; } 
 #ifndef _DRV_TM7705_H #define _DRV_TM7705_H #include "sys.h" void TM7705_CalibSelf(uint8_t _ch); //启动自校准 void TM7705_Init(void); //初始化函数 uint16_t TM7705_ReadAdc(uint8_t _ch);//读值 #endif 
#include "drv_spi.h" //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最近接收的数据 } 
#ifndef __DRV_SPI_H #define __DRV_SPI_H #include "sys.h" void SPI2_Init(void); //初始化SPI口 void SPI2_SetSpeed(u8 SpeedSet); //设置SPI速度 u8 SPI2_ReadWriteByte(u8 TxData);//SPI总线读写一个字节 #endif 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/116925.html

(0)
上一篇 2025-11-25 10:45
下一篇 2025-11-25 11:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信