硬件I2C(查询方式)以STC8F2K08S2单片机为例
一、I2C相关的寄存器① I2C 配置寄存器② I2C 主机控制寄存器③ I2C 主机辅助控制寄存器④ I2C 主机状态寄存器⑤ I2C 数据寄存器⑥ 外设端口切换控制寄存器 1⑦ 外设端口切换控制寄存器 2
二、程序编写① 寄存器和相关宏定义② 硬件I2C初始化③ 硬件I2C操作代码④ BMP085 读写例程⑤ 串口代码
一、I2C相关的寄存器
① I2C 配置寄存器
② I2C 主机控制寄存器
③ I2C 主机辅助控制寄存器
④ I2C 主机状态寄存器
⑤ I2C 数据寄存器
⑥ 外设端口切换控制寄存器 1
⑦ 外设端口切换控制寄存器 2
二、程序编写
① 寄存器和相关宏定义
sfr P_SW2
= 0xBA;
#define I2CCFG (*(unsigned char volatile xdata *)0xfe80)
#define I2CMSCR (*(unsigned char volatile xdata *)0xfe81)
#define I2CMSST (*(unsigned char volatile xdata *)0xfe82)
#define I2CTXD (*(unsigned char volatile xdata *)0xfe86)
#define I2CRXD (*(unsigned char volatile xdata *)0xfe87)
#define I2C_S0 0x10
#define I2C_S1 0x20
#define EAXFR 0x80
sbit SDA
= P3
^3;
sbit SCL
= P3
^2;
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
② 硬件I2C初始化
void init_i2c(void)
{
uchar temp
= 0x00;
temp
|= (I2C_S0
| I2C_S1
);
temp
|= EAXFR
;
P_SW2
= temp
;
I2CCFG
= 0xE0;
I2CMSST
= 0x00;
}
③ 硬件I2C操作代码
void wait()
{
while(!(I2CMSST
& 0x40));
I2CMSST
&= ~0x40;
}
void start()
{
I2CMSCR
= 0x01;
wait();
}
void send_data(uchar dat
)
{
I2CTXD
= dat
;
I2CMSCR
= 0x02;
wait();
}
void recv_ack()
{
I2CMSCR
= 0x03;
wait();
}
uchar
recv_data()
{
I2CMSCR
= 0x04;
wait();
return I2CRXD
;
}
void send_ack()
{
I2CMSST
= 0x00;
I2CMSCR
= 0x05;
wait();
}
void send_nack()
{
I2CMSST
= 0x01;
I2CMSCR
= 0x05;
wait();
}
void stop()
{
I2CMSCR
= 0x06;
wait();
}
④ BMP085 读写例程
#define BMP085_SlaveAddress 0xEE
#define OSS 0
#define p0 101325.0
uchar send
[6];
xdata
short ac1
;
xdata
short ac2
;
xdata
short ac3
;
xdata
unsigned short ac4
;
xdata
unsigned short ac5
;
xdata
unsigned short ac6
;
xdata
short b1
;
xdata
short b2
;
xdata
short mb
;
xdata
short mc
;
xdata
short md
;
void Conversion(long temp_data
, uchar
*pAscii
)
{
*(pAscii
+ 5) = temp_data
/ 100000 + 0x30;
temp_data
= temp_data
% 100000;
*(pAscii
+ 4) = temp_data
/ 10000 + 0x30;
temp_data
= temp_data
% 10000;
*(pAscii
+ 3) = temp_data
/ 1000 + 0x30;
temp_data
= temp_data
% 1000;
*(pAscii
+ 2) = temp_data
/ 100 + 0x30;
temp_data
= temp_data
% 100;
*(pAscii
+ 1) = temp_data
/ 10 + 0x30;
temp_data
= temp_data
% 10;
*(pAscii
+ 0) = temp_data
+ 0x30;
}
void Single_Write(uchar SlaveAddress
, uchar REG_Address
, uchar REG_data
)
{
start();
send_data(SlaveAddress
);
recv_ack();
send_data(REG_Address
);
recv_ack();
send_data(REG_data
);
recv_ack();
stop();
}
uchar
Single_Read(uchar SlaveAddress
, uchar REG_Address
)
{
uchar REG_data
;
start();
send_data(SlaveAddress
);
recv_ack();
send_data(REG_Address
);
recv_ack();
start();
send_data(SlaveAddress
+ 1);
recv_ack();
REG_data
= recv_data();
send_nack();
stop();
return REG_data
;
}
short Multiple_read(uchar SlaveAddress
, uchar ST_Address
)
{
uchar msb
, lsb
;
short _data
;
start();
send_data(SlaveAddress
);
recv_ack();
send_data(ST_Address
);
recv_ack();
start();
send_data(SlaveAddress
+ 1);
recv_ack();
msb
= recv_data();
send_ack();
lsb
= recv_data();
send_nack();
stop();
Delay5ms();
_data
= msb
<< 8;
_data
|= lsb
;
return _data
;
}
long BMP085_Read_Temp(void)
{
Single_Write(BMP085_SlaveAddress
, 0xF4, 0x2E);
Delay5ms();
return (long)Multiple_read(BMP085_SlaveAddress
, 0xF6);
}
long BMP085_Read_Pressure(void)
{
long pressure
= 0;
Single_Write(BMP085_SlaveAddress
, 0xF4, 0x34);
Delay5ms();
pressure
= Multiple_read(BMP085_SlaveAddress
, 0xF6);
pressure
&= 0x0000FFFF;
return pressure
;
}
void Init_BMP085()
{
ac1
= Multiple_read(BMP085_SlaveAddress
, 0xAA);
ac2
= Multiple_read(BMP085_SlaveAddress
, 0xAC);
ac3
= Multiple_read(BMP085_SlaveAddress
, 0xAE);
ac4
= Multiple_read(BMP085_SlaveAddress
, 0xB0);
ac5
= Multiple_read(BMP085_SlaveAddress
, 0xB2);
ac6
= Multiple_read(BMP085_SlaveAddress
, 0xB4);
b1
= Multiple_read(BMP085_SlaveAddress
, 0xB6);
b2
= Multiple_read(BMP085_SlaveAddress
, 0xB8);
mb
= Multiple_read(BMP085_SlaveAddress
, 0xBA);
mc
= Multiple_read(BMP085_SlaveAddress
, 0xBC);
md
= Multiple_read(BMP085_SlaveAddress
, 0xBE);
}
void BMP085_Convert()
{
long ut
;
long up
;
long x1
, x2
, b5
, b6
, x3
, b3
, p
;
unsigned long b4
, b7
;
long temperature
;
long pressure
;
double altitude
;
ut
= BMP085_Read_Temp();
up
= BMP085_Read_Pressure();
x1
= ((long)ut
- ac6
) * ac5
>> 15;
x2
= ((long) mc
<< 11) / (x1
+ md
);
b5
= x1
+ x2
;
temperature
= (b5
+ 8) >> 4;
Conversion(temperature
, send
);
uart_sendstring("Temperature: ");
uart_sendchar(send
[2]);
uart_sendchar(send
[1]);
uart_sendchar('.');
uart_sendchar(send
[0]);
uart_sendstring("℃\r\n");
memset(send
, 0x00, 6);
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);
Conversion(pressure
, send
);
uart_sendstring("Pressure: ");
uart_sendchar(send
[5]);
uart_sendchar(send
[4]);
uart_sendchar(send
[3]);
uart_sendchar('.');
uart_sendchar(send
[2]);
uart_sendchar(send
[1]);
uart_sendchar(send
[0]);
uart_sendstring("kPa\r\n");
memset(send
, 0x00, 6);
altitude
= 44330.0 * (1 - pow((float)pressure
/ p0
, 1.0 / 5.255)) * 100;
Conversion(altitude
, send
);
uart_sendstring("Altitude:");
uart_sendchar(send
[4]);
uart_sendchar(send
[3]);
uart_sendchar(send
[2]);
uart_sendchar('.');
uart_sendchar(send
[1]);
uart_sendchar(send
[0]);
uart_sendstring("m\r\n");
memset(send
, 0x00, 6);
}
void main(void)
{
init_uart();
init_i2c();
ES
= 1;
EA
= 1;
Init_BMP085();
while(1){
BMP085_Convert();
uart_sendstring("\r\n");
uart_sendstring("\r\n");
uart_sendstring("\r\n");
Delay500ms();
Delay500ms();
Delay500ms();
Delay500ms();
}
}
⑤ 串口代码
#ifndef FOSC
#define FOSC 24000000L
#endif
#define BAUD 115200
sfr P_SW1
= 0xa2;
sfr AUXR
= 0x8e;
sfr T2H
= 0xd6;
sfr T2L
= 0xd7;
bit busy
;
void init_uart()
{
P_SW1
= 0x00;
SCON
= 0x50;
T2L
= (65536 - FOSC
/ BAUD
/ 4) % 256;
T2H
= (65536 - FOSC
/ BAUD
/ 4) / 256;
AUXR
= 0x15;
}
void uart_sendchar(uchar dat
)
{
while (busy
);
busy
= 1;
SBUF
= dat
;
}
void uart_sendstring(uchar
*p
)
{
while(*p
){
uart_sendchar(*p
++);
}
}
void uart_isr() interrupt
4 using
1
{
if(TI
){
TI
= 0;
busy
= 0;
}
if(RI
){
RI
= 0;
}
}
转载请注明原文地址:https://blackberry.8miu.com/read-3019.html