普中开源电子分享网

 找回密码
 立即注册
搜索
查看: 4291|回复: 1

STM32F103用硬件I2C发送不了起始信号

[复制链接]

1

主题

1

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2020-4-28 20:12:31 | 显示全部楼层 |阅读模式
1金钱
我的STM32系列是PZ6806L,配套视频讲的是模拟I2C。但是我用硬件I2C来对EEPROM操作的时候,总是在起始信号的时候就出现错误。下面是代码麻烦大佬帮忙看看:


头文件I2C_Hardware.h
#ifndef _I2C_Hardware_H
#define _I2C_Hardware_H
#include "stm32f10x.h"
#include "Systick.h"
#include "printf.h"


#define I2C_GPIO GPIOB
#define SCL_Pin        GPIO_Pin_10
#define SDA_Pin        GPIO_Pin_11
#define IIC_CLK        RCC_APB1Periph_I2C2
#define IIC_GPIO_CLK RCC_APB2Periph_GPIOB
#define IIC_Speed        400000        //400K
#define IIC_x        I2C2
#define OwnAddress1        0x0A        //第一个设备自身地址,与STM32的I2C地址不一样即可
#define EE_Address 0xA0                //器件地址


void I2C_EE_Init(void);
void I2C_ByteWrite(u8 address,u8 data);
u8 I2C_ByteRead(u8 address);


#endif


子程序:
#include "I2C_Hardware.h"


void I2C_EE_Init()        //初始化,配置函数
{
        GPIO_InitTypeDef GPIO_InitStructure;                                                //GPIO初始化结构体
        I2C_InitTypeDef I2C_InitStructure;                                                        //I2C初始化结构体
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);        //对应GPIO的时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);         //打开I2C外设时钟
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         //复用开漏输出
        GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
       
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStructure.I2C_OwnAddress1 = 0x0A;       
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_AcknowledgedAddress =
        I2C_AcknowledgedAddress_7bit;
        I2C_InitStructure.I2C_ClockSpeed = IIC_Speed;
        I2C_Init(IIC_x, &I2C_InitStructure);
       
        I2C_Cmd(IIC_x, ENABLE);
}


void I2C_ByteWrite(u8 address,u8 data)        //写一个字节
{
        u8 time=250;
        I2C_GenerateSTART(IIC_x,ENABLE);        //产生一个起始信号
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_MODE_SELECT))        //EV5
        {
                time--;
                if(time==0)
                {
                        printf("写:起始信号的应答错误\r\n");//用串口调试助手的时候,显示“写:起始信号的应答错误”。问题就出在这里
                        return;
                }
        }
        time=250;
       
        I2C_Send7bitAddress(IIC_x,EE_Address,I2C_Direction_Transmitter);        //发送器件地址
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_BYTE_TRANSMITTED))        //EV8
        {
                time--;
                if(time==0)
                {
                        printf("写:器件地址的应答错误\r\n");
                        return;
                }
        }
        time=250;
       
        I2C_SendData(IIC_x,address);        //发送数据地址
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_BYTE_TRANSMITTED))        //EV8
        {
                time--;
                if(time==0)
                {
                        printf("写:数据地址的应答错误\r\n");
                        return;
                }
        }
        time=250;
       
        I2C_SendData(IIC_x,data);        //发送数据
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_BYTE_TRANSMITTED))        //EV8
        {
                time--;
                if(time==0)
                {
                        printf("写:数据的应答错误\r\n");
                        return;
                }
        }
       
        I2C_GenerateSTOP(IIC_x,ENABLE);        //停止信号
}






u8 I2C_ByteRead(u8 address)        //读一个字节
{
        u8 time=250,data;
       
        I2C_GenerateSTART(IIC_x,ENABLE);        //产生一个起始信号
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_MODE_SELECT))        //EV5
        {
                time--;
                if(time==0)
                {
                        printf("读:发送起始信号出现错误\r\n");
                        return 0;
                }
        }
        time=250;
       
        I2C_Send7bitAddress(IIC_x,EE_Address,I2C_Direction_Transmitter);        //发送器件地址
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))        //EV6
        {
                time--;
                if(time==0)
                {
                        printf("读:发送器件地址时出现错误\r\n");
                        return 0;
                }
        }
        time=250;
       
        I2C_SendData(IIC_x,address);        //发送数据地址
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_BYTE_TRANSMITTED))        //EV8
        {
                time--;
                if(time==0)
                {
                        printf("读:发送数据地址时出现错误\r\n");
                        return 0;
                }
        }
        time=250;
       
        I2C_GenerateSTART(IIC_x,ENABLE);        //再次产生起始信号
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_MODE_SELECT))        //EV5
        {
                time--;
                if(time==0)
                {
                        printf("读:再次发送起始信号时出现错误\r\n");
                        return 0;
                }
        }
        time=250;
       
        I2C_Send7bitAddress(IIC_x,EE_Address,I2C_Direction_Receiver);        //发送器件地址---接受方向
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))        //EV6
        {
                time--;
                if(time==0)
                {
                        printf("读:再次发送器件地址时出现错误\r\n");
                        return 0;
                }
        }
        time=250;
       
       
        while(!I2C_CheckEvent(IIC_x,I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
                {
                time--;
                if(time==0)
                {
                        printf("读:接受数据时时出现错误\r\n");
                        return 0;
                }
                }
        }
        data=I2C_ReceiveData(IIC_x);
        I2C_AcknowledgeConfig(IIC_x,DISABLE);
        I2C_GenerateSTOP(IIC_x,ENABLE);        //停止信号
        I2C_AcknowledgeConfig(IIC_x,ENABLE);
        return data;
}




主函数:
#include "public.h"
#include "printf.h"
#include "I2C_Hardware.h"
int main()
{       
        u8 addr=0,data=1;
        printf_Init();        //串口1初始化
        I2C_EE_Init();        //IIC2初始化
        I2C_ByteWrite(addr,data);        //0地址写一个1
        printf("%d地址写一个%d\r\n",addr,data);
        printf("%d地址读出的数据是%d\r\n",addr,I2C_ByteRead(addr));
        while(1)
        {
        }
}



我知道答案 本帖寻求最佳答案回答被采纳后将获得系统奖励10 金钱 , 目前已有0人回答

回复

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|普中开源电子分享网 粤ICP备16123577号-2

GMT+8, 2024-4-25 21:06 , Processed in 0.086077 second(s), 32 queries .

Powered by 论坛搭建 X3.4

Copyright © 2001-2021, Tencent Cloud.

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