用模拟IIC写的代码,用串口上传到串口调试助手显示啊,希望对大家有帮助!
.C与.H上如下。
#ifndef BMP085_H
#define BMP085_H
#include <ioCC2530.h>
#define uint unsigned int
#define uchar unsigned char
#define u8 unsigned char
#define OSS 0 // BMP085使用
//定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
#define BMP085_Addr 0xee //气压传感器器件地址
unsigned char BUF[8]; //接收数据缓存区
int x,y;
float angle;
extern uchar ge,shi,bai,qian,wan,shiwan; //显示变量
int A_X,A_Y,A_Z;
short T_X,T_Y,T_Z;
short data_xyz[3];
float Roll,Pitch,Q,T,K;
//***BMP085使用
short ac1;
short ac2;
short ac3;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1;
short b2;
short mb;
short mc;
short md;
extern long temperature;
extern long pressure;
/*模拟IIC端口输出输入定义*/
//IO方向设置
#define SDA_IN() {P0DIR &=0xfd;}
#define SDA_OUT() {P0DIR |=0x02;}
//IO操作函数
#define SCL P0_0 //SCL
#define SDA P0_1 //SDA
#define SDA_read P0_1 //输入SDA
void delay1us(void); //1 us延时
void delay10us(void); //10 us延时
void delay_xms(uint Time);//n ms延时
void conversion(long temp_data);
void I2C_Init(void);
void I2C_delay(void);
void delay5ms(void);
uchar I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NoAck(void);
uchar I2C_WaitAck(void); //返回为:=1有ACK,=0无ACK
void I2C_SendByte(u8 SendByte); //数据从高位到低位//
unsigned char I2C_RadeByte(void); //数据从高位到低位//
uchar Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);
unsigned char Single_Read(uchar SlaveAddress,uchar REG_Address);
long bmp085ReadTemp(void);
long bmp085ReadPressure(void);
void Init_BMP085(void);
void read_BMP085(void);
void Send_BMP085(void);
#endif
#include <BMP085.h>
#include "hal_button.h"
uchar ge,shi,bai,qian,wan,shiwan;
long temperature;
long pressure;
void delay1us(void) //1 us延时
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
void delay10us(void) //10 us延时
{
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
delay1us();
}
void delay_xms(uint Time)//n ms延时
{
unsigned char i;
while(Time--)
{
for(i=0;i<100;i++)
delay10us();
}
}
void conversion(long temp_data)
{
shiwan=temp_data/100000+0x30 ;
temp_data=temp_data%100000; //取余运算
wan=temp_data/10000+0x30 ;
temp_data=temp_data%10000; //取余运算
qian=temp_data/1000+0x30 ;
temp_data=temp_data%1000; //取余运算
bai=temp_data/100+0x30 ;
temp_data=temp_data%100; //取余运算
shi=temp_data/10+0x30 ;
temp_data=temp_data%10; //取余运算
ge=temp_data+0x30;
}
//初始化IIC
void I2C_Init(void)
{
P1SEL &= ~0x03; //P0_0、P0_1定义为普通IO口
P1DIR |= 0x03; //P0_0、P0_1定义为输出
P1INP &= ~0x03; //打开P0_0、P0_1上拉
}
void I2C_delay(void)
{
u8 i=30; //这里可以优化速度 ,经测试最低到5还能写入
while(i)
{
i--;
}
}
uchar I2C_Start(void)
{
SDA_OUT();
SDA=1;
SCL=1;
I2C_delay();
SDA_IN();
if(!SDA_read)return 0; //SDA线为低电平则总线忙,退出
SDA_OUT();
SDA=0;
I2C_delay();
SDA_IN();
if(SDA_read) return 0; //SDA线为高电平则总线出错,退出
SDA_OUT();
SDA=0;
I2C_delay();
return 1;
}
void I2C_Stop(void)
{
SDA_OUT();
SCL=0;
I2C_delay();
SDA=0;
I2C_delay();
SCL=1;
I2C_delay();
SDA=1;
I2C_delay();
}
void I2C_Ack(void)
{
SDA_OUT();
SCL=0;
I2C_delay();
SDA=0;
I2C_delay();
SCL=1;
I2C_delay();
SCL=0;
I2C_delay();
}
void I2C_NoAck(void)
{
SDA_OUT();
SCL=0;
I2C_delay();
SDA=1;
I2C_delay();
SCL=1;
I2C_delay();
SCL=0;
I2C_delay();
}
uchar I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SDA_OUT();
SCL=0;
I2C_delay();
SDA=1;
I2C_delay();
SCL=1;
I2C_delay();
SDA_IN();
if(SDA_read)
{
SCL=0;
I2C_delay();
return 0;
}
SCL=0;
I2C_delay();
return 1;
}
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i=8;
SDA_OUT();
while(i--)
{
SCL=0;
I2C_delay();
if(SendByte&0x80)
SDA=1;
else
SDA=0;
SendByte<<=1;
I2C_delay();
SCL=1;
I2C_delay();
}
SCL=0;
}
unsigned char I2C_RadeByte(void) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0;
SDA_OUT();
SDA=1;
while(i--)
{
ReceiveByte<<=1;
SCL=0;
I2C_delay();
SCL=1;
I2C_delay();
SDA_IN();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL=0;
return ReceiveByte;
}
//单字节写入*******************************************
uchar Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data) //void
{
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return 0;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
delay_xms(5);
return 0;
}
//单字节读取*****************************************
unsigned char Single_Read(uchar SlaveAddress,uchar REG_Address)
{
unsigned char REG_data;
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return 0;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
REG_data= I2C_RadeByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
}
long bmp085ReadTemp(void)
{
short temp_ut;
Single_Write(BMP085_Addr,0xF4,0x2E);
delay_xms(3); // max time is 4.5ms
temp_ut = Single_Read(BMP085_Addr,0xF6);
temp_ut = (temp_ut<<8)| Single_Read(BMP085_Addr,0xF7);
return (long) temp_ut ;
}
long bmp085ReadPressure(void)
{
long pressure = 0;
Single_Write(BMP085_Addr,0xF4,0x34);
delay_xms(3); // max time is 4.5ms
pressure = Single_Read(BMP085_Addr,0xF6);
pressure = (pressure<<8)| Single_Read(BMP085_Addr,0xF7);
pressure &= 0x0000FFFF;
return pressure;
}
void Init_BMP085(void)
{
ac1 = Single_Read(BMP085_Addr,0xAA);
ac1 = (ac1<<8)|Single_Read(BMP085_Addr,0xAB);
ac2 = Single_Read(BMP085_Addr,0xAC);
ac2 = (ac2<<8)| Single_Read(BMP085_Addr,0xAD);
ac3 = Single_Read(BMP085_Addr,0xAE);
ac3 = (ac3<<8)| Single_Read(BMP085_Addr,0xAF);
ac4 = Single_Read(BMP085_Addr,0xB0);
ac4 = (ac4<<8)| Single_Read(BMP085_Addr,0xB1);
ac5 = Single_Read(BMP085_Addr,0xB2);
ac5 = (ac5<<8)| Single_Read(BMP085_Addr,0xB3);
ac6 = Single_Read(BMP085_Addr,0xB4);
ac6 = (ac6<<8)| Single_Read(BMP085_Addr,0xB5);
b1 = Single_Read(BMP085_Addr,0xB6);
b1 = (b1<<8)| Single_Read(BMP085_Addr,0xB7);
b2 = Single_Read(BMP085_Addr,0xB8);
b2 = (b2<<8)| Single_Read(BMP085_Addr,0xB9);
mb = Single_Read(BMP085_Addr,0xBA);
mb = (mb<<8)| Single_Read(BMP085_Addr,0xBB);
mc = Single_Read(BMP085_Addr,0xBC);
mc = (mc<<8)| Single_Read(BMP085_Addr,0xBD);
md = Single_Read(BMP085_Addr,0xBE);
md = (md<<8)| Single_Read(BMP085_Addr,0xBF);
}
void read_BMP085(void) //读取温度与湿度的值
{
long ut;
long up;
long x1, x2, b5, b6, x3, b3, p;
unsigned long b4, b7;
ut = bmp085ReadTemp(); // 读取温度
// ut = bmp085ReadTemp(); // 读取温度
up = bmp085ReadPressure(); // 读取压强
// up = bmp085ReadPressure(); // 读取压强
x1 = ((long)ut - ac6) * ac5 >> 15;
x2 = ((long) mc << 11) / (x1 + md);
b5 = x1 + x2;
temperature = (b5 + 8) >> 4;
//****************
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = (((long)ac1 * 4 + x3) + 2)/4;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
b7 = ((unsigned long) up - b3) * (50000 >> OSS);
if( b7 < 0x80000000)
p = (b7 * 2) / b4 ;
else
p = (b7 / b4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
pressure = p + ((x1 + x2 + 3791) >> 4);
}
void Send_BMP085(void) //用于串口显示的
{
UartSend_OneChar('B');
UartSend_OneChar('M');
UartSend_OneChar('P');
UartSend_OneChar('0');
UartSend_OneChar('8');
UartSend_OneChar('5');
UartSend_OneChar(':');
UartSend_OneChar('t');
UartSend_OneChar('=');
conversion(temperature);
UartSend_OneChar(bai);
UartSend_OneChar(shi);
UartSend_OneChar('.');
UartSend_OneChar(ge);
UartSend_OneChar('`');
UartSend_OneChar('C');
UartSend_OneChar(0x0d);
UartSend_OneChar(0x0a);
UartSend_OneChar('p');
UartSend_OneChar('=');
conversion(pressure);
UartSend_OneChar(shiwan);
UartSend_OneChar(wan);
UartSend_OneChar(qian);
UartSend_OneChar('.');
UartSend_OneChar(bai);
UartSend_OneChar(shi);
UartSend_OneChar(ge);
UartSend_OneChar('K');
UartSend_OneChar('p');
UartSend_OneChar('a');
UartSend_OneChar(0x0d);
UartSend_OneChar(0x0a);
}
一周热门 更多>