最近用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。
硬件上连接
求大神帮忙看下!
楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。 安 发表于 2018-6-4 15:33
楼主,光从代码上分析不出什么太大问题,建议通过I2C总线波形进行一下判断。 ...
谢谢,已解决。代码没问题。硬件上,当时想着一个IO能否驱动8路,就加了个电流驱动增强的芯片。问题就出在它身上。拿掉,就好了。而且8路也能驱动成功! 已解决,结贴!
页:
[1]