中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C

B站:https://space.bilibili.com/309103931

中移4G模块-ML302专栏:https://blog.csdn.net/qq_33259323/category_10453372.html

中移4G模块-ML302文集:https://www.bilibili.com/read/readlist/rl328642

1.中移4G模块-ML302-OpenCpu开发-(固件编译和烧录)

https://blog.csdn.net/qq_33259323/article/details/108586847

https://www.bilibili.com/read/cv7876504

2.中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云)

https://blog.csdn.net/qq_33259323/article/details/108638945

https://www.bilibili.com/read/cv7876527

2.1中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-订阅主题)

https://blog.csdn.net/qq_33259323/article/details/108960540

https://www.bilibili.com/read/cv7879954

2.2中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-接收和发送数据)

https://blog.csdn.net/qq_33259323/article/details/108964810

https://www.bilibili.com/read/cv7886836

2.3中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-RRPC通讯)

https://blog.csdn.net/qq_33259323/article/details/108965071

https://www.bilibili.com/read/cv7888259

3.中移4G模块-ML302-OpenCpu开发-串口开发

https://blog.csdn.net/qq_33259323/article/details/108974888

https://www.bilibili.com/read/cv7888865

4.中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C

https://blog.csdn.net/qq_33259323/article/details/109020642

https://www.bilibili.com/read/cv7922942

5.中移4G模块-ML302-OpenCpu开发-MCP23017输入/输出

https://blog.csdn.net/qq_33259323/article/details/109109136

https://www.bilibili.com/read/cv7969395

7.中移4G模块-ML302-OpenCpu开发-PCF8591测量电压

https://blog.csdn.net/qq_33259323/article/details/109109266

https://www.bilibili.com/read/cv7969365

8.中移4G模块-ML302-OpenCpu开发-GPIO

https://blog.csdn.net/qq_33259323/article/details/108960947

https://www.bilibili.com/read/cv7877192

9.中移4G模块-ML302-OpenCpu开发-ADC

https://blog.csdn.net/qq_33259323/article/details/109020864

https://www.bilibili.com/read/cv7922958

10.中移4G模块-ML302-OpenCpu开发-CJSON

https://blog.csdn.net/qq_33259323/article/details/109020898

https://www.bilibili.com/read/cv7923020

11.中移4G模块-ML302-OpenCpu开发-HTTP

https://blog.csdn.net/qq_33259323/article/details/109020904

https://www.bilibili.com/read/cv7923054

中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C

因为ML302模块的I2C口是3.3v,其他设备的I2C都是上拉5V,然后我用PCA9306模块进行电平转换,但是发现还是不行,所以我准备使用51单片机串口转I2c。我使用的是STC15W408AS单片机,有个启动标志P1.1。

ML302发送数据格式:10 90 43 00 0d   

10:写数据标识符       90:I2C地址         43:地址         00:数据          0d:结束符

ML302读取格式:11 90 43 0D

11:读数据标识符       90:I2C地址         43:地址         0D:结束符

ML302接收格式:90 ff

90:I2C地址  ff数据

#define	RX1_Lenth	60
#include	"STC15Fxxxx.H"
#include <stdio.h>
#include <string.h>

char xdata RX1_Buffer[RX1_Lenth];	
int	TX1_Cnt=0;	
int	RX1_Cnt=0;	
bit	B_TX1_Busy=0;
bit	B_RX1_Busy=0;

unsigned char result_iic_address;




//----------------IIC

int IIC_RESULT = -1;
unsigned char * IIC_RESULT_DATA;

#define I2C_DELAY_TIME 5

sbit I2C_SCL = P3^4;
sbit I2C_SDA = P3^5;
sbit I2C_START = P1^1;
sbit I2C_ST = P1^0;

void I2C_Send_Start();
void I2C_Send_Stop();
bit I2C_Get_Ack_From_Slave();
bit I2C_Write_Byte(unsigned char Data);
bit I2C_Read_Byte(unsigned char* recv);
bit I2C_Sync_The_Clock_T0();
void I2C_Delay();

void sendLen(char * sendData,int length);
void sendbit(unsigned char d);





