源程序来自“金属狂人”贴的,但是程序不全,我稍加整理写了一下,以前用51单片机做开发时候,用过这个,程序没问题,但是现在改用LM3S开发,经过整理读出数据错误(见截图)
特将两个程序都贴上,请高手指点,一个是51驱动,一个LM3S1651驱动。51驱动的程序是对的,产品公司已经卖出好多了。
/*************************************************************************************
文件名:LM3S
文件功能:驱动温湿度传感器
*************************************************************************************/
#include "hw_i2c.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "gpio.h"
#include "i2c.h"
#include "interrupt.h"
#include "sysctl.h"
#include "sht10.h"
#include "uart.h"
//1、宏定义,SDA接到PB3,SCL接到PB2上。
#define SHT1x_SDA_SYSCTL SYSCTL_PERIPH_GPIOB
#define SHT1x_SDA_GPIO_PORT GPIO_PORTB_BASE
#define SHT1x_SDA_PIN GPIO_PIN_3
#define SHT1x_SCL_SYSCTL SYSCTL_PERIPH_GPIOB
#define SHT1x_SCL_GPIO_PORT GPIO_PORTB_BASE
#define SHT1x_SCL_PIN GPIO_PIN_2
//控制命令,SHT1x地址位均为 000 地址位 命令 R/W
#define SHT1x_CMD_STATUS_REG_W 0x06 //000 0011 0
#define SHT1x_CMD_STATUS_REG_R 0x07 //000 0011 1
#define SHT1x_CMD_GET_TEMP 0x03 //000 0001 1
#define SHT1x_CMD_GET_HUMI 0x05 //000 0010 1
#define SHT1x_CMD_RESET 0x1E //000 1111 0
//ACK为低电平有效
#define SHT1x_ACK_YES 0x01
#define SHT1x_ACK_NO 0x00
#define SHT1x_CALC_TEMP 0x01
#define SHT1x_CALC_HUMI 0x02
//===============================================================
int test;
unsigned short test2;
unsigned char test3;
int iHumi,iTemp;
unsigned char checkSum;
float fTempVal,fHumiVal; //定义的浮点型温湿度的值
//=========================
void delay_sht1x_bus(unsigned int z)
{
unsigned int x;//,y;
for(x=z;x>0;x--);
// for(y=1; y>0; y--);
}
//设置SDA为输出
static void set_sht1x_sda_output(void)
{
GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT); //SDA为输出管脚,推挽
GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
}
//设置SDA为输入
static void set_sht1x_sda_input(void)
{
GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_IN); //SDA为输入管脚,推挽
GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
}
//====================================================================
//IO初始化
void init_sht1x_dev_pin(void)
{
SysCtlPeripheralEnable(SHT1x_SDA_SYSCTL); //使能GPIOB
GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT); //将PB3设为输出
GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); //推挽。2mA驱动
SysCtlPeripheralEnable(SHT1x_SCL_SYSCTL); //使能GPIOB
GPIODirModeSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_DIR_MODE_OUT); //将PB2设为输出
GPIOPadConfigSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); //推挽,4mA驱动
set_sht1x_sda_output(); //将SDA设为输出
}
//======================================================================
//设置SCL为0或1
static void set_sht1x_scl(char flag)
{
if (0 == flag)
{
GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, ~SHT1x_SCL_PIN);
}
else if (1 == flag)
{
GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, SHT1x_SCL_PIN);
}
}
//=====================================================================
//设置DSA为0或1
static void set_sht1x_sda(char flag)
{
if (0 == flag)
{
GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN);
}
else if (1 == flag)
{
GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, SHT1x_SDA_PIN);
}
}
//============================================================================
//启动传感器
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
void start_sht1x_op(void)
{
//初始状态
set_sht1x_sda(1); delay_sht1x_bus(1);
set_sht1x_scl(0); delay_sht1x_bus(1);
//第一个时钟上升沿后数据变为低
set_sht1x_scl(1); delay_sht1x_bus(1);
set_sht1x_sda(0); delay_sht1x_bus(1);
//时钟下降沿后时钟上升沿
set_sht1x_scl(0); delay_sht1x_bus(1);
set_sht1x_scl(1); delay_sht1x_bus(1);
//数据变为高,时钟下降沿
set_sht1x_sda(1); delay_sht1x_bus(1);
set_sht1x_scl(0); delay_sht1x_bus(1);
}
//=====================================================================
////读取SDA,返回值为读取结果
static int read_sht1x_sda(void)
{
int proc_result = -1;
unsigned char tmp_data;
set_sht1x_sda_input();
tmp_data = GPIOPinRead(SHT1x_SDA_GPIO_PORT,SHT1x_SDA_PIN);
// if (SHT1x_SDA_PIN == tmp_data) //======================================???约等于1==tmp_data
if(1== tmp_data)
{
proc_result = 1;
}
else
{
proc_result = 0;
}
set_sht1x_sda_output();
return (proc_result);
}
//=====================================================================
//写一字节,
//入口函数为要写入的数据,返回值为ACK信号,是否正确写入数据
int write_sht1x_byte(unsigned char indata)
{
int proc_result = -1;
int i;
unsigned char in_data;
in_data=indata;
for (i = 0; i < 8; i++)
{
if (0x80 == (in_data & 0x80))
{
//High
set_sht1x_sda(1);
}
else
{
set_sht1x_sda(0);
}
delay_sht1x_bus(1);
in_data = (in_data << 1); //左移一位
set_sht1x_scl(1);
delay_sht1x_bus(1);
set_sht1x_scl(0);
}
//释放总线
set_sht1x_sda(1);
//给出上升沿,读入ACK
set_sht1x_scl(1);
proc_result = read_sht1x_sda();
if (1 == proc_result)
{
//无效ACK信号
proc_result = -1;
}
set_sht1x_scl(0);
return (proc_result);
}
//==============================================================================
//读一字节
//ack暂时为无效入口函数,返回值为ack信号
int read_sht1x_byte(unsigned char *p_out_data,unsigned char ack)
{
int proc_result = -1;
int i;
unsigned char tmp_data;
tmp_data = 0x00;
for (i = 0; i < 8; i++)
{
tmp_data = (tmp_data << 1);
set_sht1x_scl(1);
delay_sht1x_bus(1);
proc_result = read_sht1x_sda();
if (1 == proc_result)
{
tmp_data |= 0x01;
}
set_sht1x_scl(0);
delay_sht1x_bus(1);
}
*p_out_data = tmp_data;
proc_result = read_sht1x_sda();
if (1 == proc_result)
{
//没有ACK信号
proc_result = -1;
}
//释放总线
set_sht1x_scl(1);delay_sht1x_bus(1);
set_sht1x_scl(0);delay_sht1x_bus(1);
set_sht1x_sda(1);delay_sht1x_bus(1);
return (proc_result);
}
/*
//=====================================================================
//读SHT11状态
int read_sht1x_status(unsigned char *p_value,unsigned char *p_checksum)
{
int proc_result = -1;
unsigned char read_st,read_checksum;
//启动操作
start_sht1x_op();
//写入读取命令
proc_result = write_sht1x_byte(SHT1x_CMD_STATUS_REG_R);
//读取状态
proc_result = read_sht1x_byte(&read_st,SHT1x_ACK_YES);
//读取校验值
proc_result = read_sht1x_byte(&read_checksum,SHT1x_ACK_NO);
*p_value = read_st;
*p_checksum = read_checksum;
return (proc_result);
}
//=====================================================================
//写SHT11状态
int write_sht1x_status(unsigned char value)
{
int proc_result = 0;
//启动操作
start_sht1x_op();
proc_result += write_sht1x_byte(SHT1x_CMD_STATUS_REG_W);
proc_result += write_sht1x_byte(value);
return (proc_result);
}
//====================================================================
//SHT11复位
void reset_sht1x_connect(void)
{
int i;
set_sht1x_sda(1);delay_sht1x_bus(1);
set_sht1x_scl(0);delay_sht1x_bus(1);
for (i = 0; i < 9; i++) {
set_sht1x_scl(1);delay_sht1x_bus(1);
set_sht1x_scl(0);delay_sht1x_bus(1);
}
start_sht1x_op();
}
//=====================================================================
//软件复位
int reset_sht1x_software(void)
{
int proc_result = -1;
reset_sht1x_connect();
proc_result = write_sht1x_byte(SHT1x_CMD_RESET); //需要11ms
return (proc_result);
}
*/
/*
//===========================================================================
//计算温湿度
//int calc_sht1x_value(int mode,t_dev_sht1x *p_this)
//int calc_sht1x_value()
int calc_sht1x_value(int mode,int *p_this)
{
int proc_result = -1;
const float T1 = 0.01;
const float T2 = 0.00008;
float c1 = -4;
float c2 = 0.0405;
float c3 = -0.0000028;
float rh;
float t;
float rh_lin;
float rh_true;
float t_c;
float logex,dew_point;
//计算温湿度
rh = p_this->humi;
t = p_this->temp;
t_c = t*0.01 - 39.6; //12bit 0.04 14bit 0.01
rh_lin = c3*rh*rh + c2*rh + c1;
rh_true = (t_c - 25)*(T1 + T2*rh) + rh_lin;
if (rh_true > 100)
{
rh_true = 100;
}
else if (rh_true < 0.1)
{
rh_true = 0.1;
}
p_this->temp_value = t_c;
p_this->humi_value = rh_true;
return (proc_result);
}
*/
//=============================================================================
//读取结果
//入口函数mode为读取温度或者湿度,pvalue为读取结果,pcheaksum为校验数据
int get_sht1x_result(int mode,unsigned char *p_value,unsigned char *p_check_sum)
{
int proc_result = 0;
int i;
static unsigned char read1,read2; //optimize
static unsigned short result_value;
//启动操作
start_sht1x_op();
//获取传感器测量数值
switch (mode)
{
case SHT1x_CALC_TEMP:
proc_result += write_sht1x_byte(SHT1x_CMD_GET_TEMP);
break;
case SHT1x_CALC_HUMI:
proc_result += write_sht1x_byte(SHT1x_CMD_GET_HUMI);
break;
default:
proc_result = -1;
break;
}
//等待测量完成
for(i = 0; i < 65535; i++)
{
delay_sht1x_bus(1);
proc_result = read_sht1x_sda(); //读取ACK位
if (0 == proc_result)
{
//得到传感器响应
break;
}
}
if (1 == proc_result)
{
//超时后传感器仍未响应
proc_result = -1;
}
read1 = 0;
read2 = 0;
proc_result += read_sht1x_byte(&read1,SHT1x_ACK_YES); //MSB 高八位数据到read1,低八位数据到read2
//read1 = (read1 & 0x0F);
proc_result += read_sht1x_byte(&read2,SHT1x_ACK_YES); //LSB
result_value = read1;
result_value = (result_value << 8);
result_value = (result_value | read2);
*p_value = result_value;
proc_result += read_sht1x_byte(&read1,SHT1x_ACK_NO);
*p_check_sum = read1;
return (proc_result);
}
//=============================================================================
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature and humidity [%RH]
// input : humi (12 bit)
// temp (14 bit)
// output: humi
// temp
{ const float C1=-4.0; // for 12 Bit
const float C2=+0.0405; // for 12 Bit
const float C3=-0.0000028; // for 12 Bit
const float T1=+0.01; // for 14 Bit @ 5V
const float T2=+0.00008; // for 14 Bit @ 5V
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [癈]
t_C=t*0.01 - 40; //calc. temperature from ticks to [癈]温度转换系数
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度的温度补偿系数calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [癈]
*p_humidity=rh_true; //return humidity[%RH]
}
void GetLast_Humi_Temp()
{
int error;
error+= get_sht1x_result(1,(unsigned char *)&iTemp,&checkSum);
error+= get_sht1x_result(2,(unsigned char *)&iHumi,&checkSum);
//此处可检测
fHumiVal=(float)iHumi; //converts integer to float整形转化成浮点型
fTempVal=(float)iTemp;
calc_sth11(&fHumiVal,&fTempVal); //calculate humidity, temperature计算实际值
iTemp=(int)(fTempVal*10);
iHumi=(int)(fHumiVal*10);
}
//==============================
void main()
{
unsigned char a,b;
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_6MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
UARTEnable(UART0_BASE);
init_sht1x_dev_pin();
while(1)
{
GetLast_Humi_Temp();
// test=0x11;
// test=get_sht1x_result(1,&test2,&test3);
// a=test/16;
// b=test%16;
UARTCharPut(UART0_BASE,a);
UARTCharPut(UART0_BASE,b);
}
}
以上为LM3S驱动,串口暂时没用。
此帖出自
小平头技术问答
一周热门 更多>