OpenEdv-开源电子网

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

IIC时序问题,PCF8574无法输出

[复制链接]

12

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2017-11-5
在线时间
31 小时
发表于 2020-4-24 15:09:26 | 显示全部楼层 |阅读模式
原子哥你好,这两天在学习IO口扩展,用的器件是TI公司的PCF8574芯片,IIC接口,我按照阿波罗上面的例程写一直IO口一直没有电平输出。
微信截图_20200424145904.png
main函数代码
#include "stm32f4xx.h"
#include "sys.h"
#include "led.h"
#include "time.h"
#include "delay.h"
#include "myiic.h"

int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        LED_Init();
        delay_init(168);
        IIC_Init();
        LED=0;
        Timer3_Init(10000,8400);
        PCF8574_WriteOneByte(0xff);
        while(1)               
        {
        }
}

void TIM3_IRQHandler(void)
{
       
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
                LED=~LED;               
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}


IIC部分代码
#include "myiic.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//Mini STM32开发板
//IIC 驱动函数          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2010/6/10
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 正点原子 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////           

void IIC_Init(void)
{                       
  GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
       
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  IIC_SCL=1;IIC_SDA=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;
        IIC_SDA=1;//发送I2C总线结束信号
        delay_us(10);                                                                  
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
        u8 ucErrTime=0;
        SDA_IN();      //SDA设置为输入  
        IIC_SDA=1;delay_us(1);          
        IIC_SCL=1;delay_us(1);         
        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(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}
//不产生ACK应答                    
void IIC_NAck(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        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);   //对TEA5767这三个延时都是必须的
                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(2);
                IIC_SCL=1;
                receive<<=1;
                if(READ_SDA)receive++;   
                delay_us(1);
  }                                         
        if (!ack)
                        IIC_NAck();//发送nACK
        else
                        IIC_Ack(); //发送ACK   
        return receive;
}

void PCF8574_WriteOneByte(u8 DataToWrite)
{
        IIC_Start();  
  IIC_Send_Byte(0x40|0X00);   //发送器件地址0X40,写数据          
        IIC_Wait_Ack();                                                                                                                
        IIC_Send_Byte(DataToWrite);                     //发送字节                                                          
        IIC_Wait_Ack();      
  IIC_Stop();                                                        //产生一个停止条件
        delay_ms(10);         
}

不知道是IIC时序不对还是什么原因,我想让8个端口都输出高电平,却一直没有。
微信截图_20200424150450.png 微信截图_20200424150432.png 微信截图_20200424150416.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14404
金钱
14404
注册时间
2018-8-3
在线时间
1156 小时
发表于 2020-4-24 15:56:06 | 显示全部楼层
iic的头文件 有修改对应的IO嘛
回复 支持 反对

使用道具 举报

12

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2017-11-5
在线时间
31 小时
 楼主| 发表于 2020-4-24 16:03:14 | 显示全部楼层
翼行园子 发表于 2020-4-24 15:56
iic的头文件 有修改对应的IO嘛

修改了的 单片机上是接的PB6和PB7
//IO方向设置
#define SDA_IN()  {GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=0<<(7*2);}//输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=1<<(7*2);}//输出模式

//IO操作函数         
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA         
#define READ_SDA   PBin(7)  //输入SDA
回复 支持 反对

使用道具 举报

12

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2017-11-5
在线时间
31 小时
 楼主| 发表于 2020-5-6 14:02:57 | 显示全部楼层
问题已解决,原因是这个芯片的输出电流很小,用这个器件的IO用来驱动三极管来控制继电器时,驱动电流不够导致电压被拉低
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-2 01:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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