//--------------------------------------------------------------------------------------   
//  函数名称:void I2C_Send_Start() 
//  函数功能:IIC开始信号  
//--------------------------------------------------------------------------------------   
void I2C_Send_Start()
{
    I2C_SCL = 1; 					//总线复位
    I2C_SDA = 1; 

    I2C_Delay(); 

    I2C_SDA = 0; 					//产生开始信号
    I2C_Delay(); 

    I2C_SCL = 0; 
    I2C_Delay();

    return;
}
//--------------------------------------------------------------------------------------   
//  函数名称:void I2C_Send_Stop()
//  函数功能:IIC停止信号  
//--------------------------------------------------------------------------------------   
void I2C_Send_Stop()
{

    I2C_SDA = 0; 
    I2C_Delay(); 

    I2C_SCL = 1;  
    I2C_Delay();
 
    I2C_SDA = 1;  

    return;
}
//--------------------------------------------------------------------------------------   
//  函数名称:bit I2C_Get_Ack_From_Slave()
//  函数功能:IIC等待从设备的ACK信号
//	说明:这里使用主从通信协议,CPU是主设备 
//--------------------------------------------------------------------------------------   
bit I2C_Get_Ack_From_Slave()
{
    bit ack;

    I2C_SDA = 1; 					//总线复位
    I2C_SCL = 1;

    if(!I2C_Sync_The_Clock_T0())
    {
        return (bit)0; 				//'同步'错误
    }

    I2C_Delay(); 					//同步时钟

    ack = I2C_SDA;        

    I2C_SCL = 0; 					//产生一个时钟
 
    if (ack)
        return (bit)0;
    else
        return (bit)1;     			//从设备发送了ACK信号
}
//--------------------------------------------------------------------------------------   
//  函数名称:bit I2C_Write_Byte(unsigned char Data)
//  函数功能:IIC向从设备写一个字节的数据
//--------------------------------------------------------------------------------------   
bit I2C_Write_Byte(unsigned char Data)
{
    unsigned char Bit = 0;  

    for (Bit = 0; Bit < 8; Bit++ )		//发送一个字节数据,MSB先发送
    {
        I2C_SDA = (bit)(Data & 0x80);
        I2C_SCL = 1;  
                      
        if (!I2C_Sync_The_Clock_T0())
        {
            return (bit)0; 				//同步失败
        }

        I2C_Delay(); 
        I2C_SCL = 0;                     

        Data = Data << 1;               //准备发送下一个bit     
    }
    return (I2C_Get_Ack_From_Slave());	//确保从设备发送了ACK信号
}
//--------------------------------------------------------------------------------------   
//  函数名称:bit I2C_Read_Byte(unsigned char* recv)
//  函数功能:IIC从从设备读一个字节的数据
//--------------------------------------------------------------------------------------   
bit I2C_Read_Byte(unsigned char* recv)
{
    unsigned char result  = 0;  
    unsigned char Bit = 0;  

    for (Bit = 0; Bit < 8; Bit++ )
    {
        I2C_SDA = 1;           			//释放SDA
        I2C_SCL = 1;           			//释放SCL

        if (!I2C_Sync_The_Clock_T0())
        {
           return (bit)0; 				//同步失败
        }

        result = result<< 1;      		

        if (I2C_SDA)					//如果I2C_SDA线是1,则result用自增1的方式将LSB置1
        {								//如果I2C_SDA线是0,则保持resultLSB的0
            result++;  
        }

        I2C_SCL = 0;             
    }

    (*recv) = result;
		
		//printf("data: %d \r\n",(*recv));
		
		//返回格式	地址+数据
		sendbit(result_iic_address);
		sendbit(result);

    return (bit)1;
}
//--------------------------------------------------------------------------------------   
//  函数名称:bit I2C_Sync_The_Clock_T0()
//  函数功能:IIC传输同步
//--------------------------------------------------------------------------------------   
bit I2C_Sync_The_Clock_T0()
{
    unsigned int delay = 0xffff;

    while ((!I2C_SCL) && delay)			//试图同步时钟
        delay--;

    if (!delay)
        return (bit)0;  				//同步超时

    return (bit)1;  					//同步成功
}
//--------------------------------------------------------------------------------------   
//  函数名称:void I2C_Delay()
//  函数功能:IIC短暂的软件延时
//	说明:对于标准IIC设备,最短延时5.425us,对于最新的IIC设备,或许可以缩短此延时
//--------------------------------------------------------------------------------------   
void I2C_Delay()
{
    char x = I2C_DELAY_TIME;

    while(x--);

    return;
}


