打印
[经验知识]

通过spidev0.0驱动及MAX31855芯片采集K型热电偶温度

[复制链接]
653|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 maximQ820270087 于 2020-5-3 12:40 编辑

通过spidev0.0驱动及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℃精度。

MAX31855与MCU或MPU接线图:

SPI通讯时序图:


驱动CS为低电平时,SO引脚将输出第一位数据。通过串口读取完整的冷端补偿热电偶温度,需要14个时钟周期。读取热电偶和参考端温度需要32个时钟(表2和表3)。在时钟下降沿读取输出位。第一位D31为热电偶温度符号位。D[30:18]位包含温度转换数据,顺序为MSB至LSB。D16位正常状态下为低电平,热电偶输入开路或对GND或VCC短路时变为高电平。参考端温度数据从D15开始。输出转换数据时,CS任何时候均可变为高电平。
根据以上描述,将上述时序、数据位的含义转换为后续的程序代码。

2. 硬件环境搭建
根据第一节对MAX31855引脚的功能描述,将K型热电偶、MAX31855、Nanopi M2用杜邦线连起来。

MAX31855实物图:

MAX31855连接K型热电偶:
Nanopi M2的SPI0接口如下(3.3V,GND,MISO,CLK,CS共5根线):


K型热电偶、MAX31855和Nanopi M2硬件连接:


3. 基于QTK型热电偶SPI接口数据采集软件开发
3.1 创建QT项目
在命令行输入如下命令:
su root
password:fa
qtcreator
启动QT软件开发环境,新建项目,项目名称我选为max31855_temperatureShow,软件类型设置widget,设计界面如图所示:



3.2 编写头文件
1common.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 <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <pthread.h>
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);
#define FILE_PATH_LENGTH           (128)
#endif
2libfahw-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
3libfahw-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的驱动,如图所示:


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

219

帖子

1

粉丝