各位大神,如果这个有人能帮我解决,我真就服了,(可以找我拿福利867051287,请吃早餐也可以20块以下)我已经看了有4天的代码,改了又改,还是只读出FF。我只能怀疑是别的问题了 ,大家谁觉得对SHT10非常了解的,帮帮我看看时序方面,还有就是我的延时是不是有问题。
#include <iostm8s003f3.h>
//#include "stm8s.h"
//#define UART1_R_OR_vector 0x14
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
#define u8 unsigned char
#define u16 unsigned short int
#define iic_SCL PB_ODR_ODR4
#define iic_SDA PB_ODR_ODR5
#define DATA_H() PB_ODR_ODR5=1
#define DATA_L() PB_ODR_ODR5=0
#define SCK_H() PB_ODR_ODR4=1
#define SCK_L() PB_ODR_ODR4=0
#define SHT10_DATA_IN() {PB_DDR&=~BIT(5)B_CR1|=BIT(5)B_CR2&=~BIT(5);} //010 上拉输入
#define SHT10_DATA_OUT() {PB_DDR|=BIT(5)B_CR1|=BIT(5)B_CR2&=~BIT(5);} //110 推挽输出
u8 check_num[1] = {0};// 存放从 SHT10 所读取到的 CRC 校验值
#define SCK_SETOUTPUT {PB_DDR|=BIT(4)B_CR1|= BIT(4)B_CR1&=~BIT(4);} //110 推挽输出
#define DATA() (PB_ODR&0x10) //?是不是这个呢 SDA为PB5
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
#define TEMP 0
#define HUMI 1
u8 temperature,humidity;
u8 t[2];
void CLK_Init()
{
CLK_CKDIVR_HSIDIV =0; // 设置成 fHSI/1 =16MHz
CLK_CKDIVR_CPUDIV =0;
}
void delay_us(int us)
{
int z;
for(z=0;z<us;z++)
{
while(0);
// while(0);
}
}
/***********************
函数功能:us延时
输入参数:无
输出参数:无
备 注:粗略延时
***********************/
void Init_UART1(void)
{
UART1_CR1=0x00;
UART1_CR2=0x00;
UART1_CR3=0x00;
// 设置波特率,必须注意以下几点:
// (1) 必须先写BRR2
// (2) BRR1存放的是分频系数的第11位到第4位,
// (3) BRR2存放的是分频系数的第15位到第12位,和第3位
// 到第0位
// 例如对于波特率位9600时,分频系数=2000000/9600=208
// 对应的十六进制数为00D0,BBR1=0D,BBR2=00
UART1_BRR2=0x02;
UART1_BRR1=0x68; //16MH的设置
UART1_CR2=0x2c;//允许接收,发送,开接收中断
}
void UART1_sendchar(u8 c)
{
while((UART1_SR & 0x80)==0x00);
UART1_DR=c;
}
void uart_printf(unsigned char *buff)
{
while(*buff!='\0')
UART1_sendchar(*buff++);
}
//通讯这里开始
//启动信号
void SHT10_Start(void)
{
SHT10_DATA_OUT();
SCK_SETOUTPUT;
SCK_L();
DATA_H();
delay_us(1);
SCK_H();
delay_us(1);
DATA_L();
delay_us(1);
SCK_L();
delay_us(5); //这个地方有人设置为3us,但是手册说要大于4.7us啊
SCK_H();
delay_us(1);
DATA_H();
delay_us(1);
SCK_L();
}
/********************************************************************************
* 函数名 :SHT10_ConnectionReset
* 描述 :SHT10 通讯中断时复位,状态寄存器内容任然保留
* 输入参数 : 无
* 输出结果 :无
* 返回值 :无
********************************************************************************/
void SHT10_ConnectionReset(void) //这个函数我没用,我只想简单的读写先
{
u8 i;
SHT10_DATA_OUT();
DATA_H();
SCK_L();
for( i=0; i<9; i++ )
{
SCK_H();
delay_us(1);
SCK_L();
delay_us(1);
}
SHT10_Start();
}
//写入一个字节的命令,并且检查传感器是否正确接收了这个数据,返回值为0表示正确接收
//*******************************
u8 SHT10_WriteByte(u8 value)
{
u8 i, err = 0;
SHT10_DATA_OUT();
//数据处理,将8位的数据value按位一步步写入到芯片中
for( i=0x80; i>0; i/=2 )
{
if( i & value )
{
DATA_H();
}
else
{
DATA_L();
}
SCK_H();
delay_us(5); //延时多少好呢?
SCK_L();
}
DATA_H();
SCK_H();
SHT10_DATA_IN();
err = DATA()?1:0;//在第 9 个时钟上升沿读取 SHT10 的 DATA 的数据,为低电平则说明:已正确的接收到指令
SCK_L();
return err;
}
//********************************************
//读一个字节的数据,并且向传感器发出一个字节的“已接收”信号
//********************************************
u8 SHT10_ReadByte(u8 ack)
{
u8 i, val=0x00;
DATA_H();
//SHT10_DATA_IN();
//读八个字节的数据,SCK 高电平时读出 SHT10 的数据,读完后给 SCK 一个低电平,之后读下一位
SHT10_DATA_IN();
for( i=0x80;i>0;i>>=1 )
{
SCK_H();
//?是否要呢
if( DATA() ) //这个地方DATA()永远等于1,所以只发送FF,为什么没有0的时候呢
{
val = ( val | i );
}
else
PA_ODR_ODR3= ~PA_ODR_ODR3;
delay_us(5);
SCK_L();
}
//判断是否结束通信,并输出相应电平
SHT10_DATA_OUT();
if(ack)
DATA_L();
else
DATA_H();
//需要重新给 SHT10 一个低电平以确保 DATA 输出有效
SCK_H();
delay_us(5);
DATA_H();
SCK_L();
return val;
}
/********************************************************************************
* 函数名 :SHT10_Measure
* 描述 :SHT10 温度或湿度初始值读取
* 输入参数 : u8* pValue 指向温度或湿度初始值
* u8* pCheckSum 指向 CRC 校验值
* u8 mode 选择需要读取温度值还是湿度值,TEMP表示温度,HUMI表示湿度
* 输出结果 :无
* 返回值 :读取成功则返回 0 ,不成功则返回1
********************************************************************************/
u8 SHT10_Measure( u8 *pchecksum, u8 mode )
{
u8 er=0,i;
SHT10_Start(); //启动传输
switch(mode) //发送开始测量命令
{
case 0 : SHT10_WriteByte(MEASURE_TEMP); break;
case 1 : SHT10_WriteByte(MEASURE_HUMI); break;
default : break;
}
SHT10_DATA_IN();
for(i=0;i<10;i++)
delay_us(30000);
while(DATA());
//DATA_L();
//SHT10_DATA_OUT();
//读取两个字节的数据
t[0]=SHT10_ReadByte(1);
t[1]=SHT10_ReadByte(1);
*pchecksum=SHT10_ReadByte(noACK );
return er;
}
void main(void)
{
u8 error,pchecksum;
PA_DDR|= BIT(3);
PA_CR1|= BIT(3);
Init_UART1();
CLK_Init();
while(1)
{
error=0;
error+= SHT10_Measure(&pchecksum,0);
// humi = s_measure(HUMI);
// calc_sth11(&humi,&temp);
/*
SHT10_ConnectionReset();
if(error!=0)
{
SHT10_ConnectionReset();
delay_ms(500);
continue;
}*/
// temperature=(u16)(((t[0]<<8)+t[1])*0.01-40);
//UART1_sendchar( temperature);
UART1_sendchar(t[1]);
UART1_sendchar(t[0]); //这俩个输出都是FF
}
}
转载
|