找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 864|回复: 0
打印 上一主题 下一主题
收起左侧

采用STM32F103ZET6驱动TM7705或者AD7705程序

[复制链接]
跳转到指定楼层
楼主
ID:376031 发表于 2023-3-30 17:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*===================================================
  2. =        模块名称:TM7705 驱动模块(2通道带PGA的16位ADC)
  3. =        说明:使用芯片自带的SPI2驱动
  4. =        作者:xcm
  5. =         版本:V1.0
  6. =======================================================*/

  7. #include <drv_tm7705.h>
  8. #include <drv_spi.h>
  9. #include <delay.h>
  10. #include <lcd.h>
  11. /*
  12.         TM7705模块可以直接插到STM32f103开发板nRF24L01模块的排母接口上。
  13.     TM7705模块   STM32F103开发板
  14.       SCK   ------  PB13/SPI2_SCK
  15.       DOUT  ------  PB14/SPI2_MISO
  16.       DIN   ------  PB15/SPI3_MOSI
  17.       CS    ------  PG7/NRF24L01_CS
  18.       DRDY  ------  PG8/NRF24L01_IRQ
  19.       RST   ------  PG6/NRF_CE                                       
  20. */

  21. #define TM7705_CS                         PGout(7)  //CS片选宏定义,低电平有效
  22. #define TM7705_RST                         PGout(6)  //RST使能复位宏定义,低电平有效
  23. #define TM7705_DRDY         PGin(8)  //DRDY,低电平时表示TM7705可读


  24. /*================下面为芯片的驱动数据定义============================*/
  25. /* 通信寄存器bit定义 */
  26. enum
  27. {
  28.         /* 寄存器选择  RS2 RS1 RS0  */
  29.         REG_COMM        = 0x00,        /* 通信寄存器 */
  30.         REG_SETUP        = 0x10,        /* 设置寄存器 */
  31.         REG_CLOCK        = 0x20,        /* 时钟寄存器 */
  32.         REG_DATA        = 0x30,        /* 数据寄存器 */
  33.         REG_ZERO_CH1        = 0x60,        /* CH1 偏移寄存器 */
  34.         REG_FULL_CH1        = 0x70,        /* CH1 满量程寄存器 */
  35.         REG_ZERO_CH2        = 0x61,        /* CH2 偏移寄存器 */
  36.         REG_FULL_CH2        = 0x71,        /* CH2 满量程寄存器 */

  37.         /* 读写操作 */
  38.         WRITE                 = 0x00,        /* 写操作 */
  39.         READ                 = 0x08,        /* 读操作 */

  40.         /* 通道 */
  41.         CH_1                = 0,        /* AIN1+  AIN1- */
  42.         CH_2                = 1,        /* AIN2+  AIN2- */
  43.         CH_3                = 2,        /* AIN1-  AIN1- */
  44.         CH_4                = 3                /* AIN1-  AIN2- */
  45. };

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

  53.         GAIN_1                        = (0 << 3),        /* 增益 */
  54.         GAIN_2                        = (1 << 3),        /* 增益 */
  55.         GAIN_4                        = (2 << 3),        /* 增益 */
  56.         GAIN_8                        = (3 << 3),        /* 增益 */
  57.         GAIN_16                        = (4 << 3),        /* 增益 */
  58.         GAIN_32                        = (5 << 3),        /* 增益 */
  59.         GAIN_64                        = (6 << 3),        /* 增益 */
  60.         GAIN_128                = (7 << 3),        /* 增益 */

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

  64.         BUF_NO                        = (0 << 1),        /* 输入无缓冲(内部缓冲器不启用) */
  65.         BUF_EN                        = (1 << 1),        /* 输入有缓冲 (启用内部缓冲器) 可处理高阻抗源 */

  66.         FSYNC_0                        = 0,
  67.         FSYNC_1                        = 1                /* 不启用 */
  68. };

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

  74.         /*
  75.                 2.4576MHz(CLKDIV=0 )或为 4.9152MHz (CLKDIV=1 ),CLK 应置 “0”。
  76.                 1MHz (CLKDIV=0 )或 2MHz   (CLKDIV=1 ),CLK 该位应置  “1”
  77.         */
  78.         CLK_4_9152M = 0x08,
  79.         CLK_2_4576M = 0x00,
  80.         CLK_1M                 = 0x04,
  81.         CLK_2M                 = 0x0C,
  82.         
  83. /*输出更新速率设置*/
  84.         FS_20HZ     = 0X00,
  85.         FS_25HZ     = 0x01,
  86.         FS_100HZ    = 0x20,
  87.         FS_200HZ    = 0x03,
  88.         FS_50HZ                = 0x04,
  89.         FS_60HZ                = 0x05,
  90.         FS_250HZ        = 0x06,
  91.         FS_500HZ        = 0x07,

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

  100. static void TM7705_ResetHard(void);                //硬件复位
  101. static void TM7705_SyncSPI(void);


  102. /*====================芯片的驱动数据定义到此结束==========================*/

  103. void TM7705_Init(void) //初始化函数
  104. {
  105.         /*==信号引脚初始化==*/
  106.         GPIO_InitTypeDef GPIO_InitStructure;


  107.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG, ENABLE);         //使能PB,G端口时钟
  108.             
  109.         
  110.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                                 //PB12上拉 防止W25X的干扰
  111.          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                  //推挽输出
  112.          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  113.          GPIO_Init(GPIOB, &GPIO_InitStructure);        //初始化指定IO
  114.          GPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉                                
  115.          

  116.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;        //PG 7 推挽          CS
  117.          GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IO
  118.         GPIO_SetBits(GPIOG,GPIO_Pin_7);        
  119.         
  120.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;        //PG6  推挽   RST              
  121.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  122.          GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IO
  123.         GPIO_ResetBits(GPIOG,GPIO_Pin_6 );
  124.         
  125.         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;   
  126.         GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING; //PG8 输入  DRAY
  127.         //GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU; //PG8 输入  DRAY   两种方式亲测都可以
  128.         GPIO_Init(GPIOG, &GPIO_InitStructure);
  129.         GPIO_ResetBits(GPIOG,GPIO_Pin_8 );
  130.         
  131.         
  132.         
  133.         
  134.         
  135.         SPI2_Init();                        //初始化SPI2外设,在drv_spi.h中实现
  136.         SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
  137.         
  138.         TM7705_CS = 1;                         //TM7705初始化不选中
  139.         TM7705_RST = 0;
  140.         delay_ms(10);
  141.         TM7705_ResetHard();                //硬件复位
  142.         delay_ms(5);
  143.         
  144.         TM7705_SyncSPI();      //同步SPI接口时序
  145.         delay_ms(10);
  146.         
  147.         /*配置时钟寄存器*/
  148.         TM7705_CS = 0;
  149.         SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_1); //先写通信寄存器,下一步写时钟寄存器
  150.         delay_ms(10);
  151.         SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_100HZ ); //刷新速率250HZ
  152.         delay_ms(10);
  153.         SPI2_ReadWriteByte(REG_CLOCK | WRITE |CH_2); //先写通信寄存器,下一步写时钟寄存器
  154.         delay_ms(10);
  155.         SPI2_ReadWriteByte(CLKDIS_0 | CLK_4_9152M | FS_100HZ ); //刷新速率250HZ
  156.         delay_ms(10);
  157.         TM7705_CS = 1;
  158. /*下面注释内容在TM7705_CalibSelf(1);函数中集成实现*/
  159. //        SPI2_ReadWriteByte(REG_SETUP | WRITE |CH_1); //先写通信寄存器,下一步写设置寄存器
  160. //        delay_ms(10);
  161. //        SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | BIPOLAR |BUF_EN |FSYNC_0        ); //写设置寄存器,双极性、有缓冲、增益为1、滤波器工作、自校准
  162. //        delay_ms(5 00);

  163.         /*每次上电进行一次自校准*/
  164.         TM7705_CalibSelf(1);      //内部自校准
  165.         TM7705_CalibSelf(2);      //内部自校准
  166.         delay_ms(5);
  167. }        

  168. /*===硬件复位Tm7705芯片,无出入参数===*/
  169. static void TM7705_ResetHard(void)        //硬件复位
  170. {
  171.         TM7705_RST = 1;
  172.         delay_ms(1);
  173.         TM7705_RST = 0;
  174.         delay_ms(2);
  175.         TM7705_RST = 1;
  176.         delay_ms(1);
  177. }

  178. /*=============================================
  179. = 功能:同步TM7705芯片SPI接口时序
  180. = 说明:连续发送32个1即可,不同步会发生数据错位   
  181. ==============================================*/

  182. static void TM7705_SyncSPI(void)      //同步SPI接口时序
  183. {
  184.         TM7705_CS = 0;
  185.         SPI2_ReadWriteByte(0xFF);//32个1
  186.         SPI2_ReadWriteByte(0xFF);
  187.         SPI2_ReadWriteByte(0xFF);
  188.         SPI2_ReadWriteByte(0xFF);
  189.         
  190.         TM7705_CS = 1;

  191. }
  192. /*====================================================================
  193. =功能说明: 等待内部操作完成,自校准时间较长,需要等待
  194. =参           数: 无
  195. ======================================================================*/
  196. static void TM7705_WaitDRDY(void)
  197. {
  198.         uint32_t i;
  199.         for(i = 0; i<4000000; i++)
  200.         {
  201.                 if(TM7705_DRDY == 0)
  202.                 {
  203.                         break;
  204.                 }
  205.         
  206.         }
  207.         if(i >=4000000 )
  208.         {
  209.                 LCD_ShowString(50,100,200,16,16,"TM7705 WAIT TIME OUT !!!");
  210.         
  211.         }


  212. }



  213. /*====================================================================
  214. = 功能说明: 启动自校准. 内部自动短接AIN+ AIN-校准0位,内部短接到Vref
  215.                         校准满位。此函数执行过程较长,实测约 180ms        
  216. = 形    参:  _ch : ADC通道,1或2
  217. =====================================================================*/

  218. void TM7705_CalibSelf(uint8_t _ch)
  219. {
  220.         if (_ch == 1)
  221.         {
  222.                 /* 自校准CH1 */
  223.                 SPI2_ReadWriteByte(REG_SETUP | WRITE | CH_1);        /* 写通信寄存器,下一步是写设置寄存器,通道1 */               
  224.                 SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | UNIPOLAR        |BUF_EN |FSYNC_0);/* 启动自校准 *///写设置寄存器,单极性、有缓冲、增益为1、滤波器工作、自校准
  225.                 //SPI2_ReadWriteByte(0x4C);
  226.                 TM7705_WaitDRDY();        /* 等待内部操作完成 --- 时间较长,约180ms */
  227.         }
  228.         else if (_ch == 2)
  229.         {
  230.                 /* 自校准CH2 */
  231.                 SPI2_ReadWriteByte(REG_SETUP | WRITE | CH_2);        /* 写通信寄存器,下一步是写设置寄存器,通道2 */
  232.                 SPI2_ReadWriteByte(MD_CAL_SELF | GAIN_1 | UNIPOLAR |BUF_EN |FSYNC_0);        /* 启动自校准 */
  233.                 //SPI2_ReadWriteByte(0x44);
  234.                 TM7705_WaitDRDY();        /* 等待内部操作完成  --- 时间较长,约180ms */
  235.         }


  236. }

  237. /*=====================================================================
  238. =功能说明:读到一个8位数据
  239. =参    数:返回读到的值
  240. =====================================================================*/
  241. static uint8_t TM7705_ReadByte(void)
  242. {
  243.         uint8_t read = 0;
  244.         TM7705_CS = 0;
  245.         read = SPI2_ReadWriteByte(0xFF);
  246.         TM7705_CS = 1;
  247.         
  248.         return read;
  249. }

  250. /*=====================================================================
  251. =功能说明:读到一个16位数据(半字)
  252. =参    数:返回读到16位数据的值
  253. =====================================================================*/
  254. static uint16_t TM7705_Read2Byte()
  255. {
  256.         uint16_t read = 0;
  257.         
  258.         TM7705_CS =0 ;
  259.         read = SPI2_ReadWriteByte(0xFF);
  260.         read <<=8;
  261.         read += SPI2_ReadWriteByte(0xFF);
  262.         TM7705_CS =1 ;

  263.         return read;
  264.         
  265. }

  266. /*=====================================================================
  267. =功能说明:读到一个24位数据(3字节)
  268. =参    数:返回读到24位数据的值
  269. =====================================================================*/
  270. static uint16_t TM7705_Read3Byte(void)
  271. {
  272.         uint32_t read = 0;
  273.         TM7705_CS = 0;
  274.         read = SPI2_ReadWriteByte(0xFF);
  275.         read <<=8;
  276.         read += SPI2_ReadWriteByte(0xFF);
  277.         read <<=8;
  278.         read += SPI2_ReadWriteByte(0xFF);
  279.         TM7705_CS =1 ;
  280.         
  281.         return read;
  282.         
  283. }

  284. /*=====================================================================
  285. =功能说明:读取采样电压值
  286. =参    数:返回采样值
  287. =====================================================================*/
  288. uint16_t TM7705_ReadAdc(uint8_t _ch)
  289. {
  290.         uint8_t i;
  291.         uint16_t read = 0;
  292.         
  293.         /* 为了避免通道切换造成读数失效,读2次 */
  294.         for (i = 0; i < 2; i++)
  295.         {
  296.                 TM7705_WaitDRDY();                /* 等待DRDY口线为0 */               

  297.                 if (_ch == 1)
  298.                 {
  299.                         TM7705_CS = 0;
  300.                         SPI2_ReadWriteByte(0x38);
  301.                         TM7705_CS = 1;
  302.                 }
  303.                 else if (_ch == 2)
  304.                 {
  305.                         TM7705_CS = 0;
  306.                         SPI2_ReadWriteByte(0x39);
  307.                         TM7705_CS = 1;
  308.                 }
  309.                 //TM7705_WaitDRDY();        /* 等待内部操作完成 --- 时间较长,约180ms */
  310.                 read = TM7705_Read2Byte();
  311.         }
  312.         return read;        



  313. }
复制代码



#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, 下载次数: 24)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表