*********************************************************************************************************
** 函数名称:IRvcStrExt()
** 函数功能:向无子地址器件读取N字节数据。
** 入口参数:sla 器件地址
** s 接收数据的变量指针
** no 将要读取的数据的个数
** 出口参数:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
** 说明: 至少要读取2个字节
*********************************************************************************************************
*/
int IRvcStrExt(uchar sla, uchar *s, uchar no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
if(I2C_num > 1)
{
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
else
I2C_state = STATE_READ_NEXT;
I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, true); // 主机读操作
I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);// 突发读操作启动
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C1_MASTER_BASE))
return (false);
else
return (true);
}
else
return (false);
}
/*******************************************************************************************
** 函数名称 :I2C_ISR()
** 函数功能 :中断读写数据
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************/
void I2C_ISR (void)
{
I2CMasterIntClear(I2C1_MASTER_BASE); // 清除I2C中断标志
switch(I2C_state)
{
// 空闲状态
case STATE_IDLE:
{
break;
}
// 写完单个字节状态
case STATE_WRITE_ONE:
{
I2C_state = STATE_IDLE;
break;
}
// 写下一个数据
case STATE_WRITE_NEXT:
{
// 将下一个字节写入寄存器
if(I2C_suba_num != 0)
{
I2C_suba_num--;
I2CMasterDataPut(I2C1_MASTER_BASE,
(I2C_suba >> (8 * I2C_suba_num)));
if((I2C_suba_num == 0) && I2C_opt == 1)
{
if(I2C_num == 1)
I2C_state = STATE_READ_ONE;
else
I2C_state = STATE_READ_FIRST;
}
}
else
{
I2CMasterDataPut(I2C1_MASTER_BASE, *I2C_buf++);
I2C_num--;
if(I2C_num == 1)
{
I2C_state = STATE_WRITE_FINAL;
}
}
// 继续执行块写操作(run=1)
I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
break;
}
// 写最后一个数据
case STATE_WRITE_FINAL:
{
I2CMasterDataPut(I2C1_MASTER_BASE, *I2C_buf);
I2C_num--;
// 发送停止
I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
// 下一个状态为块写完成
I2C_state= STATE_IDLE;
break;
}
// 读取一个字节
case STATE_READ_ONE:
{
I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, true);
I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
I2C_state= STATE_READ_WAIT;
break;
}
// 读取多个字节开始
case STATE_READ_FIRST:
{
I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, true);
I2CMasterControl(I2C1_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_START);
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
else
I2C_state = STATE_READ_NEXT;
break;
}
// 读取下一个字节
case STATE_READ_NEXT:
{
*I2C_buf++ = I2CMasterDataGet(I2C1_MASTER_BASE);
I2C_num--;
I2CMasterControl(I2C1_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_CONT);
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
break;
}
// 读取最后一个字节
case STATE_READ_FINAL:
{
*I2C_buf++ = I2CMasterDataGet(I2C1_MASTER_BASE);
I2C_num--;
I2CMasterControl(I2C1_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
I2C_state= STATE_READ_WAIT;
break;
}
// 等待读取一个字节
case STATE_READ_WAIT:
{
*I2C_buf++ = I2CMasterDataGet(I2C1_MASTER_BASE); // 读取数据
I2C_num--;
I2C_state= STATE_IDLE;
break;
}
}
}
//读取函数:
void read_sd2405()
{
IRcvStr(0x64, 0, 1, temp, 7);
}
调试时候总是停在while(I2C_state != STATE_IDLE);总线总是不出空闲状态。
有人能够搞定吗谢谢了,网上有人说改成查询方式,不太会改,望有人指点
//
#include
//#include "STC12C2052AD.h"
#include //Keil library (is used for _nop()_ operation)
#include //Keil library
#include //Keil library
//====================================================================
#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
sbit SCK = P1^7;
sbit DATA = P1^6;
sbit t =P1^0;
unsigned char checksum;
//unsigned char startVal=0x00;
unsigned char readyT;
unsigned char readyRH;
unsigned char endT=0xCA;
unsigned char endRH=0xDB;
//unsigned char uart0Time;
float fTempVal,fHumiVal; //定义的浮点型温湿度的值
//long lTempVal,lHumiVal;
int idata iTempVal,iHumiVal,iDewpoint; //定义的整形的温湿度的值
unsigned int iText;
//unsigned char idata *pcTempVal,*pcHumiVal;
unsigned char a,b,c,d;
unsigned char idata e,f,g;
unsigned char idata cHumiVal;
unsigned char idata ayTempHumiFram[10]; //数组中存放:第一个温度,第二个湿度,第三个计算出来的露点温度,
//第四个温度校验,第五个湿度校验,第六个露点值校验
enum {TEMP,HUMI};//枚举类型声明,变量可能存在多种类型
void s_transstart(void)//启动传输时序
//----------------------------------------------------------------------------------
// generates a transmission start 形成一个传输开始
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1; SCK=0; //Initial state
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SCK=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
DATA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SCK=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SCK=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
DATA=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SCK=0;
}
void s_connectionreset(void) //正确接收指令信号
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart 通信复位
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
// _______________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| 1|__|2 |_|3 |__|4 |__|5 |__|6 |__|7 |__| 8|__|9 |______| |___| |______
{
unsigned char i;
DATA=1; SCK=0; //Initial state
for(i=0;i0;i/=2) //shift bit for masking
{
if (i & value)
DATA=1; //同时为1的时候执行 masking value with i , write to SENSI-BUS 8位移动
else DATA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //+2
SCK=1; //clk for SENSI-BUS
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //+2 //pulswith approx. 5 us //拉高表示通讯结束
SCK=0;
}
DATA=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
//release DATA-line
SCK=1; //clk #9 for ack
error=DATA; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+1 //check ack (DATA will be pulled down by SHT11)
SCK=0; _nop_(); _nop_();_nop_();_nop_();_nop_(); //+1
return error; //error=1 in case of no acknowledge
}
char s_read_byte(unsigned char ack) //带返回值函数 字符型变量 读寄存器
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
DATA=1; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{ SCK=1;_nop_();_nop_();//+1 //clk for SENSI-BUS
if (DATA) val=(val | i); //read bit
SCK=0; _nop_(); //+1
}
DATA=!ack; _nop_();_nop_();_nop_(); //+1 //in case of "ack==1" pull down DATA-Line
SCK=1; //clk #9 for ack
_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();//+1 //pulswith approx. 5 us
SCK=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+1
DATA=1; //release DATA-line
return val;
}
/*
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset 重置传感器
{
unsigned char error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
*/
/*
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
*/
//----------------------------------------------------------------------------------
/*
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start初始化
error+=s_write_byte(STATUS_REG_W);//send command to sensor发送命令
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
*/
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned char error=0;
unsigned int i;
s_transstart(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //+6 //transmission start 数据传输初始化
switch(mode)
{ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i100)rh_true=100; //cut if the value is outside of
if(rh_true0;y--);
}
void main()
{
EA = 1;
// Uart0_Init(0x70,9600); //根据晶振设定波特率
// Uart0_IntEnable(); //串口使能
uart0Init();
InitTempHumiSensor(); //初始化传感器,详细参考dht60.h
while(1)
{
calcltTempHumi();
// delay(200);
// sendUart0Fram();
// waitUartSendOver(4000);
uartTx();
delay(900);
t=~t;
}
}
以上是51驱动程序