以下为.c文件得程序
/*
* COPYRIGHT(c) 2019 ShenYang university laboratory of 327
*
* Author:YUE Gaofeng
*
//本部分程序主要为 超声波数据测量
//使用IIC通信协议获取多个超声波数据,超声波型号为KS103
*/
/*定义超声波位置顺序
3 2 1 对应IIC地址为 0xD4 0xD2 0xD0
********* *********
********* *********
********* *********
********* *********
********* *********
4 5 6 0xD6 0xD8 0xDA
*/
#include "bsp_iic.h"
#include "gpio.h"
#include "delay.h"
//SCL为PF1
//SDA为PF0
u16 Distance;
//超声波任务开启函数
void ultrasonic_Task(void const * argument)
{
IIC_Init();
delay_ms(10);
//Change_IIC_Address(0XE8,0XD2); //额外可以使用UART配合上位机修改
while(1)
{
KS103_WriteOneByte(0Xe8,0X02,0XB0);
delay_ms(80);
Distance = KS103_ReadOneByte(0xe8, 0x02);
Distance <<= 8;
Distance += KS103_ReadOneByte(0xe8, 0x03);
delay_ms(10);
}
}
//IIC初始化
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOF_CLK_ENABLE(); //使能GPIOF时钟
//PF0,1初始化设置
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_NOPULL; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
HAL_GPIO_Init(GPIOF,&GPIO_Initure);
IIC_SDA=1;
IIC_SCL=1;
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(10);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(10);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(10);
IIC_SCL=1;
delay_us(10);
IIC_SDA=1;//发送I2C总线结束信号
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(6);
IIC_SCL=1;delay_us(6);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(10);
IIC_SCL=1;
delay_us(10);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(10);
IIC_SCL=1;
delay_us(10);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(10); //延时都是必须的
IIC_SCL=1;
delay_us(10); //确认数据稳定
IIC_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++ )
{
IIC_SCL=0;
delay_us(10);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)
receive++;
delay_us(5);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
u8 KS103_ReadOneByte(u8 address, u8 reg)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte(address); //发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(reg); //发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(address + 1); //进入接收模式
IIC_Wait_Ack();
delay_us(60); //增加此代码通信成功!!!
temp=IIC_Read_Byte(0); //读寄存器3
delay_us(2);
IIC_Stop();//产生一个停止条件
return temp;
}
void KS103_WriteOneByte(u8 address,u8 reg,u8 command)
{
IIC_Start();
IIC_Send_Byte(address); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(reg);//发送高地址
IIC_Wait_Ack();
IIC_Send_Byte(command); //发送低地址
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_us(100);
}
void Change_IIC_Address(u8 addr_old,u8 addr_new)
{
delay_ms(100);
KS103_WriteOneByte(addr_old,0x02,0X9a);
delay_ms(1);
KS103_WriteOneByte(addr_old,0x02,0X92);
delay_ms(1);
KS103_WriteOneByte(addr_old,0x02,0X9e);
delay_ms(100);
KS103_WriteOneByte(addr_old,0x02,addr_new);
delay_ms(100);
KS103_WriteOneByte(addr_new,0x02,0xB0);
delay_ms(500);
}
以下为它的.h文件
#ifndef _BSP_IIC_H
#define _BSP_IIC_H
#endif
#include &quot;mytype.h&quot;
#include &quot;sys.h&quot;
//超声波任务开启函数
void ultrasonic_Task(void const * argument);
//IO操作
#define SDA_IN() {GPIOF->MODER&=~(3<<(0*2));GPIOF->MODER|=0<<0*2;} //PF0输入模式
#define SDA_OUT() {GPIOF->MODER&=~(3<<(0*2));GPIOF->MODER|=1<<0*2;} //PF0输出模式
//IO操作z
#define IIC_SCL PFout(1) //SCL
#define IIC_SDA PFout(0) //SDA
#define READ_SDA PFin(0) //输入SDA
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
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 KS103_WriteOneByte(u8 address,u8 reg,u8 command);
u8 KS103_ReadOneByte(u8 address, u8 reg);
void Change_IIC_Address(u8 addr_old,u8 addr_new); |