tag 标签: max6675

相关博文
  • 热度 7
    2022-5-1 20:25
    3378 次阅读|
    0 个评论
    MAX31855芯片采集K型热电偶温度经验分享
    MAX31855 芯片采集 K 型热电偶温度 本篇试用报告主要介绍如何通过 Nanopi M2 已经实现的 SPI0 驱动程序,实现用户模式下的 SPI 通讯,完成对 K 型热电偶温度数据的采集。 1.MAX31855 介绍 MAX31855 具有冷端补偿,将 K 、 J 、 N 、 T 或 E 型热电偶信号转换成数字量。器件输出 14 位带符号数据,通过 SPITM 兼容接口、以只读格式输出。转换器的温度分辨率为 0.25 ℃,最高温度读数为 +1800 ℃,最低温度读数为 -270 ℃,对于 K 型热电偶,温度范围为 -200 ℃至 +700 ℃,保持 ±2 ℃精度。 硅天下科技常备型号 : MAX31855KASA+T SOP8 2500 片 / 包 2.MAX31855 引脚、通讯模式及温度算法 2.1MAX31855 与 MCU 或 MPU 接线图: 2.2SPI 通讯时序图: 驱动 CS 为低电平时, SO 引脚将输出第一位数据。通过串口读取完整的冷端补偿热电偶温度,需要 14 个时钟周期。读取热电偶和参考端温度需要 32 个时钟周期 ( 表 2 和表 3) 。在时钟下降沿读取输出位。第一位 D31 为热电偶温度符号位。 D 位包含温度转换数据,顺序为 MSB 至 LSB 。 D16 位正常状态下为低电平,热电偶输入开路或对 GND 或 VCC 短路时变为高电平。参考端温度数据从 D15 开始。输出转换数据时, CS 任何时候均可变为高电平。 根据以上描述,将上述时序、数据位的含义转换为后续的程序代码。 3. 硬件环境搭建 根据第一节对 MAX31855 引脚的功能描述,将 K 型热电偶、 MAX31855 、 Nanopi M2 用杜邦线连起来。 MAX31855 实物图: MAX31855 连接 K 型热电偶: Nanopi M2 的 SPI0 接口如下 (3.3V,GND,MISO,CLK,CS 共 5 根线 ) : K 型热电偶、 MAX31855 和 Nanopi M2 硬件连接: 4. 基于 QT 的 K 型热电偶 SPI 接口数据采集软件开发 4.1 创建 QT 项目 在命令行输入如下命令: su root password:fa qtcreator 启动 QT 软件开发环境,新建项目,项目名称我选为 max31855_temperatureShow ,软件类型设置 widget, 设计界面如图所示: 4.2 编写头文件 1 ) common.h #ifndef _COMMON_H_ #define _COMMON_H_ #define __DEBUG #ifdef __DEBUG #define DEBUG(format, args...) \ printf("FAHW-Lib: " format, ## args) #else #define DEBUG(format, args...) #endif #include #include #include #include #include #include #include #include #include #include #include #include extern void clearLastError(); extern void setLastError(const char *fmt, ...); #define EXPORT extern int writeValueToFile(char* fileName, char* buff); extern int writeIntValueToFile(char* fileName, int value); extern int readValueFromFile(char* fileName, char* buff, int len); extern int readIntValueFromFile(char* fileName); #endif 2 ) libfahw-filectl.h #ifndef __FRIENDLYARM_HARDWARE_FILECTRL_H__ #define __FRIENDLYARM_HARDWARE_FILECTRL_H__ int openHW(const char *devName, int flags); int writeHW(int fd, const void *_data, size_t len); int readHW(int fd, void *_data, size_t len); int selectHW(int fd, int sec, int usec); void closeHW(int fd); int ioctlWithIntValue(int fd, int cmd, int value); #endif 3 ) libfahw-spi.h #ifndef __FRIENDLYARM_HARDWARE_SPI_H__ #define __FRIENDLYARM_HARDWARE_SPI_H__ // SPIBitOrder #define LSBFIRST (0) ///< LSB First #define MSBFIRST (1) ///< MSB First // SPIMode #define SPI_MODE0 (0) ///< CPOL (0, CPHA (0 #define SPI_MODE1 (1) ///< CPOL (0, CPHA (1 #define SPI_MODE2 (2) ///< CPOL (1, CPHA (0 #define SPI_MODE3 (3) ///< CPOL (1, CPHA (1 #define SPI_CPHA (0x01) #define SPI_CPOL (0x02) #define SPI_CS_HIGH (0x04) #define SPI_LSB_FIRST (0x08) #define SPI_3WIRE (0x10) #define SPI_LOOP (0x20) #define SPI_NO_CS (0x40) #define SPI_READY (0x80) // SPIClockDivider #define SPI_CLOCK_DIV65536 (0) ///< 65536 (256us (4kHz #define SPI_CLOCK_DIV32768 (32768) ///< 32768 (126us (8kHz #define SPI_CLOCK_DIV16384 (16384) ///< 16384 (64us (15.625kHz #define SPI_CLOCK_DIV8192 (8192) ///< 8192 (32us (31.25kHz #define SPI_CLOCK_DIV4096 (4096) ///< 4096 (16us (62.5kHz #define SPI_CLOCK_DIV2048 (2048) ///< 2048 (8us (125kHz #define SPI_CLOCK_DIV1024 (1024) ///< 1024 (4us (250kHz #define SPI_CLOCK_DIV512 (512) ///< 512 (2us (500kHz #define SPI_CLOCK_DIV256 (256) ///< 256 (1us (1MHz #define SPI_CLOCK_DIV128 (128) ///< 128 (500ns (= 2MHz #define SPI_CLOCK_DIV64 (64) ///< 64 (250ns (4MHz #define SPI_CLOCK_DIV32 (32) ///< 32 (125ns (8MHz #define SPI_CLOCK_DIV16 (16) ///< 16 (50ns (20MHz #define SPI_CLOCK_DIV8 (8) ///< 8 (25ns (40MHz #define SPI_CLOCK_DIV4 (4) ///< 4 (12.5ns 80MHz #define SPI_CLOCK_DIV2 (2) ///< 2 (6.25ns (160MHz #define SPI_CLOCK_DIV1 (1) ///< 0 (256us (4kHz int setSPIWriteBitsPerWord( int spi_fd, int bits ); int setSPIReadBitsPerWord( int spi_fd, int bits ); int setSPIBitOrder( int spi_fd, int order); int setSPIMaxSpeed(int spi_fd, unsigned int spi_speed); int setSPIDataMode( int spi_fd, int mode); int SPItransferOneByte( int spi_fd, unsigned char byteData, int spi_delay, int spi_speed, int spi_bits); int SPItransferBytes( int spi_fd , unsigned char * writeData , int writeLen , unsigned char * readBuffer , int readLen , int spi_delay , int spi_speed , int spi_bits ); int writeBytesToSPI( int spi_fd , unsigned char * writeData , int writeLen , int spi_delay , int spi_speed , int spi_bits ); int readBytesFromSPI( int spi_fd , unsigned char * readBuffer , int readLen , int spi_delay , int spi_speed , int spi_bits ); #define SPI0_PATH "/dev/spidev0.0" #endif 重点关注上面红颜色的那一行,代表我们使用哪个接口的驱动程序。系统目前只实现 SPI0 的驱动,如图所示:
  • 热度 3
    2021-8-9 10:02
    3080 次阅读|
    1 个评论
    MAX6675的推荐电路
    从datasheet里可以看到max6675的建议电路如下图所示: 下面是我根据经验画出的原理图: 下面来说一下为什么这样设计。 1、 电容C3,是为了滤波,添加一刻0.1uF的电容可以降低输入信号的波动; 2、 电阻R67,他是跟C3一起使用的,是为了增加响应速度。如果K+的电压降低,那么C3可以通过R67进行放电; 3、 电阻R68和电容C4、C10 是为了RC稳压,就有小朋友要问了为什么要多此一举,因为推荐电路里没这个。那么我们来看一下MAX6675的内部原理图: 可以看出一个放大电路和一个跟随电路,那么我们就有理由为MAX6675提供一个稳定的电源了,毕竟41uV/℃,轻微的电源波动都会引起测量结果的波动。 本文转自:http://www.tfmcu.com/TechnologyNews/036db855-8454-3706-13a2-5e5e58207ff3.shtml
  • 热度 23
    2014-3-17 15:37
    3685 次阅读|
    1 个评论
      2014年已经来到了3月份,这篇文章算是开年以来的第一篇文章,开始前还是先扯些别的话题吧。 首先是关于马航客机,祝愿他们平安回来,不论生命多么脆弱,为他们祈祷,为他们祝福。 周日的晚上,听着right here waiting,另一边做着永远也做不完的公务员考试题,别样的感觉。也许在一些人眼中,公务员是一份那么形式大于内容的差事,但是并不是说改变没有可能,在困难和阻碍中就蕴藏着改变世界的机会。如果你有足够的勇气和能力,那就加入这个队伍吧,你可以贡献自己的一份力量。 前不久又重新装了一次手机系统,我的电子产品们似乎产生了一种周期性的重装冲动,每每面对这样的场景,我不知道是应该用欲哭无泪来形容还是脱胎换骨来形容,其实算是兼而有之吧。重装使得我可以把过去的不太重要的事情,资料直接忘却,然后就是那些重要的部分留待解决了。比如通讯录中那些存在却不拨打的号码,比如你在记事本里面写下的不切合实际的计划和任务,夹杂一些琐事和无耻吸引注意力的细枝末节。所以,不得不说是一种好事。 好了,新年的开头第一篇,进去正题吧。 其实说到这个max6675,之前并没有概念,是在和别人合作的一个项目中碰巧用到了它,所以也就进行了一些了解,也不算是深入吧,如果有更多的兴趣,您大可以多去文库和wiki找找介绍和datasheet。不过有一点需要插进这个地方,max6675是用来测定温度的,测定温度的,你可能会想起温度传感器来,之前我接触过这个东西,比如热敏电阻,算是一种粗糙但实用的温度测量元件,只不过需要你自己去校准。max6675在这里显然更加高级了,通过自带芯片进行校准计算,最后通讯输出温度值,可以说方便而且实用。那么,仅仅如此吗?不全是,max6675多用于工业场合,或是近似于工业的场合,在一些高温,我说的是上百度的地方,这个时候就没法用普通元件或是传感器了,而且也不太准(热敏电阻可能反而会好),这里还有一个热电偶的出现,在我理解里面,相当于一个温度电压转换装置,由电偶近身接触目标,然后送回数据,给max6675处理,最后协同完成温度测定的光荣使命。 这里控制max6675的中心我用的就是闻名的arduino了,没有闻过这一名的请先绕道恶补五分钟arduino的知识。在arduino的官方网站上是有一个对应的库的,专门给max6675控制用,怎么样,很强大吧。而我在这里介绍的,就是其中的一个示例程序。下面我慢慢道来: 在一份资料中,如下: The MAX6675 performs cold-junction compensation and digitizes the signal from a type-K thermocouple. The data is output in a 12-bit resolution, SPI tm-compatible, read-only format. This converter resolves temperatures to 0.25°C, allows readings as high as +1024°C, and exhibits thermocouple accuracy of 8 LSBs for temperatures ranging from 0°C to +700°C. Key Features Cold-Junction Compensation Simple SPI-Compatible Serial Interface 12-Bit, 0.25°C Resolution Open Thermocouple Detection   讲到max6675的输出是12位的精度,那么按理应该是2的12次方的温度精度,而实际只到1024摄氏度,这是为什么呢?原来,在0摄氏度的右边还有一些空间,也就是到了0.25摄氏度,这样就是2的-2次方了,其精度就是0.25度。而通信方式在其中也提到了,就是SPI。那么现在我们如果想要得到温度值,就需要通过arduino以及SPI协议将max6675驱动起来,读出它不断送出的温度值。直接上arduino中的示例程序吧: /*   Single_Temp.pde - Example using the MAX6675 Library.   Created by Ryan McLaughlin ryanjmclaughlin@gmail.com */   #include MAX6675.h   int LED1 = 9;             // Status LED Pin int CS = 10;              // CS pin on MAX6675 int SO = 12;              // SO pin of MAX6675 int SCK = 13;             // SCK pin of MAX6675 int units = 0;            // Units to readout temp (0 = ˚F, 1 = ˚C) float error = 0.0;        // Temperature compensation error float temperature = 0.0;  // Temperature output variable     // Initialize the MAX6675 Library for our chip   MAX6675 temp0(CS0,SO,SCK,units,error);     // Setup Serial output and LED Pin   // MAX6675 Library already sets pin modes for MAX6675 chip!   void setup() {   Serial.begin(9600);   pinMode(LED1, OUTPUT); }   void loop() {   temperature = temp0.read_temp(5);         // Read the temp 5 times and return the average value to the var     if(temperature == -1) {                   // If there is an error with the TC, temperature will be -1     Serial.println("Thermocouple Error!!"); // Temperature is -1 and there is a thermocouple error     digitalWrite(LED1, HIGH);               // Turn on the status LED   } else {     Serial.print("Current Temperature: ");     Serial.println( temperature );          // Print the temperature to Serial      digitalWrite(LED1, LOW);                // Turn on the status LED   }      delay(1000); // Wait one second before reading again }     不妨再看看它的声明头文件: /*   MAX6675.h - Library for reading temperature from a MAX6675.   Created by Ryan McLaughlin ryanjmclaughlin@gmail.com */   #ifndef MAX6675_h #define MAX6675_h   #include "WProgram.h"   class MAX6675 {   public:     MAX6675(int CS_pin, int SO_pin, int SCK_pin, int units, float error);     float read_temp(int samples);   private:     int _CS_pin;     int _SO_pin;     int _SCK_pin;     int _units;     float _error; };   #endif     可以看到这里使用的是c++编程语言。将max6675的相关数据和操作都进行了很好的封装,其实在类似这样的场合,c语言才是使用的最多的语言,主要可能还是更加贴近低层的硬件吧。 在源文件中,可以看到明显的arduino编程的特点,一个是setup,还有一个是loop也就是相当于c程序中的while语句,不断的进行执行。最开始的地方进行引脚的设定,这也是推荐的一种方式,如果采用硬编码的方式进行制定,难免在后期的改变过程中引入不必要的麻烦,而且还有相当大的可能性会被改错。对照相应的数字连接arduino上的引脚,然后这里通过串口就可以读出实际的温度值了,注意,在max6675的同名构造函数中,有一个参数名叫units,这个参数是用来指定输出的温度值的单位的,别忘了设定成摄氏度哦。将程序烧写入arduino,然后就可以在arduino集成开发环境自带的串口监视器中看到实时的温度值啦。   由于这里的max6675对相关的重要操作都进行了很好的封装,难免给人一种很简单的感觉,其实,主要的spi等实现细节都在cpp文件中,如果想要研究是可以自己去好好看看的,这里贴上:     /*   MAX6675.cpp - Library for reading temperature from a MAX6675.   Created by Ryan McLaughlin ryanjmclaughlin@gmail.com */   #include WProgram.h #include MAX6675.h   MAX6675::MAX6675(int CS_pin, int SO_pin, int SCK_pin, int units, float error) {   pinMode(CS_pin, OUTPUT);   pinMode(SO_pin, INPUT);   pinMode(SCK_pin, OUTPUT);      digitalWrite(CS_pin, HIGH);      _CS_pin = CS_pin;   _SO_pin = SO_pin;   _SCK_pin = SCK_pin;   _units = units;   _error = error; }   float MAX6675::read_temp(int samples) {   int value = 0;   int error_tc = 0;   float temp = 0;     for (int i=samples; i0; i--){       digitalWrite(_CS_pin,LOW); // Enable device       /* Cycle the clock for dummy bit 15 */     digitalWrite(_SCK_pin,HIGH);     digitalWrite(_SCK_pin,LOW);       /* Read bits 14-3 from MAX6675 for the Temp         Loop for each bit reading the value and         storing the final value in 'temp'      */     for (int i=11; i=0; i--){       digitalWrite(_SCK_pin,HIGH);  // Set Clock to HIGH       value += digitalRead(_SO_pin)  i;  // Read data and add it to our variable       digitalWrite(_SCK_pin,LOW);  // Set Clock to LOW     }        /* Read the TC Input inp to check for TC Errors */     digitalWrite(_SCK_pin,HIGH); // Set Clock to HIGH     error_tc = digitalRead(_SO_pin); // Read data     digitalWrite(_SCK_pin,LOW);  // Set Clock to LOW        digitalWrite(_CS_pin, HIGH); //Disable Device   }      value = value/samples;  // Divide the value by the number of samples to get the average      /*       Keep in mind that the temp that was just read is on the digital scale      from 0˚C to 1023.75˚C at a resolution of 2^12.  We now need to convert      to an actual readable temperature (this drove me nuts until I figured       this out!).  Now multiply by 0.25.  I tried to avoid float math but      it is tough to do a good conversion to ˚F.  THe final value is converted       to an int and returned at x10 power.          */       value = value + _error; // Insert the calibration error value      if(_units == 0) { // Request temp in ˚F     temp = ((value*0.25) * (9.0/5.0)) + 32.0; // Convert value to ˚F (ensure proper floats!)   } else if(_units == 1) { // Request temp in ˚C     temp = (value*0.25); // Multiply the value by 0.25 to get temp in ˚C   }      /* Output -1 if there is a TC error, otherwise return 'temp' */   if(error_tc != 0) {     return -1;    } else {      return temp;    } }     这里的引脚驱动主要是使用的digitalwrite这个函数来实现的,当然,严格按照时序。在另一份实现中,我看到作者使用了arduino自带的SPI库,这样可能更加的方便吧,不过其实实现起来基本是一样的。好了,新年第一帖,就此结束吧。给大家拜个晚年啦。        
相关资源