int IIC_WRITE_DATA(unsigned char driver_address,unsigned char data_address,unsigned char content){
	I2C_Send_Start();
	if(!I2C_Write_Byte(driver_address)){
		return 0;
	}
	if(!I2C_Write_Byte(data_address)){
		return 0;
	}
	if(!I2C_Write_Byte(content)){
		return 0;
	}
	I2C_Send_Stop();
	
	return 1;
}



int IIC_READ_DATA(unsigned char driver_address,unsigned char data_address,unsigned char* recv){
	int result = 0;
	I2C_Send_Start();
	result_iic_address = driver_address;
	if(!I2C_Write_Byte(driver_address)){
		return 0;
	}
	if(!I2C_Write_Byte(data_address)){
		return 0;
	}
	I2C_Send_Stop();
	
	I2C_Send_Start();
	if(!I2C_Write_Byte(driver_address | 0x01)){
		return 0;
	}
	result = I2C_Read_Byte(recv);
	I2C_Send_Stop();
	
	return result;
}

//----------------IIC



void UartInit(void){
				SCON = 0x50;		
				AUXR |= 0x01;		
				AUXR |= 0x04;	
				T2L = 0xE8;		
				T2H = 0xFF;		
				AUXR |= 0x10;		
	
				ES=1; 
				EA=1; 
				TI=1;
}

void delay(unsigned int xms){
    unsigned int x,y;
    for(x=xms;x>0;x--)
        for(y=110;y>0;y--);
}

void sendLen(char * sendData,int length){
	int i=0;
	for(i=0;i<length;i++){
		while(1){
			if(!B_TX1_Busy){
				B_TX1_Busy = 1;
				SBUF = sendData[i];
				break;
			}
		}
	}
}

void sendbit(unsigned char d){
	while(1){
			if(!B_TX1_Busy){
				B_TX1_Busy = 1;
				SBUF = d;
				break;
			}
		}
}

void get(){
	memset(RX1_Buffer,0,RX1_Lenth);
	while(1){
		if(B_RX1_Busy == 1){
			B_RX1_Busy = 0;
			break;
		}
	}
}




void main(void){
	  
		UartInit();
	
		I2C_ST = 0;
		if(I2C_START == 1){
			delay(100);
			if(I2C_START == 0){
				I2C_ST = 1;
				while(1){
					get();
					if(RX1_Buffer[0] == 0x10){
						if(IIC_WRITE_DATA(RX1_Buffer[1],RX1_Buffer[2],RX1_Buffer[3]) == 0){
							I2C_ST=0x00;
							sendLen("ok2",3);
						}else{
							I2C_ST=0xFF;
							sendLen("ok3",3);
						}
						//sendLen("ok1",3);
						//sendLen(RX1_Buffer,4);
					}else if(RX1_Buffer[0] == 0x11){
						if(IIC_READ_DATA(RX1_Buffer[1],RX1_Buffer[2],IIC_RESULT_DATA) == 0){
							I2C_ST=0x00;
						}else{
							I2C_ST=0xFF;
						}
					}else{
						sendLen("error",5);
						sendLen(RX1_Buffer,5);
					}
					memset(RX1_Buffer,0,RX1_Lenth);
				}
			}
		}
}

void UART1_int (void) interrupt UART1_VECTOR
{
	if(RI){
		RI = 0;
		RX1_Buffer[RX1_Cnt] = SBUF;	
		
		if(RX1_Buffer[RX1_Cnt] == 0x0D){
			RX1_Cnt = 0;
			B_RX1_Busy = 1;
		}else{
			RX1_Cnt++;
		}
	}

	if(TI){
		TI = 0;
		B_TX1_Busy = 0;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_33259323/article/details/109020642