今天时间有限我就只贴代码了
myiic.c
#include "myi2c.h"//IIC.SCL->GPIOB6
//IIC.SDA->GPIOB7void IIC_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);IIC_SCL(1);IIC_SDA(1);
}void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}void SDA_OUT(void)
{ GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}void IIC_Start(void)
{SDA_OUT(); 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);
} void IIC_Stop(void)
{SDA_OUT();IIC_SCL(0);IIC_SDA(0);//STOP:when CLK is high DATA change form low to highdelay_us(10);IIC_SCL(1); IIC_SDA(1);delay_us(10);
}uint8_t IIC_Wait_Ack(void)
{uint8_t ucErrTime=0;SDA_IN(); IIC_SDA(1);delay_us(2); IIC_SCL(1);delay_us(2); while(IIC_SDAIN){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL(0); return 0;
} void IIC_Ack(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(0);delay_us(5);IIC_SCL(1);delay_us(5);IIC_SCL(0);
}void IIC_NAck(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(1);delay_us(5);IIC_SCL(1);delay_us(5);IIC_SCL(0);
} void IIC_Send_Byte(uint8_t txd)
{ uint8_t t; SDA_OUT(); IIC_SCL(0);for(t=0;t<8;t++) { if((txd&0x80)>>7)IIC_SDA(1);elseIIC_SDA(0);txd<<=1; delay_us(5); IIC_SCL(1);delay_us(5); IIC_SCL(0); delay_us(5);}
} uint8_t IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();for(i=0;i<8;i++ ){IIC_SCL(0); delay_us(5);IIC_SCL(1);receive<<=1;if(IIC_SDAIN)receive++; delay_us(4); } if (!ack)IIC_NAck();elseIIC_Ack(); //产生ACK return receive;
}
myiic.h
#ifndef _MYI2C_H
#define _MYI2C_H#include "main.h"
#include "delay.h"#define IIC_SCL(x) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,(GPIO_PinState)(x)) //IIC.SCL->GPIOB6
#define IIC_SDA(x) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,(GPIO_PinState)(x)) //IIC.SDA->GPIOB7
#define IIC_SDAIN HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Send_Byte(uint8_t txd);
uint8_t IIC_Read_Byte(unsigned char ack);
uint8_t IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void); void SDA_IN(void);
void SDA_OUT(void);#endif
mcp4725.c
#include "MCP4725.h"void MCP4725_Init(void)
{IIC_Init();
}//使用快速模式写命令写DAC寄存器
void MCP4725_WriteData_Voltage(uint16_t Vout) //电压单位mV (max:3299)
{uint8_t temp;uint16_t Dn;Dn = (4096*Vout)/VREF; temp = (0x0F00 & Dn) >> 8; //12位数据。0000XXXX XXXXXXXX IIC_Start();IIC_Send_Byte(0XC0); //器件寻址,器件代码:1100; 地址位A2,A1,A0为 0 , 0 , 0;-> 1100 0000IIC_Wait_Ack(); IIC_Send_Byte(temp); //将高8位送到DAC寄存器IIC_Wait_Ack(); IIC_Send_Byte(Dn); //将低8位送到DAC寄存器IIC_Wait_Ack(); IIC_Stop(); //产生一个停止条件 delay_ms(10);
}void MCP4725_WriteData_Digital(uint16_t data) //12位数字量 (max:4095)
{uint8_t data_H=0,data_L=0;data_H = ( 0x0F00 & data) >> 8;data_L = 0X00FF & data ;IIC_Start(); //20usIIC_Send_Byte(0XC0); //器件寻址,器件代码:1100; 地址位A2,A1,A0为 0 , 0 , 0;-> 1100 0000 15usIIC_Wait_Ack(); //5usIIC_Send_Byte(data_H); IIC_Wait_Ack(); IIC_Send_Byte(data_L);IIC_Wait_Ack(); IIC_Stop(); //产生一个停止条件 20usdelay_us(10);
}
mcp4725.h
#ifndef __Mcp4725_H
#define __Mcp4725_H#include "Myi2c.h"
#include "Delay.h"#define VREF 3300void MCP4725_Init(void);
void MCP4725_WriteData_Digital(uint16_t data);
void MCP4725_WriteData_Voltage(uint16_t Vout);#endif
软件IIC就是移植得快,我试过很多次了这个能用。