栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32F103 KS103超声波IIC实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32F103 KS103超声波IIC实现

一.看图模拟IIC

1.宏定义io和初始化io

#define  IIC_SCL_PORT      		GPIOC
#define  IIC_SCL_PIN       		GPIO_Pin_3
#define  IIC_SCL_L              GPIO_ResetBits(IIC_SCL_PORT, IIC_SCL_PIN)
#define  IIC_SCL_H              GPIO_SetBits(IIC_SCL_PORT, IIC_SCL_PIN)

#define  IIC_SDA_PORT      		GPIOC
#define  IIC_SDA_PIN       		GPIO_Pin_2
#define  IIC_READ_SDA           GPIO_ReadInputDataBit(IIC_SDA_PORT,IIC_SDA_PIN)
#define  IIC_SDA_L              GPIO_ResetBits(IIC_SDA_PORT, IIC_SDA_PIN)
#define  IIC_SDA_H              GPIO_SetBits(IIC_SDA_PORT, IIC_SDA_PIN)


void iic_sda_out(void)
{
	  GPIO_InitTypeDef  GPIO_InitStructure;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	  GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;                   
	  GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
}


void iic_sda_in(void)
{
	  GPIO_InitTypeDef  GPIO_InitStructure;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	  GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;                   
	  GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
}


void iic_init(void)
{
	  GPIO_InitTypeDef  GPIO_InitStructure;

	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD
														| RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
	
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
	  GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;                   
	  GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure);
	  IIC_SCL_H;
	  GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;                   
	  GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
	  IIC_SDA_H;
}

2.模拟:启动信号 停止信号
起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。
停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。

![在这里插入图片描述](https://img-blog.csdnimg.cn/a0c4631f8dc94d76b43cd4274bc4ba52.png

void iic_start(void)
{
	iic_sda_out();//sda线输出
	IIC_SDA_H;	  	  
	IIC_SCL_H;
	delay_us(10);
 	IIC_SDA_L;//start:when CLK is high,DATA change form high to low 
	delay_us(10);
	IIC_SCL_L;//钳住I2C总线,准备发送或接收数据 
}



void iic_stop(void)
{
	iic_sda_out();//sda线输出
	IIC_SCL_L;
	IIC_SDA_L;//stop:when SCL is high,DATA change form low to high
 	delay_us(10);
	IIC_SCL_H;
	delay_us(2);
	IIC_SDA_H;
	delay_us(10);						   	
}

3.模拟:应答信号 、非应答信号、等待应答信号
发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。(大白话理解应答:A向B读取数据,A是接收数据者,B是发送数据者。A接收完一个8位数据后,要发送一个信号告诉B让它结束发送。该信号分高电平和低电平,A是发送应答,B是等待应答)


void iic_ack(void)
{
	IIC_SCL_L;
	iic_sda_out();
	IIC_SDA_L;
	delay_us(10);
	IIC_SCL_H;
	delay_us(10);
	IIC_SCL_L;
}
 
   
void iic_nack(void)
{
	IIC_SCL_L;
	iic_sda_out();
	IIC_SDA_H;
	delay_us(10);
	IIC_SCL_H;
	delay_us(10);
	IIC_SCL_L;
}

       
 
u8 iic_wait_ack(void)
{
	 u8 wait_time=0;
	  
	 IIC_SDA_H;	  
	 delay_us(6); 
	 IIC_SCL_H;	 
	 delay_us(6);
	 iic_sda_in();  //SDA设置为输入	
	 while(IIC_READ_SDA)
	 {
		 wait_time++;
		 if(wait_time>250)
		 {
			 iic_stop();
			 return 1;
		 }
	 }
	 IIC_SCL_L;	   
	 return 0;  
}

4.模拟:发送数据、接收数据
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
即:数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。

 
void iic_send_byte(u8 data)
{                        
    u8 pnext;   
    iic_sda_out(); 	    
    IIC_SCL_L;
    for(pnext=0;pnext<8;pnext++)
    {      
	     
	     if((data&0x80)>>7){IIC_SDA_H;}
	     else{IIC_SDA_L;}
	     data<<=1; 	
	     delay_us(10);   
	     IIC_SCL_H;
	     delay_us(10); 
	     IIC_SCL_L; 	
	     delay_us(10);
    }	 
} 


 
  
u8 iic_read_byte(u8 ack)
{
		u8 pnext,receive=0;
		iic_sda_in();//SDA设置为输入
		for(pnext=0;pnext<8;pnext++ )
		{
         IIC_SCL_L; 
         delay_us(10);
         IIC_SCL_H;
         receive<<=1;
         if(IIC_READ_SDA)receive++;   
         delay_us(5); 
		}					 
		if (!ack)
        iic_nack();//发送nACK
		else
        iic_ack(); //发送ACK   
		return receive;
}
二KS103探测距离

1.官网手册地址如下:http://www.dauxi.com/KS10X-V110_CN.pdf

2.读取探测结果和开始探测

  
u8 ks103_readonebyte(u8 addr, u8 reg)
{
	 u8 result=0;
	 iic_start();
	 iic_send_byte(addr); 
	 iic_wait_ack();
	 iic_send_byte(reg); 
	 iic_wait_ack();
	 iic_start();
	 iic_send_byte(addr+ 1); 
	 iic_wait_ack();
	 delay_us(50); 
	 result=iic_read_byte(0); 
	 iic_stop();
	 return result;
}


 
void ks103_writeonebyte(u8 addr,u8 reg,u8 cmd)
{
	 iic_start();
	 iic_send_byte(addr); 
	 iic_wait_ack();
	 iic_send_byte(reg);
	 iic_wait_ack();
	 iic_send_byte(cmd); 
	 iic_wait_ack();
	 iic_stop();
}



void ks103_change_addr(u8 source, u8 destin)
{
		 ks103_writeonebyte(source,0x02,0x9a);
		 delay_ms(5);
		 ks103_writeonebyte(source,0x02,0x92);
		 delay_ms(5);
		 ks103_writeonebyte(source,0x02,0x9e);
		 delay_ms(5);
		 ks103_writeonebyte(source,0x02,destin);
		 delay_ms(500);
}




  
 u16 result_distance=0;
 u8 distance_h=0;
 u8 distance_l=0;
 
void main(void)
{

	  iic_init();
	  
		while(1)
		{
	 		    ks103_writeonebyte(0xE8,0x02,0xb0);
	 		    delay_ms(50);
	 		    distance_h = ks103_readonebyte(0xE8, 0x02);
	 		    distance_l= ks103_readonebyte(0xE8, 0x03);
	 		    result_distance=distance_h<<8 |distance_l;
	 		    delay_ms(50);
		}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917051.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号