F429BI测试过
//////////////
////IICD.h////
//////////////
#ifndef __IICD_H
#define __IICD_H
#include "sys.h"
#include "delay.h"
#include "usart.h"
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
//IO方向设置
#define SDA_IND() {GPIOD->MODER&=~(3<<(4*2));GPIOD->MODER|=0<<4*2;} //PD4输入模式
#define SDA_OUTD() {GPIOD->MODER&=~(3<<(4*2));GPIOD->MODER|=1<<4*2;} //PD4输出模式
//IO操作函数
#define IICD_SCL PDout(5)
#define IICD_SDA PDout(4)
#define READD_SDA PDin(4)
//IICD所有操作函数
void iicd_init(void);
u8 iicd_write_byte(u8 value);
u8 iicd_read_byte(u8 ack);
void iicd_transstart(void);
void iicd_connectreset(void);
u8 iicd_softreset(void);
u8 iicd_read_statusreg(u8 *p_value, u8 *p_checksum);
u8 iicd_write_statusreg(u8 *p_value);
u8 iicd_measure(u8 *p_value, u8 *p_checksum, u8 mode);
s16 iicd_getTem(void);
u16 iicd_getHum(s16 Tem);
#endif
//////////////
////IICD.c////
//////////////
#include &quot;IICD.h&quot;
#define IIC_DELAY_TIME 10
#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
enum {TEMP,HUMI};
u8 iicd_valueH, iicd_valueL,iicd_crc8;
//-------------//
// iicd initial//
//-------------//
void iicd_init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //使能GPIO时钟
//GPIO初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化
IICD_SCL=0;IICD_SDA=1;
}
//---------------------------------------------------------//
// writes a byte on the Sensibus and checks the acknowledge//
//---------------------------------------------------------//
u8 iicd_write_byte(u8 value){
u8 i,error=0;
SDA_OUTD();
for (i=0x80;i>0;i/=2){ //shift bit for masking
if (i & value) IICD_SDA=1; //masking value with i , write to SENSI-BUS
else IICD_SDA=0;
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME); //clk for SENSI-BUS
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME); //pulswith approx. 5 us
}
IICD_SDA=1; //release DATA-line
SDA_IND();
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);
error=READD_SDA; //check ack (DATA will be pulled down by SHT11)
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);//clk拉低
return error;
}
//---------------------------------------------------------------------------//
// reads a byte form the Sensibus and gives an acknowledge in case of &quot;ack=1&quot;//
//---------------------------------------------------------------------------//
u8 iicd_read_byte(u8 ack){
u8 i,val=0;
IICD_SDA=1; //release DATA-line
SDA_IND();
for (i=0x80;i>0;i/=2){ //shift bit for masking
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);//clk for SENSI-BUS
if (READD_SDA) val |= i; //read bit
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);
}
SDA_OUTD();
IICD_SDA=!ack; //in case of &quot;ack==1&quot; pull down DATA-Line
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);//clk #9 for ack
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);
IICD_SDA=1; //release DATA-line
return val;
}
//-------------------------------//
// generates a transmission start//
//-------------------------------//
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
//-------------------------------//
void iicd_transstart(void){
//初始状态
SDA_OUTD();IICD_SDA=1;IICD_SCL=0;
//开始信号
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);//clk拉高
IICD_SDA=0;
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);//clk拉低
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);//clk拉高
IICD_SDA=1;
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);//clk拉低
}
//----------------------------------------------------------------------------------//
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart//
//----------------------------------------------------------------------------------//
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
//----------------------------------------------------------------------------------//
void iicd_connectreset(void){
u8 i;
//初始状态
SDA_OUTD();IICD_SDA=1;IICD_SCL=0;
//复位方法
for(i=0;i<9;i++){
delay_us(IIC_DELAY_TIME);IICD_SCL=1;delay_us(IIC_DELAY_TIME);//clk拉高
delay_us(IIC_DELAY_TIME);IICD_SCL=0;delay_us(IIC_DELAY_TIME);//clk拉低
}
iicd_transstart();
}
//---------------------------------//
// resets the sensor by a softreset//
//---------------------------------//
u8 iicd_softreset(void){
u8 error=0;
iicd_connectreset(); //reset communication
error+=iicd_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//------------------------------------------------//
// reads the status register with checksum (8-bit)//
//------------------------------------------------//
u8 iicd_read_statusreg(u8 *p_value, u8 *p_checksum){
u8 error=0;
iicd_transstart(); //transmission start
error=iicd_write_byte(STATUS_REG_R);//send command to sensor
*p_value=iicd_read_byte(ACK); //read status register (8-bit)
*p_checksum=iicd_read_byte(noACK); //read checksum (8-bit)
printf(&quot;read_statusreg is %x.reg checksum is %x.
&quot;,*(p_value),*p_checksum);
return error; //error=1 in case of no response form the sensor
}
//-------------------------------------------------//
// writes the status register with checksum (8-bit)//
//-------------------------------------------------//
u8 iicd_write_statusreg(u8 *p_value){
u8 error=0;
iicd_transstart(); //transmission start
error+=iicd_write_byte(STATUS_REG_W);//send command to sensor
error+=iicd_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//---------------------------------------------------------//
// makes a measurement (humidity/temperature) with checksum//
//---------------------------------------------------------//
u8 iicd_measure(u8 *p_value, u8 *p_checksum, u8 mode){
u16 error=0;
u32 i;
iicd_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=iicd_write_byte(MEASURE_TEMP); break;
case HUMI : error+=iicd_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) {
if(READD_SDA==0) break; //wait until sensor has finished the measurement
delay_us(30);
}
if(READD_SDA) error+=1; // or timeout (~2 sec.) is reached
*(p_value) =iicd_read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=iicd_read_byte(ACK); //read the second byte (LSB)
*p_checksum =iicd_read_byte(noACK); //read checksum
printf(&quot;value0 is %x.value1 is %x.checksum is %x.
&quot;,*(p_value),*(p_value+1),*p_checksum);
return error;
}
////////////////////////////////////////////////////////////////////////
//实际计算公式 //
//Tem=0.01*recieveDateT-39.63; //
//HumRaw=-4+0.0405*recieveDateH-2.8*10^(-6)*recieveDateH*recieveDateH //
//HumCal=(Tem-25)*(0.01+0.00008*recieveDateH)+HumRaw //
////////////////////////////////////////////////////////////////////////
//得到扩大了10^2倍的温度
s16 iicd_getTem(void){
u8 error;
u16 TemDate;
s16 Tem;
error=iicd_measure(&iicd_valueH, &iicd_valueL,0); //0,tem.1,hum
if(error==0){
TemDate=((u16)iicd_valueH<<8)+iicd_valueL;
Tem=TemDate-3963;
return Tem;
}
else return 0x1fff;
}
//得到扩大了10^2倍的湿度
u16 iicd_getHum(s16 Tem){
u8 error;
u16 HumDate;
u32 HumOri;
u32 HumCal;
u16 Hum;
error=iicd_measure(&iicd_valueH, &iicd_valueL,1); //0,tem.1,hum
if(error==0){
HumDate=((u16)iicd_valueH<<8)+iicd_valueL;
HumOri=405000*HumDate-28*HumDate*HumDate-40000000;
HumCal=(Tem-2500)*(1000+8*HumDate)+HumOri;
Hum=HumCal/100000;
return Hum;
}
else return 0x1fff;
} |