LMP91000是一个可编程的模拟前端,用于微功率电化学传感器。值得注意的是,该芯片的浓度数据不是通过IIC读取的,而是通过ADC口读取到的,和传感器数据采集有些类似;IIC只是用来设置LMP91000芯片中寄存器的数值。以下是LMP91000芯片的驱动代码。
1. LMPIIC.H
#ifndef __LMPIIC_H
#define __LMPIIC_H
#include
#include "stm32f10x_i2c.h"
#include "delay.h"
#include "public.h"
/***************************************IO方向设置**********************************************/
#define LMP_SDA_IN(){GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
#define LMP_SDA_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=2<<12;} //1 - 10MHZ2 - 2MHZ3- 50MHZ
/***************************************IO操作函数**********************************************/
#define LMP_IIC_REF_EN PBout(13) //REF_EN
#define LMP_IIC_MENB PAout(12) //MENB
#define LMP_IIC_SCL PBout(10) //SCL
#define LMP_IIC_SDA PBout(11) //SDA
#define LMP_READ_SDA PBin(11) //输入SDA
#define LMP_WRITE_ADDE 0x90 //LMP地址+写操作
#define LMP_READ_ADDE 0x91 //LMP地址+读操作
#define LMP_REG1_ADDE 0x00 //LMP寄存器1地址0x00
#define LMP_REG2_ADDE 0x01 //LMP寄存器2地址0x01
#define LMP_REG3_ADDE 0x10 //LMP寄存器3地址0x10
#define LMP_REG4_ADDE 0x11 //LMP寄存器4地址0x11
#define LMP_REG5_ADDE 0x12 //LMP寄存器5地址0x12
#define LMP_REG2_UNLOCK 0x00 //LMP寄存器2中的数据0x00
#define LMP_REG2_LOCK 0x01 //LMP寄存器2中的数据0x01
#define LMP_REG3_DATA 0x0F //LMP寄存器3中的数据0x0E
#define LMP_REG4_DATA 0xB0 //LMP寄存器4中的数据0xB0
#define LMP_REG5_DATA 0x07 //LMP寄存器5中的数据0x07/03
/*************************************IIC所有操作函数*******************************************/
void LMP_IIC_Init_Func(void); //初始化IIC的IO口
void LMP_IIC_Start(void); //发送IIC开始信号
void LMP_IIC_Stop(void); //发送IIC停止信号
u8 LMP_IIC_Wait_Ack(void); //IIC等待ACK信号
void LMP_IIC_Ack(void); //IIC发送ACK信号
void LMP_IIC_NAck(void); //IIC不发送ACK信号
void LMP_IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 LMP_IIC_Read_Byte(u8 ack); //IIC读取一个字节
void LMP_Init_Func(void); //ADS初始化函数
u16LMP_Read_Func(void); //ADS读取函数
#endif
2. LMPIIC.C
/************************************************************************************************
** 函数名称:LMP_IIC_Init_Func
** 输入参数:无
** 输出参数:无
** 功能描述:初始化IIC的IO口以及调用ADS初始化函数
************************************************************************************************/
void LMP_IIC_Init_Func(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//PB10--SCLPB11--SDAPB13--REF_EN(LMP91000使用外部供电,供电使能位;也可选择使用内部供电)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//PA12--MENB
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB1--LMP91000数据采集
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOB, &GPIO_InitStructure);
LMP_IIC_REF_EN = 1;
LMP_IIC_SCL=1;
LMP_IIC_SDA=1;
LMP_Init_Func();
}
/************************************************************************************************
** 函数名称:LMP_IIC_MENB
** 输入参数:无
** 输出参数:无
** 功能描述:产生IIC起始信号
************************************************************************************************/
void LMP_IIC_Start(void)
{
LMP_IIC_MENB = 0;//MEBN拉低
delay_us(4);
LMP_SDA_OUT(); //sda线输出
LMP_IIC_SDA=1;
LMP_IIC_SCL=1;
delay_us(4);
LMP_IIC_SDA=0; //START:when CLK is high,DATA change form high to low
delay_us(4);
LMP_IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
}
/************************************************************************************************
** 函数名称:LMP_IIC_Stop
** 输入参数:无
** 输出参数:无
** 功能描述:产生IIC停止信号
************************************************************************************************/
void LMP_IIC_Stop(void)
{
LMP_SDA_OUT(); //sda线输出
LMP_IIC_SCL=0;
delay_us(4);
LMP_IIC_SDA=0; //STOP:when CLK is high DATA change form low to high
delay_us(4);
LMP_IIC_SCL=1;
delay_us(4);
LMP_IIC_SDA=1; //发送I2C总线结束信号
delay_us(4);
LMP_IIC_MENB = 1;//MEBN拉高
}
/************************************************************************************************
** 函数名称:LMP_IIC_Wait_Ack
** 输入参数:无
** 输出参数:返回值 1,接收应答失败
** 0,接收应答成功
** 功能描述:等待应答信号到来
************************************************************************************************/
u8 LMP_IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
LMP_SDA_IN(); //SDA设置为输入
LMP_IIC_SDA=1;
delay_us(1);
LMP_IIC_SCL=1;
delay_us(1);
while(LMP_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
LMP_IIC_Stop();
return 1;
}
}
LMP_IIC_SCL=0;//时钟输出0
return 0;
}
/************************************************************************************************
** 函数名称:LMP_IIC_Ack
** 输入参数:无
** 输出参数:无
** 功能描述:产生ACK应答
************************************************************************************************/
void LMP_IIC_Ack(void)
{
LMP_IIC_SCL=0;
LMP_SDA_OUT();
LMP_IIC_SDA=0;
delay_us(2);
LMP_IIC_SCL=1;
delay_us(2);
LMP_IIC_SCL=0;
}
/************************************************************************************************
** 函数名称:LMP_IIC_NAck
** 输入参数:无
** 输出参数:无
** 功能描述:不产生ACK应答
************************************************************************************************/
void LMP_IIC_NAck(void)
{
LMP_IIC_SCL=0;
LMP_SDA_OUT();
LMP_IIC_SDA=1;
delay_us(2);
LMP_IIC_SCL=1;
delay_us(2);
LMP_IIC_SCL=0;
}
/************************************************************************************************
** 函数名称:LMP_IIC_Send_Byte
** 输入参数:txd:发送数据
** 输出参数:无
** 功能描述:IIC发送一个字节。
************************************************************************************************/
void LMP_IIC_Send_Byte(u8 txd)
{
u8 t;
LMP_SDA_OUT();
LMP_IIC_SCL=0; //拉低时钟开始数据传输
for(t=0;t<8;t++)
{
LMP_IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对LMP91000这三个延时都是必须的
LMP_IIC_SCL=1;
delay_us(2);
LMP_IIC_SCL=0;
delay_us(2);
}
LMP_IIC_SDA = 0;
}
/************************************************************************************************
** 函数名称:LMP_IIC_Read_Byte
** 输入参数:ack: = 1时,发送ACK
** = 0时,发送nACK
** 输出参数:返回读取IIC中的数据。
** 功能描述:IIC读取一个字节。
************************************************************************************************/
u8 LMP_IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
LMP_SDA_IN(); //SDA设置为输入
for(i=0;i<8;i++ )
{
LMP_IIC_SCL=0;
delay_us(2);
LMP_IIC_SCL=1;
receive<<=1;
if(LMP_READ_SDA)
receive++;
delay_us(1);
}
if (!ack)
LMP_IIC_NAck();//发送nACK
else
LMP_IIC_Ack(); //发送ACK
return receive;
}
/************************************************************************************************
** 函数名称:LMP_Init_Func
** 输入参数:无
** 输出参数:无
** 功能描述:通过IIC初始化ADS设置寄存器的值
************************************************************************************************/
void LMP_Init_Func(void)
{
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址 LMP+写操作位90
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG2_ADDE); //发送寄存器地址2 01
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG2_UNLOCK); //发送寄存器地址2中需要写入的数据
LMP_IIC_Wait_Ack();
LMP_IIC_Stop();
delay_us(8);
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG3_ADDE); //发送寄存器地址2 10
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG3_DATA); //发送寄存器地址2中需要写入的数据
LMP_IIC_Wait_Ack();
LMP_IIC_Stop();
delay_us(8);
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG4_ADDE); //发送寄存器地址2 11
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG4_DATA); //发送寄存器地址2中需要写入的数据
LMP_IIC_Wait_Ack();
LMP_IIC_Stop();
delay_us(8);
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG5_ADDE); //发送寄存器地址2 12
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG5_DATA); //发送寄存器地址2中需要写入的数据
LMP_IIC_Wait_Ack();
LMP_IIC_Stop();
delay_us(8);
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址 LMP+写操作位
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG2_ADDE); //发送寄存器地址2 01
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG2_LOCK); //发送寄存器地址2中需要写入的数据
LMP_IIC_Wait_Ack();
LMP_IIC_Stop(); //产生一个停止条件
delay_ms(10);
}
/************************************************************************************************
** 函数名称:LMP_Read_Func
** 输入参数:无
** 输出参数:返回读取的ADS中数据
** 功能描述:通过IIC读取ADS数据寄存器的值
************************************************************************************************/
u16 LMP_Read_Func(void)
{
unsigned charun8Date;
un8Date = 0;
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_WRITE_ADDE); //发送LMP91000地址
LMP_IIC_Wait_Ack();
LMP_IIC_Send_Byte(LMP_REG3_ADDE); //发送寄存器地址00
LMP_IIC_Wait_Ack();
LMP_IIC_Stop();
LMP_IIC_Start();
LMP_IIC_Send_Byte(LMP_READ_ADDE); //发送LMP91000地址
LMP_IIC_Wait_Ack();
un8Date = LMP_IIC_Read_Byte(0);
LMP_IIC_Stop(); //产生一个停止条件
return (un8Date);
}
3. MAIN.C
int main(void)
{
delay_init(24); //延时初始化函数
RCC_Configuration(); //始终初始化函数
IIC_Init_Func(); //IIC初始化函数
LMP_IIC_Init_Func();
while (1)
{
G_un16ADCValue4 = ADC_Average(G_un16ADC_ConValue,3);
G_un16V4Value4= (unsigned int)((unsigned long)G_un16ADCValue4 * 2480/4096);
G_un16LMPValue = LMP_Read_Func();
}
}