esp8266|pcf8951 ad/da(iic)转换模块 在 esp8266下的实现

adc.h #ifndef __ADC_H__
#define __ADC_H__
#include "Gpio.h"//GPIO头文件
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "user_devicefind.h"
#include "user_webserver.h"

#include "driver/gpio16.h"//GPIO16头文件
#include "Gpio.h"//GPIO头文件
#define SDAPINGPIO_ID_PIN(14)
#define SCLPINGPIO_ID_PIN(12)
#define SCLNAMEPERIPHS_IO_MUX_MTDI_U
#define SDANAME PERIPHS_IO_MUX_MTMS_U
#define SDAL GPIO_OUTPUT_SET(SDAPIN,0)
#define SCLLGPIO_OUTPUT_SET(SCLPIN,0)
#define SDAH GPIO_OUTPUT_SET(SDAPIN,1)
#define SCLHGPIO_OUTPUT_SET(SCLPIN,1)
#define SDARGPIO_INPUT_GET(SDAPIN)
void IICio_init();
//引脚初始化
void Start_I2c();
//结束总线函数
void Stop_I2c();
//应答子函数
void Ack_I2c(char a);
//字节数据发送函数
voidSendByte(unsigned charc);
//有子地址发送多字节数据函数
char ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) ;
//无子地址发送多字节数据函数
char ISendStrExt(unsigned char sla,unsigned char *s,unsigned char no);
//无子地址读字节数据函数
unsigned char RcvByte();
char DACconversion(unsigned char sla,unsigned char c,unsigned char Val);
#endif




adc.c

#include"adc.h"
#define NOP os_delay_us
char ack=1; /*应答标志位*/

void IICio_init()
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12); //SCL
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U,FUNC_GPIO14); //SDA
}
/**************************************************
开始信号
************************************************/
void Start_I2c()
{
SDAH;
NOP(1);
SCLH;
NOP(5);
SDAL;
NOP(5);
SCLL;
NOP(2);
}

/**************************************************
结束信号
************************************************/
void Stop_I2c()
{
SDAL;
NOP(1);
SCLH;
NOP(5);
SDAH;
NOP(4);
}

/*******************************************************************
字节数据发送函数
函数原型: voidSendByte(UCHAR c);
功能:将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
voidSendByte(unsigned charc)
{
unsigned charBitCnt;
SCLL;

for(BitCnt=0; BitCnt<8; BitCnt++)/*要传送的数据长度为8位*/
{
if((c<elseSDAL;
NOP(5);
SCLH; /*置时钟线为高,通知被控器开始接收数据位*/
NOP(5); /*保证时钟高电平周期大于4μs*/
SCLL;
NOP(10);
}
NOP(3);
SDAH; /*8位发送完后释放数据线,准备接收应答位*/
NOP(2);
SCLH;
NOP(7);
if(SDAR == 0) ack=1;
else ack=0; /*判断是否接收到应答信号*/
SCLL;
NOP(2);

}
/*******************************************************************
字节数据接收函数
函数原型: UCHARRcvByte();
功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
unsigned charRcvByte()
{
unsigned charretc;
unsigned charBitCnt;

retc=0;
SDAH; /*置数据线为输入方式*/
for(BitCnt=0; BitCnt<8; BitCnt++)
{
NOP(1);
SCLL; /*置时钟线为低,准备接收数据位*/
NOP(5);
SCLH; /*置时钟线为高使数据线上数据有效*/
NOP(2);
retc=retc<<1;
if(SDAR != 0) retc=retc+1; /*读数据位,接收的数据位放入retc中 */
NOP(2);
}
SCLL;
NOP(2);
return(retc);
}

/********************************************************************
应答子函数
函数原型:void Ack_I2c(bit a);
功能:主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(char a)
{

if(a==0) SDAL; /*在此发出应答或非应答信号 */
else SDAH;
NOP(3);
SCLH;
NOP(5); /*时钟低电平周期大于4μs*/
SCLL; /*清时钟线,钳住I2C总线以便继续接收*/
NOP(2);
}




/*******************************************************************
DAC 变换, 转化函数
*******************************************************************/
char DACconversion(unsigned char sla,unsigned char c,unsigned char Val)
{
Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
SendByte(c); //发送控制字节
if(ack==0)return(0);
SendByte(Val); //发送DAC的数值
if(ack==0)return(0);
Stop_I2c(); //结束总线
return(1);
}

/*******************************************************************
ADC发送字节[命令]数据函数
*******************************************************************/
char ISendByte(unsigned char sla,unsigned char c)
{

Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1);
SendByte(c); //发送数据
if(ack==0)return(0);
Stop_I2c(); //结束总线
GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);
return(1);
}
/*******************************************************************
ADC读字节数据函数
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
{unsigned char c;
Start_I2c(); //启动总线
SendByte(sla+1); //发送器件地址
if(ack==0)return(0);
c=RcvByte(); //读取数据0
Ack_I2c(1); //发送非就答位
Stop_I2c(); //结束总线
return(c);
}


    推荐阅读