本帖最后由 mftang2016 于 2024-1-18 18:35 编辑
1 驱动程序实现1)SHT20硬件接口图
file://G:/workspace/documents/%E6%8A%80%E6%9C%AF%E8%B5%84%E6%96%99/linux/Linux%20Study(Mini2440).assets/1704466900882.png?lastModify=1705556772 file://G:/workspace/documents/%E6%8A%80%E6%9C%AF%E8%B5%84%E6%96%99/linux/Linux%20Study(Mini2440).assets/1704466918987.png?lastModify=1705556772 2) 代码实现 在drv-sht20.c中实现驱动程序,使用系统自带I2C-0接口,编写驱动代码
- #include "drv-sht20.h"
- /******************************************************************************
- * LOCAL MACROS AND DEFINITIONS
- ******************************************************************************/
- #define SHT2X_ADDR 0x40
- #define POLY 0x131 //P(x)=x^8+x^5+x^4+1 = 100110001
- #define DELAY_CNT 4500 //for , sleep time is 6.4 ms
- #define DEV_FILE "/dev/i2c/0"
- #define QUERY_TEMP_CMD TRIG_T_MEASUREMENT_POLL
- #define QUERY_HUMIDY_CMD TRIG_RH_MEASUREMENT_POLL
- static int public_fd;
- static void msleep(unsigned int time)
- {
- struct timespec sleeper, temp;
- sleeper.tv_sec = (time_t)(time/1000);
- sleeper.tv_nsec = (long)(time%1000)*1000000;
- nanosleep(&sleeper, &temp);
- }
- static int sht2xdrv_CheckCrc(unsigned char data[], unsigned char nbrOfBytes, unsigned char checksum)
- {
- int set = 0;
- unsigned char crc = 0;
- unsigned char byteCtr;
- unsigned char bit;
-
- //calculates 8-Bit checksum with given polynomial
- for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
- {
- crc ^= (data[byteCtr]);
- for ( bit = 8; bit > 0; --bit)
- {
- if (crc & 0x80)
- {
- crc = (crc << 1) ^ POLY;
- }
- else
- {
- crc = (crc << 1);
- }
- }
- }
- if (crc != checksum)
- {
- set = -1;
- }
- return set;
- }
- static int sht2xdrv_CalcTemperatureC(unsigned short u16sT)
- {
- int temperatureC; // variable for result
- u16sT &= ~0x0003; // clear bits [1..0] (status bits)
- /*
- * Formula T = -46.85 + 175.72 * ST / 2^16 from data sheet 6.2,
- * optimized for integer fixed point (3 digits) arithmetic
- */
- temperatureC = ((17572 * u16sT) >> 16) - 4685;
- return temperatureC;
- }
- static int sht2xdrv_CalcRH(unsigned short u16sRH)
- {
- int humidityRH; // variable for result
- u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
- /*
- * Formula RH = -6 + 125 * SRH / 2^16 from data sheet 6.1,
- * optimized for integer fixed point (3 digits) arithmetic
- */
- humidityRH = ((12500 * u16sRH) >> 16) - 600;
- return humidityRH;
- }
- static int sht2x_send_cmd_wr( unsigned cmd)
- {
- int ret = -1;
- unsigned char buf[2] = {0};
- switch (cmd)
- {
- case QUERY_TEMP_CMD:
- buf[0] = QUERY_TEMP_CMD;
- ret = write(public_fd, buf, 1);
- if( ret < 0 )
- {
- printf("write temper cmd to sht2x failure.\n");
- return -1;
- }
- msleep(85); //datasheet typ=66, max=85
- break;
- case QUERY_HUMIDY_CMD:
- buf[0] = QUERY_HUMIDY_CMD;
- ret = write(public_fd, buf, 1);
- if( ret < 0 )
- {
- printf("write humidity cmd to sht2x failure.\n");
- return -1;
- }
- msleep(29); //datasheet typ=22, max=29
- break;
- default:
- return -1;
- }
- return 0;
- }
- int sht2x_init(void)
- {
- int fd = -1;
-
- fd = open(DEV_FILE, O_RDWR);
- if( fd < 0 )
- {
- close( fd );
- printf("%s %s i2c device open failure: %s\n", __FILE__, __FUNCTION__, strerror(errno));
- return -1;
- }
- ioctl(fd, I2C_TENBIT, 0);
- ioctl(fd, I2C_SLAVE, SHT2X_ADDR);
- public_fd = fd;
- return fd;
- }
- int sht2x_softreset( void )
- {
- int ret = -1;
- unsigned char buf[2] = {0};
- unsigned char cmd = SOFT_RESET;
-
- buf[0] = cmd;
- ret = write(public_fd, buf, 1);
- if( ret < 0 )
- {
- printf("%s %s write softrest cmd to sht2x failure \n", __FILE__, __FUNCTION__);
- return -1;
- }
- msleep(50);
- return 0;
- }
- int sht2x_get_tempeture( float *temper)
- {
- unsigned char buf[4] = {0}, checksum;
- int ret = -1;
- int tempval;
- ret = sht2x_send_cmd_wr( QUERY_TEMP_CMD);
- if( ret < 0 )
- {
- return -1;
- }
- ret = read(public_fd, buf, 3);
- if( ret < 0 )
- {
- printf("get the temper failure.\n");
- return -1;
- }
- // match crc here
- checksum = buf[2];
- ret = sht2xdrv_CheckCrc(buf, 2, checksum);
- if( ret < 0 )
- {
- printf("match check sum error.\n");
- return -1;
- }
- tempval = (buf[0] << 8) | buf[1];
- *temper = sht2xdrv_CalcTemperatureC( tempval );
-
- return 0;
- }
- int sht2x_get_humidy( float *humidy )
- {
- unsigned char buf[4] = {0}, checksum;
- int ret = -1;
- int tempval;
- ret = sht2x_send_cmd_wr( QUERY_HUMIDY_CMD );
- if( ret < 0 )
- {
- return -1;
- }
- ret = read(public_fd, buf, 3);
- if( ret < 0 )
- {
- printf("get the humidy failure.\n");
- return -1;
- }
- // match crc here
- checksum = buf[2];
- ret = sht2xdrv_CheckCrc(buf, 2, checksum);
- if( ret < 0 )
- {
- printf("match check sum error.\n");
- return -1;
- }
- tempval = (buf[0] << 8) | buf[1];
- *humidy = sht2xdrv_CalcRH( tempval );
-
- return 0;
- }
- int sht2x_open( void )
- {
- int set;
- set = sht2x_init();
- if( set < 0 ){
- return -1;
- }
- set = sht2x_softreset();
- if( set < 0 ){
- return -1;
- }
- return 0;
- }
- int sht2x_release( void )
- {
- close( public_fd );
- return 0;
- }
复制代码
头文件部分定义参数和引用
- #ifndef __DRV_SHT20_H
- #define __DRV_SHT20_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <linux/types.h>
- #include <linux/i2c-dev.h>
- #include <linux/i2c.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <linux/fs.h>
- #include <errno.h>
- #include <assert.h>
- #include <string.h>
- #include <time.h>
- typedef enum sht2xOptErrorCode
- {
- SHT2x_RES_I2C_ERR = 0X01,
- }sht2xOptErrorCode;
- /******************************************************************************
- * EXPORTED MACROS AND DEFINITIONS
- ******************************************************************************/
- typedef enum sht2xResolution_t
- {
- SHT2x_RES_12_14BIT = 0x00, // RH=12bit, T=14bit
- SHT2x_RES_8_12BIT = 0x01, // RH= 8bit, T=12bit
- SHT2x_RES_10_13BIT = 0x80, // RH=10bit, T=13bit
- SHT2x_RES_11_11BIT = 0x81, // RH=11bit, T=11bit
- SHT2x_RES_MASK = 0x81 // Mask for res. bits (7,0) in user reg.
- } sht2xResolution_t;
- typedef enum sht2xStatusCode {
- SHT2x_STATUS_OK = 0x00,
- SHT2x_STATUS_VALID_DATA = 0x01,
- SHT2x_STATUS_NO_CHANGE = 0x02,
- SHT2x_STATUS_ABORTED = 0x03,
- SHT2x_STATUS_BUSY = 0x04,
- SHT2x_STATUS_SUSPEND = 0x05,
- SHT2x_STATUS_ERR_IO = 0x06,
- SHT2x_STATUS_ERR_BAD_DATA = 0x07,
- SHT2x_STATUS_ERR_TIMEOUT = 0x08
- }sht2xStatusCode;
- // sensor command
- typedef enum{
- TRIG_T_MEASUREMENT_HM = 0xE3, // command trig. temp meas. hold master
- TRIG_RH_MEASUREMENT_HM = 0xE5, // command trig. humidity meas. hold master
- TRIG_T_MEASUREMENT_POLL = 0xF3, // command trig. temp meas. no hold master
- TRIG_RH_MEASUREMENT_POLL = 0xF5, // command trig. humidity meas. no hold master
- USER_REG_W = 0xE6, // command writing user register
- USER_REG_R = 0xE7, // command reading user register
- SOFT_RESET = 0xFE // command soft reset
- }sht2xCommand_t;
- typedef enum {
- SHT2x_EOB_ON = 0x40, // end of battery
- SHT2x_EOB_MASK = 0x40, // Mask for EOB bit(6) in user reg.
- } sht2xEob_t;
- typedef enum {
- SHT2x_HEATER_ON = 0x04, // heater on
- SHT2x_HEATER_OFF = 0x00, // heater off
- SHT2x_HEATER_MASK = 0x04, // Mask for Heater bit(2) in user reg.
- } etSHT2xHeater;
- // measurement signal selection
- typedef enum{
- HUMIDITY,
- TEMP
- }etSHT2xMeasureType;
- typedef enum{
- I2C_ADR_W = 128, // sensor I2C address + write bit
- I2C_ADR_R = 129 // sensor I2C address + read bit
- }etI2cHeader;
- typedef struct {
- unsigned char _step;
- unsigned char ret;
-
- unsigned char finish; //1: finished, 0: idle
- unsigned char dataValid; //1: valid, 0: invalid
-
- int _tryCnt;
- int _binValue; // primordial value from sht20 register
- int outValue; // true temperature or humidity
- } shtdrv;
- typedef struct {
- shtdrv st_Temp;
- shtdrv st_RH;
- int errorCode;
- }shtOpt;
- int sht2x_open( void );
- int sht2x_get_humidy( float *humidy );
- int sht2x_get_tempeture( float *temper);
- int sht2x_release( void );
- #ifdef __cplusplus
- }
- #endif
- #endif /* __DRV_SHT20_H */
复制代码
2 测试代码实现实现功能,读取温度和湿度数据,并通过调试终端打印数据 1) 测试代码 - #include <sys/types.h>
- #include <sys/stat.h>
- #include <linux/types.h>
- #include <linux/i2c-dev.h>
- #include <linux/i2c.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <linux/fs.h>
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <assert.h>
- #include <string.h>
- #include <time.h>
- #include "drv-sht20.h"
- int main(void)
- {
- float temper, rh;
- int count_run = 100;
- int set;
- set = sht2x_open();
- if( set < 0){
- printf("initial sht20 failure.\n");
- return -1;
- }
- while( count_run > 0){
- set = sht2x_get_tempeture( &temper );
- if(set > -1)
- {
- printf( "TM(C): %.2f ", temper*0.01);
- }
- set = sht2x_get_humidy( &rh );
- if(set > -1)
- {
- printf("HM(\%): %.2f \r\n", rh*0.01);
- }
- count_run--;
- }
- sht2x_release();
- return 0;
- }
复制代码2)Makefile文件 - CFLAGS= -Wall -O2
- CC=arm-linux-gcc
- test-sht20: test-sht20.o drv-sht20.o
- $(CC) $(CFLAGS) -o test-sht20 test-sht20.o drv-sht20.o
- arm-linux-strip -s test-sht20
- clean:
- rm -f test-sht20 test-sht20.o drv-sht20.o
复制代码
3 测试实验编译代码,通过NFS传送到开发板上
|