打印

模拟IIC为什么通信不了,结果要么是00要么是FF

[复制链接]
357|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
菊江先生|  楼主 | 2018-7-6 17:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下为.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 "mytype.h"
#include "sys.h"
//超声波任务开启函数
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);

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

446

主题

447

帖子

0

粉丝