胤幻1988 发表于 2018-6-4 15:14:30

最近用STM32来控制可编程电位器IIC模式,不成功,求帮助!

最近用STM32F103RET6控制MAX公司的可编程电位器DS3502不成功。不知道为何。模拟IIC代码,参考的原子的代码。
下面是IIC的具体代码,用的IIC2.
IIC2的C文件
#include "myiic2.h"
#include "delay.h"
                                                                  
//////////////////////////////////////////////////////////////////////////////////

//初始化IIC2
void IIC2_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);         //PB6,PB7 输出高
}
//产生IIC起始信号
void IIC2_Start(void)
{
        SDA2_OUT();   //sda线输出
        IIC2_SDA=1;                    
        IIC2_SCL=1;
        delay_us(4);
        IIC2_SDA=0;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC2_SCL=0;//钳住I2C总线,准备发送或接收数据
}          
//产生IIC停止信号
void IIC2_Stop(void)
{
//        SDA_OUT();//sda线输出
//        IIC_SCL=0;
//        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
//         delay_us(4);
//        IIC_SCL=1;
//        IIC_SDA=1;//发送I2C总线结束信号
//        delay_us(4);

        SDA2_OUT();   //sda线输出
        IIC2_SCL=0;
        IIC2_SDA=0;   //STOP:when CLK is high DATA change form low to high
                delay_us(4);
        IIC2_SCL=1;
        delay_us(2);   //加入延时
        IIC2_SDA=1;   //发送I2C总线结束信号
        delay_us(4);        
}
//等待应答信号到来
//返回值:1,接收应答失败
//      0,接收应答成功
u8 IIC2_Wait_Ack(void)
{
        u8 ucErrTime=0;
        SDA2_IN();      //SDA设置为输入
        IIC2_SDA=1;delay_us(1);          
        IIC2_SCL=1;delay_us(1);       
        while(READ2_SDA)
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        IIC2_Stop();
                        return 1;
                }
        }
        IIC2_SCL=0;//时钟输出0           
        return 0;
}
//产生ACK应答
void IIC2_Ack(void)
{
        IIC2_SCL=0;
        SDA2_OUT();
        IIC2_SDA=0;
        delay_us(2);
        IIC2_SCL=1;
        delay_us(2);
        IIC2_SCL=0;
}
//不产生ACK应答                  
void IIC2_NAck(void)
{
        IIC2_SCL=0;
        SDA2_OUT();
        IIC2_SDA=1;
        delay_us(2);
        IIC2_SCL=1;
        delay_us(2);
        IIC2_SCL=0;
}                                                                            
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC2_Send_Byte(u8 txd)
{                        
    u8 t;   
        SDA2_OUT();           
    IIC2_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {            
      //IIC_SDA=(txd&0x80)>>7;
                if((txd&0x80)>>7)
                        IIC2_SDA=1;
                else
                        IIC2_SDA=0;
                txd<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                IIC2_SCL=1;
                delay_us(2);
                IIC2_SCL=0;       
                delay_us(2);
    }       
}           
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC2_Read_Byte(unsigned char ack)
{
        unsigned char i,receive=0;
        SDA2_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
      IIC2_SCL=0;
      delay_us(2);
                IIC2_SCL=1;
      receive<<=1;
      if(READ2_SDA)receive++;   
                delay_us(1);
    }                                       
    if (!ack)
      IIC2_NAck();//发送nACK
    else
      IIC2_Ack(); //发送ACK   
    return receive;
}

IIC的h文件:
#ifndef __MYIIC2_H
#define __MYIIC2_H
#include "sys.h"


//IO方向设置PB11

#define SDA2_IN(){GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)8<<12;}
#define SDA2_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)3<<12;}

//IO操作函数       
#define IIC2_SCL    PBout(10) //SCL
#define IIC2_SDA    PBout(11) //SDA       
#define READ2_SDA   PBin(11)//输入SDA

//IIC所有操作函数
void IIC2_Init(void);                //初始化IIC的IO口                               
void IIC2_Start(void);                                //发送IIC开始信号
void IIC2_Stop(void);                                  //发送IIC停止信号
void IIC2_Send_Byte(u8 txd);                        //IIC发送一个字节
u8 IIC2_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC2_Wait_Ack(void);                                 //IIC等待ACK信号
void IIC2_Ack(void);                                        //IIC发送ACK信号
void IIC2_NAck(void);                                //IIC不发送ACK信号

void IIC2_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC2_Read_One_Byte(u8 daddr,u8 addr);          
#endifDS3502的c
#include "DS3502.h"
#include "delay.h"


//硬件上A1,A0都是高电平
//初始化IIC接口
void DS3502_Init(void)
{
        IIC2_Init();
}
//DS3502定地址读出一个数据
//ReadAddr:开始读数的地址
//返回值:读到的数据
u8 DS3502_ReadOneByte(u16 ReadAddr)
{                                  
        u8 temp=0;
        //开始信号       
IIC2_Start();
//发送从机地址       
        IIC2_Send_Byte(0X50+6);   //发送器件地址(不计算读写字BIT)A1,A0均为1,(110B)写数据        
        IIC2_Wait_Ack();
        //发送要读的寄存器地址
IIC2_Send_Byte(ReadAddr%256);   //发送低地址
        IIC2_Wait_Ack();       
//重新开始信号       
        IIC2_Start();
//发送计算写字的       
        IIC2_Send_Byte(0X50+6+1);         //进入接收模式                          
        IIC2_Wait_Ack();
//读取数据       
temp=IIC2_Read_Byte(0);                  
IIC2_Stop();//产生一个停止条件          
        return temp;
}
//在DS3502指定地址写入一个数据
//WriteAddr:写入数据的目的地址   
//DataToWrite:要写入的数据
void DS3502_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{               
        //开始信号       
IIC2_Start();
//发送从机地址
        IIC2_Send_Byte(0X50+6);   //发送器件地址(不计算读写字BIT)A1,A0均为1,(110B)写数据
               
        IIC2_Wait_Ack();
//发送写入的寄存器地址       
IIC2_Send_Byte(WriteAddr%256);   //发送低地址
        IIC2_Wait_Ack();
//发送要写入的数据       
        IIC2_Send_Byte(DataToWrite);   //发送字节                                                          
        IIC2_Wait_Ack();                            
IIC2_Stop();//产生一个停止条件
        delay_ms(10);       
}
DS3502的h文件:
#ifndef __DS3502_H
#define __DS3502_H
#include "myiic2.h"   

u8 DS3502_ReadOneByte(u16 ReadAddr);                                                        //指定地址读取一个字节
void DS3502_WriteOneByte(u16 WriteAddr,u8 DataToWrite);                //指定地址写入一个字节
void DS3502_Init(void); //初始化IICmain 函数
DS3502_WriteOneByte(0X00,43);//0~127
        delay_ms(200);
        CR_Value=DS3502_ReadOneByte(0X00);
        delay_ms(200);反馈的数值一直为256。

硬件上连接



求大神帮忙看下!

发表于 2018-6-4 15:33:45

楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。

胤幻1988 发表于 2018-6-4 15:49:43

安 发表于 2018-6-4 15:33
楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。 ...

谢谢,已解决。代码没问题。硬件上,当时想着一个IO能否驱动8路,就加了个电流驱动增强的芯片。问题就出在它身上。拿掉,就好了。而且8路也能驱动成功!

胤幻1988 发表于 2018-6-4 15:50:47

已解决,结贴!
页: [1]
查看完整版本: 最近用STM32来控制可编程电位器IIC模式,不成功,求帮助!