[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)
这个函数来实现改变器件地址
其他的函数直接用我写的就行了,只要在主函数里面修改即可
一周热门 更多>