我接了个项目温湿度传感器(DHT20型号)要导线80CM线长IIC通讯 普通程序通讯有干扰。
希望沁恒微给我一个低速4k通讯速率程序,模拟的程序发我谢谢了。
邮箱个人信息保护,已隐藏
我接了个项目温湿度传感器(DHT20型号)要导线80CM线长IIC通讯 普通程序通讯有干扰。
希望沁恒微给我一个低速4k通讯速率程序,模拟的程序发我谢谢了。
邮箱个人信息保护,已隐藏
IIC通讯 4K速率 再慢一点也行 发我程序哦 谢谢
一定要发我哦。
搞好给你100块买咖啡喝
你们这个IO确实不好操作 请赐教 iic
51 iic 程序我移植不了哦 操作不一样哦
网上一搜一大把, 这都不会移植, 兄弟别干嵌入式了吧
这傻逼IIC是板内通信,飞线搞能不干扰才怪
#ifdefIS_7P
// #include "nvs.h"
// #include "nvs_flash.h"
#defineCLK_PINGPIO_Pin_12
#defineDATA_PINGPIO_Pin_13
#defineMCU_HAVE_DATAGPIOB_ReadPortPin(DATA_PIN)
void Delay_N10us(uint32_tt)//延时函数
{
// volatile uint32_t k;
// while (t--)
// {
// for (k = 0; k < 2; k++)//110
// ;
// }
}
void SensorDelay_us(uint32_tt)//延时函数
{
mDelayuS(t);
// t = t - 2;
// for (; t > 0; t--)
// {
// Delay_N10us(1);
// }
}
void Delay_3us(void)//延时函数
{
mDelayuS(3);
// Delay_N10us(1);
// Delay_N10us(1);
// Delay_N10us(1);
// Delay_N10us(1);
}
void Delay_1us(void)//延时函数
{
mDelayuS(1);
// Delay_N10us(1);
// Delay_N10us(1);
// Delay_N10us(1);
// Delay_N10us(1);
// Delay_N10us(1);
}
void SDA_Pin_Output_High(void)//将P15配置为输出 , 并设置为低电平, P15作为I2C的SDA
{
GPIOB_ModeCfg(DATA_PIN,GPIO_ModeOut_PP_5mA);
GPIOB_SetBits(DATA_PIN);
// gpio_pad_select_gpio(DATA_PIN);
// gpio_set_direction(DATA_PIN, GPIO_MODE_OUTPUT);
// gpio_set_level(DATA_PIN, 1);
// Gpio_InitIOExt(1,5,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//config P15 to output
// Gpio_SetIO(1,5,1);
}
void SDA_Pin_Output_Low(void)//将P15配置为输出 并设置为高电平
{
GPIOB_ModeCfg(DATA_PIN,GPIO_ModeOut_PP_5mA);
GPIOB_ResetBits(DATA_PIN);
// gpio_pad_select_gpio(DATA_PIN);
// gpio_set_direction(DATA_PIN, GPIO_MODE_OUTPUT);
// gpio_set_level(DATA_PIN, 0);
// Gpio_InitIOExt(1,5,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//config P15 to output
// Gpio_SetIO(1,5,0);
}
void SDA_Pin_IN_FLOATING(void)// SDA配置为悬浮输入
{
GPIOB_ModeCfg(DATA_PIN,GPIO_ModeIN_Floating);
// gpio_pad_select_gpio(DATA_PIN);
// gpio_set_direction(DATA_PIN, GPIO_MODE_INPUT);
// gpio_set_pull_mode(DATA_PIN, GPIO_PULLUP_ONLY);
// Gpio_InitIO(1, 5, GpioDirIn);
}
void SCL_Pin_Output_High(void)// SCL输出高电平,P14作为I2C的SCL
{
GPIOB_SetBits(CLK_PIN);
// gpio_set_level(CLK_PIN, 1);
}
void SCL_Pin_Output_Low(void)// SCL输出低电平
{
GPIOB_ResetBits(CLK_PIN);
// gpio_set_level(CLK_PIN, 0);
}
void Init_I2C_Sensor_Port(void)//初始化I2C接口
{
GPIOB_ModeCfg(CLK_PIN,GPIO_ModeOut_PP_5mA);
GPIOB_ModeCfg(DATA_PIN,GPIO_ModeOut_PP_5mA);
GPIOB_SetBits(CLK_PIN);
GPIOB_SetBits(DATA_PIN);
// gpio_pad_select_gpio(DATA_PIN);
// gpio_set_direction(DATA_PIN, GPIO_MODE_OUTPUT);
// gpio_set_level(DATA_PIN, 1);
// gpio_pad_select_gpio(CLK_PIN);
// gpio_set_direction(CLK_PIN, GPIO_MODE_OUTPUT);
// gpio_set_level(CLK_PIN, 1);
}
void I2C_Start(void)// I2C主机发送START信号
{
SDA_Pin_Output_High();
SensorDelay_us(8);
SCL_Pin_Output_High();
SensorDelay_us(8);
SDA_Pin_Output_Low();
SensorDelay_us(8);
SCL_Pin_Output_Low();
SensorDelay_us(8);
}
void ZSSC_I2C_WR_Byte(uint8_tByte)//往AHT10写一个字节
{
uint8_tData,N,i;
Data=Byte;
i=0x80;
for (N=0;N<8;N++)
{
SCL_Pin_Output_Low();
Delay_3us();
if (i&Data)
{
SDA_Pin_Output_High();
}
else
{
SDA_Pin_Output_Low();
}
SCL_Pin_Output_High();
Delay_3us();
Data<<=1;
}
SCL_Pin_Output_Low();
SensorDelay_us(8);
SDA_Pin_IN_FLOATING();
SensorDelay_us(8);
}
uint8_t ZSSC_I2C_RD_Byte(void)//从AHT10读取一个字节
{
uint8_tByte,i,a;
Byte=0;
SCL_Pin_Output_Low();
SDA_Pin_IN_FLOATING();
SensorDelay_us(8);
for (i=0;i<8;i++)
{
SCL_Pin_Output_High();
Delay_1us();
a=0;
if (MCU_HAVE_DATA)
a=1;
Byte= (Byte<<1) |a;
SCL_Pin_Output_Low();
Delay_1us();
}
SDA_Pin_IN_FLOATING();
SensorDelay_us(8);
returnByte;
}
uint8_t Receive_ACK(void)//看AHT20是否有回复ACK
{
uint16_tCNT;
CNT=0;
SCL_Pin_Output_Low();
SDA_Pin_IN_FLOATING();
SensorDelay_us(8);
SCL_Pin_Output_High();
SensorDelay_us(8);
while ((MCU_HAVE_DATA) &&CNT<100)
CNT++;
if (CNT==100)
{
return0;
}
SCL_Pin_Output_Low();
SensorDelay_us(8);
return1;
}
void Send_ACK(void)//主机回复ACK信号
{
SCL_Pin_Output_Low();
SensorDelay_us(8);
SDA_Pin_Output_Low();
SensorDelay_us(8);
SCL_Pin_Output_High();
SensorDelay_us(8);
SCL_Pin_Output_Low();
SensorDelay_us(8);
SDA_Pin_IN_FLOATING();
SensorDelay_us(8);
}
void Send_NOT_ACK(void)//主机不回复ACK
{
SCL_Pin_Output_Low();
SensorDelay_us(8);
SDA_Pin_Output_High();
SensorDelay_us(8);
SCL_Pin_Output_High();
SensorDelay_us(8);
SCL_Pin_Output_Low();
SensorDelay_us(8);
SDA_Pin_Output_Low();
SensorDelay_us(8);
}
void Stop_I2C(void)//一条协议结束
{
SDA_Pin_Output_Low();
SensorDelay_us(8);
SCL_Pin_Output_High();
SensorDelay_us(8);
SDA_Pin_Output_High();
SensorDelay_us(8);
}
uint8_t JH_Read_Status(void)//读取AHT10的状态寄存器
{
uint8_tByte_first;
I2C_Start();
ZSSC_I2C_WR_Byte(0x71);
Receive_ACK();
Byte_first=ZSSC_I2C_RD_Byte();
Send_NOT_ACK();
Stop_I2C();
// printf("\n变量Byte_first = %d\n",Byte_first);
returnByte_first;
}
uint8_t JH_Read_Cal_Enable(void)//查询cal enable位有没有使能?
{
uint8_tval=0;// ret = 0,
val=JH_Read_Status();
if ((val&0x68) ==0x08)
return1;
else
return0;
}
void JH_SendAC(void)//向AHT10发送AC命令
{
I2C_Start();
ZSSC_I2C_WR_Byte(0x70);
Receive_ACK();
ZSSC_I2C_WR_Byte(0xac);// 0xAC采集命令
Receive_ACK();
ZSSC_I2C_WR_Byte(0x33);
Receive_ACK();
ZSSC_I2C_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
}
// CRC校验类型:CRC8/MAXIM
//多项式:X8+X5+X4+1
// Poly:0011 0001 0x31
//高位放到后面就变成 1000 1100 0x8c
// C现实代码:
uint8_t Calc_CRC8(uint8_t*message,uint8_tNum)
{
uint8_ti;
uint8_tbyte;
uint8_tcrc=0xFF;
for (byte=0;byte<Num;byte++)
{
crc^= (message[byte]);
for (i=8;i>0;--i)
{
if (crc&0x80)
crc= (crc<<1) ^0x31;
else
crc= (crc<<1);
}
}
returncrc;
}
bool JH_Read_CTdata(uint32_t*ct)//没有CRC校验,直接读取AHT10的温度和湿度数据
{
// volatile uint8_t Byte_1th = 0;
volatileuint8_tByte_2th=0;
volatileuint8_tByte_3th=0;
volatileuint8_tByte_4th=0;
volatileuint8_tByte_5th=0;
volatileuint8_tByte_6th=0;
uint32_tRetuData=0;
uint16_tcnt=0;
staticboolonce=false;
if (once==false)
{
once=true;
JH_SendAC();//向AHT10发送AC命令
returnfalse;
}
else
{
once=false;
// mDelaymS(80); //大约延时80ms
cnt=0;
while (((JH_Read_Status()&0x80) ==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
{
mDelaymS(1);
// vTaskDelay(10 / portTICK_RATE_MS);
// SensorDelay_us(1508);
if (cnt++>=100)
{
break;
}
}
I2C_Start();
ZSSC_I2C_WR_Byte(0x71);
Receive_ACK();
// Byte_1th =
ZSSC_I2C_RD_Byte();//状态字
Send_ACK();
Byte_2th=ZSSC_I2C_RD_Byte();//湿度
Send_ACK();
Byte_3th=ZSSC_I2C_RD_Byte();//湿度
Send_ACK();
Byte_4th=ZSSC_I2C_RD_Byte();//湿度/温度
Send_ACK();
Byte_5th=ZSSC_I2C_RD_Byte();//温度
Send_ACK();
Byte_6th=ZSSC_I2C_RD_Byte();//温度
Send_NOT_ACK();
Stop_I2C();
RetuData= (RetuData|Byte_2th) <<8;
RetuData= (RetuData|Byte_3th) <<8;
RetuData= (RetuData|Byte_4th);
RetuData=RetuData>>4;
ct[0] =RetuData;//湿度
RetuData=0;
RetuData= (RetuData|Byte_4th) <<8;
RetuData= (RetuData|Byte_5th) <<8;
RetuData= (RetuData|Byte_6th);
RetuData=RetuData&0xfffff;
ct[1] =RetuData;//温度
returntrue;
}
}
// void JH_Read_CTdata_crc(uint32_t *ct) // CRC校验后,读取AHT10的温度和湿度数据
// {
// volatile uint8_t Byte_1th = 0;
// volatile uint8_t Byte_2th = 0;
// volatile uint8_t Byte_3th = 0;
// volatile uint8_t Byte_4th = 0;
// volatile uint8_t Byte_5th = 0;
// volatile uint8_t Byte_6th = 0;
// volatile uint8_t Byte_7th = 0;
// uint32_t RetuData = 0;
// uint16_t cnt = 0;
// // uint8_t CRCDATA=0;
// uint8_t CTDATA[6] = {0}; //用于CRC传递数组
// JH_SendAC(); //向AHT10发送AC命令
// vTaskDelay(100 / portTICK_RATE_MS);
// // SensorDelay_us(80000); //大约延时80ms
// cnt = 0;
// while (((JH_Read_Status() & 0x80) == 0x80)) //直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
// {
// vTaskDelay(10 / portTICK_RATE_MS);
// // SensorDelay_us(1508);
// if (cnt++ >= 100)
// {
// break;
// }
// }
// I2C_Start();
// ZSSC_I2C_WR_Byte(0x71);
// Receive_ACK();
// CTDATA[0] = Byte_1th = ZSSC_I2C_RD_Byte(); //状态字
// Send_ACK();
// CTDATA[1] = Byte_2th = ZSSC_I2C_RD_Byte(); //湿度
// Send_ACK();
// CTDATA[2] = Byte_3th = ZSSC_I2C_RD_Byte(); //湿度
// Send_ACK();
// CTDATA[3] = Byte_4th = ZSSC_I2C_RD_Byte(); //湿度/温度
// Send_ACK();
// CTDATA[4] = Byte_5th = ZSSC_I2C_RD_Byte(); //温度
// Send_ACK();
// CTDATA[5] = Byte_6th = ZSSC_I2C_RD_Byte(); //温度
// Send_ACK();
// Byte_7th = ZSSC_I2C_RD_Byte(); // CRC数据
// Send_NOT_ACK();
// Stop_I2C();
// if (Calc_CRC8(CTDATA, 6) == Byte_7th)
// {
// RetuData = (RetuData | Byte_2th) << 8;
// RetuData = (RetuData | Byte_3th) << 8;
// RetuData = (RetuData | Byte_4th);
// RetuData = RetuData >> 4;
// ct[0] = RetuData; //湿度
// RetuData = 0;
// RetuData = (RetuData | Byte_4th) << 8;
// RetuData = (RetuData | Byte_5th) << 8;
// RetuData = (RetuData | Byte_6th);
// RetuData = RetuData & 0xfffff;
// ct[1] = RetuData; //温度
// // LED_GUZHANG_0();
// }
// else
// {
// ct[0] = 0x00;
// ct[1] = 0x00; //校验错误返回00
// } // CRC数据
// }
void JH_Init(void)//初始化AHT10
{
Init_I2C_Sensor_Port();
I2C_Start();
ZSSC_I2C_WR_Byte(0x70);
Receive_ACK();
ZSSC_I2C_WR_Byte(0xa8);// 0xA8进入NOR工作模式
Receive_ACK();
ZSSC_I2C_WR_Byte(0x00);
Receive_ACK();
ZSSC_I2C_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
SensorDelay_us(11038);//延时10ms左右
I2C_Start();
ZSSC_I2C_WR_Byte(0x70);
Receive_ACK();
ZSSC_I2C_WR_Byte(0xbe);// 0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
Receive_ACK();
ZSSC_I2C_WR_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
Receive_ACK();
ZSSC_I2C_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
}
float tps = 0, humidity = 0;
void aht20_read()
{
// int i = 0;
volatileintc1,t1;
uint32_tCT_data[2];
staticbooljust_once=false;
if (just_once==false)
{
just_once=true;
Init_I2C_Sensor_Port();
mDelaymS(40);
// vTaskDelay(500 / portTICK_RATE_MS);//刚上电,延时40ms才可以读取状态
if (!((JH_Read_Status()&0x0C) ==
0x0C))//首先读取状态字bit[3:2],如果=1,为校准输出,无须初始化;正常情况下读回来的状态是1C,忙状态是读回来是0x80,其他状态都是异常状态
{
JH_Init();//初始化
}
mDelaymS(500);
}
// vTaskDelay(500 / portTICK_RATE_MS);
// AHT20初始化完成后等待500mS后去读状态字status,需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT20,直至Bit[3]=1
// while (1)
{
if (JH_Read_CTdata(
CT_data))
{
c1=CT_data[0] *1000/1024/1024; //计算得到湿度值(放大了10倍)
t1=CT_data[1] *200*10/1024/1024-500;//计算得到温度值(放大了10倍)
tps=t1/10.0f;
humidity=c1/10.0f;
}
}
return;
}
void AHT20_date_to_ble(char*send_buf,intlen)
{
staticinti=0;
memset(send_buf,0,len);
snprintf(send_buf,len,"TPS%d@HUM%d@", (int)tps, (int)humidity);
}
#endif
温湿度的版本给你参考下