KS103超声波模块

2019-07-20 23:39发布

[mw_shl_code=c,true]/*KS10X.c*/ #include"I2C2init.h" #include"sys.h" #include"delay.h" #include"usart.h" #include"math.h" #include"KS10X.h" #define uchar unsigned char #define uint unsigned int u16 sum; /*************************************************************************** *******************************************************************************/ void Single_WriteI2C(u8 SlaveAddress,u8 REG_Address,u8 REG_data) { IIC_Start(); //起始信号 IIC_Send_Byte(SlaveAddress); //发送设备地址+写信号 while(IIC_Wait_Ack()); IIC_Send_Byte(REG_Address); //内部寄存器地址 while(IIC_Wait_Ack()); /**********************/ IIC_Send_Byte(REG_data); //内部寄存器数据 while(IIC_Wait_Ack()); /**********************/ IIC_Stop(); //发送停止信号 } //************************************** //从I2C设备读取一个字节数据 //************************************** u8 Single_ReadI2C(u8 SlaveAddress,u8 REG_Address) { u8 REG_data=0; IIC_Start(); IIC_Send_Byte(SlaveAddress); while(IIC_Wait_Ack()); IIC_Send_Byte(REG_Address); while(IIC_Wait_Ack()); /**********************/ IIC_Start(); IIC_Send_Byte(SlaveAddress+1); while(IIC_Wait_Ack()); delay_us(50); REG_data=IIC_Read_Byte(0); // IIC_NAck(); // delay_us(2); IIC_Stop(); return REG_data; } u32 Read_KS10X(u8 SlaveAddress) { // delay_ms(80); sum=Single_ReadI2C(SlaveAddress,0x02); //高8位 sum<<=8; sum+=Single_ReadI2C(SlaveAddress,0x03); //低8位 return sum; } void Change_Addr(u8 OldAdddr,u8 NewAddr) { // delay_ms(500); Single_WriteI2C(OldAdddr,0x02,0x9a); //默认原地址是0x00; delay_ms(1); Single_WriteI2C(OldAdddr,0x02,0x92); delay_ms(1); Single_WriteI2C(OldAdddr,0x02,0x9e); delay_ms(1); Single_WriteI2C(OldAdddr,0x02,NewAddr); delay_ms(100); // Single_WriteI2C(NewAddr,0x02,0xb0); // delay_ms(80); } float Read_KS10X_Data(u8 SlaveAddress) { float sumx; float sum_x; Single_WriteI2C(SlaveAddress,0x02,0xb0); delay_ms(80); sumx=Read_KS10X(SlaveAddress); //读出第一个超声波的数据 sum_x=(float)sumx/10; // printf("%lf ",sum_x); return sum_x; } void KS10X_Change_Addr_Init(u8 OldAddr,u8 NewAddr) //此函数用来实现选择超声波的地址 { Change_Addr(OldAddr,NewAddr); delay_ms(80); } /*KS10X.h*/ #ifndef Mpu6050_H #define Mpu6050_H //**************************************** // 定义KS10X内部地址 //**************************************** #define SlaveAddress1 0xE8 //IIC写入时的地址字节数据,+1为读取 #define SlaveAddress2 0xd0 #define SlaveAddress3 0xd2 #define SlaveAddress4 0xd4 #define SlaveAddress5 0xd6 #define SlaveAddress6 0xd8 #define SlaveAddress7 0xda #define SlaveAddress8 0xdc #define SlaveAddress9 0xde #define SlaveAddress10 0xe0 #define SlaveAddress11 0xe2 #define SlaveAddress12 0xe4 #define SlaveAddress13 0xe6 #define SlaveAddress14 0xea #define SlaveAddress15 0xec #define SlaveAddress16 0xee #define SlaveAddress17 0xf8 #define SlaveAddress18 0xfa #define SlaveAddress19 0xfc #define SlaveAddress20 0xfe #include"sys.h" u8 Single_ReadI2C(u8 SlaveAddress,u8 REG_Address); void Single_WriteI2C(u8 SlaveAddress,u8 REG_Address,u8 REG_data); u32 Read_KS10X(u8 SlaveAddress); void Change_Addr(u8 OldAdddr,u8 NewAddr); float Read_KS10X_Data(u8 SlaveAddress); void KS10X_Change_Addr_Init(u8 OldAddr,u8 NewAddr); #endif /*I2C2init.c*/ #include"I2C2init.h" #include"sys.h" #include"usart.h" #include"delay.h" #include"math.h" void I2C2_Init() { RCC->APB2ENR|=1<<3; //GPIOB时钟使能 GPIOB->CRH&=0xff00ffff; GPIOB->CRH|=0x00330000; //PB12,PB13设置为复用开漏输出 GPIOB->ODR|=1<<12; GPIOB->ODR|=1<<13; } void IIC_Start(void) { SDA_OUT(); //sda线输出 SDA=1; SCL=1; delay_us(10); SDA=0; //START:when CLK is high,DATA change form high to low delay_us(10); SCL=0; //钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT(); //sda线输出 SCL=0; SDA=0; delay_us(10); SCL=1; //STOP:when CLK is high DATA change form low to high SDA=1; //发送I2C总线结束信号 delay_us(10); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 SDA=1;delay_us(6); SCL=1;delay_us(6); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } SCL=0; //时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { SCL=0; SDA_OUT(); SDA=0; delay_us(10); SCL=1; delay_us(10); SCL=0; } //不产生ACK应答 void IIC_NAck(void) { SCL=0; SDA_OUT(); SDA=1; delay_us(10); SCL=1; delay_us(10); SCL=0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); SCL=0; //拉低时钟开始数据传输 for(t=0;t<8;t++) { SDA=(txd&0x80)>>7; txd<<=1; delay_us(10); //对TEA5767这三个延时都是必须的 SCL=1; delay_us(10); SCL=0; delay_us(10); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN(); //SDA设置为输入 for(i=0;i<8;i++ ) { SCL=0; delay_us(10); SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(5); } if (!ack) IIC_NAck(); //发送nACK else IIC_Ack(); //发送ACK return receive; } /*I2C2init.h*/ #ifndef I2C2_H #define I2C2_H #include"sys.h" #define SCL PBout(12) #define SDA PBout(13) #define READ_SDA PBin(13) #define SDA_IN() {GPIOB->CRH&=0xff0fffff;GPIOB->CRH|=0x00800000;/*GPIOB->ODR|=1<<11;*/} #define SDA_OUT() {GPIOB->CRH&=0xff0fffff;GPIOB->CRH|=0x00300000;} void I2C2_Init(void); void IIC_Start(void); //发送IIC开始信号 void IIC_Stop(void); //发送IIC停止信号 void IIC_Send_Byte(u8 txd); //IIC发送一个字节 u8 IIC_Read_Byte(unsigned char ack); //IIC读取一个字节 u8 IIC_Wait_Ack(void); //IIC等待ACK信号 void IIC_Ack(void); //IIC发送ACK信号 void IIC_NAck(void); //IIC不发送ACK信号 //void Change_Addr(u8 NewAddr); #endif /*main.c*/ #include"sys.h" #include"delay.h" #include"usart.h" #include"I2C2init.h" #include"KS10X.h" u32 sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8,sum9,sum10,sum11,sum12,sum13,sum14,sum15, sum16,sum17,sum18,sum19,sum20; float sum_1,sum_2; int main() { Stm32_Clock_Init(9); delay_init(72); uart_init(72,9600); I2C2_Init(); // KS10X_Change_Addr_Init(SlaveAddress3,SlaveAddress2); //在换了KS10X后才执行,且执行一次 ,执行完一次后就消去 //这样这个模块将有固定的地址 while(1) { sum_2=Read_KS10X_Data(SlaveAddress2); sum_1=Read_KS10X_Data(SlaveAddress1); printf("%lf ",sum_1); printf("%lf ",sum_2); } }[/mw_shl_code] [mw_shl_code=c,true] [/mw_shl_code] [mw_shl_code=c,true]这个是我今天读出来的KS103超声波数据的程序,主要是在一根总线上搭多个模块,用 [/mw_shl_code] KS10X_Change_Addr_Init(u8 OldAddr,u8 NewAddr) 这个函数来实现改变器件地址 其他的函数直接用我写的就行了,只要在主函数里面修改即可
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。