OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2336|回复: 2

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

[复制链接]

3

主题

4

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2019-11-27
在线时间
2 小时
发表于 2019-11-30 21:32:10 | 显示全部楼层 |阅读模式
以下为.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);




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
发表于 2019-12-1 14:15:00 | 显示全部楼层
回复 支持 反对

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2019-12-1 15:26:06 | 显示全部楼层
SDA管脚要配置开漏上拉模式  而不是PP模式
让我们的思维驾驭在电的速度之上!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 23:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表