总共6个字节
湿度和温度数据将始终以以下方式传输:第一个值是温度信号(2 * 8位数据+ 8位CRC),第二个值是湿度信号(2 * 8位数据+ 8位CRC)。
unsigned char cal_table_high_first(unsigned char value)
{
unsigned char i, crc;
crc = value;
/* 数据往左移了8位,需要计算8次 */
for (i=8; i>0; --i)
{
if (crc & 0x80) /* 判断最高位是否为1 */
{
/* 最高位为1,不需要异或,往左移一位,然后与0x31异或 */
/* 0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉 */
crc = (crc << 1) ^ 0x31; }
else
{
/* 最高位为0时,不需要异或,整体数据往左移一位 */
crc = (crc << 1);
}
}
return crc;
}
unsigned char crc_high_first(unsigned char *ptr, unsigned char len)
{
unsigned char i;
unsigned char crc=0x00; /* 计算的初始crc值 */
while(len--)
{
crc ^= *ptr++; /* 每次先与需要计算的数据异或,计算完指向下一数据 */
for (i=8; i>0; --i) /* 下面这段计算过程与计算一个字节crc一样 */
{
if (crc & 0x80)
crc = (crc << 1) ^ 0x31;
else
crc = (crc << 1);
}
}
return (crc);
}
立创商城搜索对应的原件看对应的数据手册
#ifndef __IICTEST_H
#define __IICTEST_H
#ifdef __cplusplus
extern "C"{
#endif
#include "delay.h"
#include "stm32f4xx.h"
//IO方向设置产考F4手册
/**********************************begin**************************************/
#define SDA_In() {GPIOC->MODER&=~(3<<(7*2));GPIOC->MODER|=0<<7*2;}
#define SDA_Out() {GPIOC->MODER&=~(3<<(7*2));GPIOC->MODER|=1<<7*2;}
/**********************************end************************************/
#define IIC_SCL_PIN GPIO_Pin_6
#define IIC_SDA_PIN GPIO_Pin_7
#define IIC_GPIO_PORT GPIOC
#define Delay_ms(x) delay_ms(x)
#define Delay_us(x) delay_us(x)
//IO操作函数
#define IIC_Scl(a) GPIO_WriteBit(IIC_GPIO_PORT, IIC_SCL_PIN, a)
#define IIC_Sda(a) GPIO_WriteBit(IIC_GPIO_PORT, IIC_SDA_PIN, a)
#define READ_Sda GPIO_ReadInputDataBit(IIC_GPIO_PORT, IIC_SDA_PIN)
//IIC所有操作函数
void IIC_Init_S(uint32_t RCC_CLK); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(uint8_t txd); //IIC发送一个字节
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
uint8_t IIC_Wait_Ack(void); //IIC等待ACK信号
uint8_t IIC_Read_B(uint8_t ack); //IIC读取一个字节
uint32_t IIC_Read_Byte(uint8_t ack,uint8_t* recvdata,uint8_t num);//IIC读取n个字节
#ifdef __cplusplus
}
#endif
#endif
#include "iictest.h"
/*----------------------------------*/
/* */
/* 初始化IIC */
/* */
/*----------------------------------*/
void IIC_Init_S(uint32_t RCC_CLK)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd( RCC_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN|IIC_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(IIC_GPIO_PORT, &GPIO_InitStructure);
GPIO_SetBits(IIC_GPIO_PORT,IIC_SCL_PIN|IIC_SDA_PIN);
}
/*----------------------------------*/
/* */
/* 产生IIC起始信号 */
/* */
/*----------------------------------*/
void IIC_Start(void)
{
SDA_Out();
IIC_Sda(1);
IIC_Scl(1);
Delay_us(4);
IIC_Sda(0);
Delay_us(4);
IIC_Scl(0);
}
/*----------------------------------*/
/* */
/* 产生IIC停止信号 */
/* */
/*----------------------------------*/
void IIC_Stop(void)
{
SDA_Out();
IIC_Scl(0);
IIC_Sda(0);
Delay_us(4);
IIC_Scl(1);
IIC_Sda(1);
Delay_us(2);
}
/*----------------------------------*/
/* */
/* 等待应答 */
/* 返回值 1:接收应答失败 */
/* 0:接收应答成功 */
/*----------------------------------*/
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_In();
IIC_Sda(1);Delay_us(1);
IIC_Scl(1);Delay_us(1);
while(READ_Sda)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_Scl(0);
return 0;
}
/*----------------------------------*/
/* */
/* 产生ACK应答 */
/* */
/*----------------------------------*/
void IIC_Ack(void)
{
IIC_Scl(0);
SDA_Out();
IIC_Sda(0);Delay_us(2);
IIC_Scl(1);Delay_us(2);
IIC_Scl(1);
}
/*----------------------------------*/
/* */
/* 不产生ACK应答 */
/* */
/*----------------------------------*/
void IIC_NAck(void)
{
IIC_Scl(0);
SDA_Out();
IIC_Sda(1);Delay_us(2);
IIC_Scl(1);Delay_us(2);
IIC_Scl(1);
}
/*----------------------------------*/
/* */
/* IIC发送一个字节 */
/* @txd: 要发送的数据 */
/* 返回值:1,有应答 */
/* 0,无应答 */
/*----------------------------------*/
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_Out();
IIC_Scl(0);
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
IIC_Sda(1);
else
IIC_Sda(0);
txd<<=1;
Delay_us(2);
IIC_Scl(1);
Delay_us(2);
IIC_Scl(0);
Delay_us(2);
}
}
/*----------------------------------*/
/* */
/* IIC读取连续2个字节 */
/* 返回值:接收到的数据 */
/* @ ack: 1
,需要应答 */
/* 0,不需要应答 */
/*----------------------------------*/
uint32_t IIC_Read_Byte(uint8_t ack,uint8_t* recvdata,uint8_t num)
{
uint32_t data=0;
while(num--)
{
*recvdata++ = IIC_Read_B(ack);
}
return data;
}
uint8_t IIC_Read_B(uint8_t ack)
{
unsigned char i;
uint8_t receive;
SDA_In();
for(i=0;i<8;i++)
{
IIC_Scl(0);
Delay_us(2);
IIC_Scl(1);
receive<<=1;
if(READ_Sda)
receive++;
Delay_us(1);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
#ifndef __SHT1000_H
#define __SHT1000_H
#include "delay.h"
#include "iictest.h"
void SHT45_Init(void);
uint8_t SHT45_ReadPdata(uint8_t ack,uint8_t *arr,float* T,float* H );
extern uint32_t SHT45_Data1[2];
#endif
#include "SHT1000.h"
uint32_t SHT45_Data1[2]={0};
void SHT45_Init(void) //初始化IIC PC6:SCL PC7:SDA
{
IIC_Init_S(RCC_AHB1Periph_GPIOC);
}
/* 读取压力数据寄存器*/
uint8_t SHT45_ReadPdata(uint8_t ack,uint8_t *arr,float* T,float* H )
{
int32_t CRC1=0XFF;
int32_t CRC2=0XFF;
//开启温度转换
IIC_Start();
IIC_Send_Byte (0x88); //0x44 <<1 +0
delay_us(2);
while(IIC_Wait_Ack ()!=0){};
IIC_Send_Byte (0xFD);
while(IIC_Wait_Ack ()!=0){};
IIC_Stop();
delay_ms(10);
//读取温度
IIC_Start();
IIC_Send_Byte (0x89); //0x44 <<1 +1
delay_us(2);
while(IIC_Wait_Ack()!=0){};
IIC_Read_Byte(ack,arr,6);
IIC_Stop();
SHT45_Data1[0] =arr[0]<<8|arr[1];
*T = (-45 + 175*(SHT45_Data1[0])/65535.0);
CRC1= arr[2];
SHT45_Data1[1] =arr[3]<<8|arr[4];
*H =(-6 + 125 *( SHT45_Data1[1])/65535.0);
CRC2= arr[5];
return 1;
}
uint8_t arr[6]={0};
float T,H;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
SHT45_Init();
delay_us(2);
while(1)
{
delay_ms(1000);
SHT45_ReadPdata(1,arr,&T,&H);
printf("T:%f....H:%f\r\n",T,H);
}
}