📄 two_memsic_lib.c
字号:
/* 所需包含的头文件
#include <avr/io.h>
#include <util/delay.h>
*/
// 系统为双通道IO口模拟IIC总线
/*****************首先掉用Memsic1_Init(0x00,0x00);或*****************/
/*******Memsic2_Init(0x00,0x00);函数,初始化加速度传感器***********/
/********以后每次获取加速度数值,掉用Memsic1_Read(0x01);**********/
/*******************或Memsic2_Read(0x01);函数即可********************/
//管脚定义:
#define I2C_DDR DDRA
#define I2C_PORT PORTA
#define I2C_PIN PINA
#define SDA1 PA1 //1通道IIC总线管脚定义
#define SCL1 PA0
#define SDA2 PA3 //2通道IIC总线管脚定义
#define SCL2 PA2
#define SDA1_OUT() (I2C_DDR |= (1<<SDA1))
#define SCL1_OUT() (I2C_DDR |= (1<<SCL1))
#define SDA2_OUT() (I2C_DDR |= (1<<SDA2))
#define SCL2_OUT() (I2C_DDR |= (1<<SCL2))
// 释放SDA1,上拉输入
#define SDA1_RLS() do{ I2C_PORT |= (1<<SDA1); I2C_DDR &= ~(1<<SDA1); }while(0)
#define SDA2_RLS() do{ I2C_PORT |= (1<<SDA2); I2C_DDR &= ~(1<<SDA2); }while(0)
#define SDA1_SET() (I2C_PORT |= (1<<SDA1))
#define SDA1_CLR() (I2C_PORT &= ~(1<<SDA1))
#define SCL1_SET() (I2C_PORT |= (1<<SCL1))
#define SCL1_CLR() (I2C_PORT &= ~(1<<SCL1))
#define READ_SDA1() ((I2C_PIN & (1<<SDA1)) ? 1 : 0)
#define SDA2_SET() (I2C_PORT |= (1<<SDA2))
#define SDA2_CLR() (I2C_PORT &= ~(1<<SDA2))
#define SCL2_SET() (I2C_PORT |= (1<<SCL2))
#define SCL2_CLR() (I2C_PORT &= ~(1<<SCL2))
#define READ_SDA2() ((I2C_PIN & (1<<SDA2)) ? 1 : 0)
#define MEMSIC_WRITE_ADDR 0x20 //加速度传感器写地址
#define MEMSIC_READ_ADDR 0x21 //加速度传感器读地址
unsigned int ZuoBiao[3]; //读出的X轴、Y轴、Z轴数据存于全局数组ZuoBiao中
// 发送起始信号
void IIC1_Start(void)
{
SDA1_OUT();
SCL1_OUT();
SDA1_SET();
SCL1_SET();
_delay_us(4);
SDA1_CLR();
_delay_us(4);
SCL1_CLR();
}
// 发送停止信号
void IIC1_Stop(void)
{
SDA1_OUT();
SCL1_OUT();
SDA1_CLR();
_delay_us(4);
SCL1_SET();
_delay_us(4);
SDA1_SET();
_delay_us(4);
}
// 向总线写1字节,并返回从机有无应答
unsigned char IIC1_Write(unsigned char byte)
{
unsigned char i, ack;
SDA1_OUT();
SCL1_OUT();
ack = 0;
for( i = 0; i < 8; ++i )
{
if ( byte & 0x80)
SDA1_SET();
else
SDA1_CLR();
byte <<= 1;
SCL1_SET();
_delay_us(4);
SCL1_CLR();
}
SDA1_RLS();
_delay_us(4);
SCL1_SET();
_delay_us(4);
ack = READ_SDA1();
SCL1_CLR();
_delay_us(4);
return ack;
}
// 读1字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char IIC1_Read(unsigned char ack)
{
unsigned char i, r = 0;
SDA1_RLS();
SCL1_OUT();
for( i = 0; i < 8; ++i )
{
SCL1_SET();
_delay_us(4);
r <<= 1;
if ( READ_SDA1() == 1)
{
r |= 1;
}
SCL1_CLR();
_delay_us(4);
}
SDA1_OUT();
// Send ACK
if (!ack)
SDA1_SET(); // Send nACK
else
SDA1_CLR(); // Send ACK
_delay_us(4);
SCL1_SET();
_delay_us(4);
SCL1_CLR();
_delay_us(4);
return r;
}
void Memsic1_Init(unsigned int addr1, unsigned char addr2)
{
IIC1_Start();
IIC1_Write(MEMSIC_WRITE_ADDR);
IIC1_Write(addr1);
IIC1_Write(addr2);
IIC1_Stop();
_delay_ms(80); // 等待80ms
}
void Memsic1_Read(unsigned char byte_addr)
{
unsigned int X1,X2,Y1,Y2;
IIC1_Start();
IIC1_Write(MEMSIC_WRITE_ADDR);
IIC1_Write(byte_addr);
IIC1_Start();
IIC1_Write(MEMSIC_READ_ADDR);
X1 = IIC1_Read(1); // 读1字节,返回ACK
X2 = IIC1_Read(1);
Y1 = IIC1_Read(1);
Y2 = IIC1_Read(0); // 读1字节,返回NoACK
IIC1_Stop();
ZuoBiao[0]=(X1<<8)+X2;
ZuoBiao[1]=(Y1<<8)+Y2;
}
// 发送起始信号
void IIC2_Start(void)
{
SDA2_OUT();
SCL2_OUT();
SDA2_SET();
SCL2_SET();
_delay_us(4);
SDA2_CLR();
_delay_us(4);
SCL2_CLR();
}
// 发送停止信号
void IIC2_Stop(void)
{
SDA2_OUT();
SCL2_OUT();
SDA2_CLR();
_delay_us(4);
SCL2_SET();
_delay_us(4);
SDA2_SET();
_delay_us(4);
}
// 向总线写1字节,并返回从机有无应答
unsigned char IIC2_Write(unsigned char byte)
{
unsigned char i, ack;
SDA2_OUT();
SCL2_OUT();
ack = 0;
for( i = 0; i < 8; ++i )
{
if ( byte & 0x80)
SDA2_SET();
else
SDA2_CLR();
byte <<= 1;
SCL2_SET();
_delay_us(4);
SCL2_CLR();
}
SDA2_RLS();
_delay_us(4);
SCL2_SET();
_delay_us(4);
ack = READ_SDA2();
SCL2_CLR();
_delay_us(4);
return ack;
}
// 读1字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char IIC2_Read(unsigned char ack)
{
unsigned char i, r = 0;
SDA2_RLS();
SCL2_OUT();
for( i = 0; i < 8; ++i )
{
SCL2_SET();
_delay_us(4);
r <<= 1;
if ( READ_SDA2() == 1)
{
r |= 1;
}
SCL2_CLR();
_delay_us(4);
}
SDA2_OUT();
// Send ACK
if (!ack)
SDA2_SET(); // Send nACK
else
SDA2_CLR(); // Send ACK
_delay_us(4);
SCL2_SET();
_delay_us(4);
SCL2_CLR();
_delay_us(4);
return r;
}
void Memsic2_Init(unsigned int addr1, unsigned char addr2)
{
IIC2_Start();
IIC2_Write(MEMSIC_WRITE_ADDR);
IIC2_Write(addr1);
IIC2_Write(addr2);
IIC2_Stop();
_delay_ms(80); // 等待80ms
}
void Memsic2_Read(unsigned char byte_addr)
{
unsigned int X1,X2,Y1,Y2;
IIC2_Start();
IIC2_Write(MEMSIC_WRITE_ADDR);
IIC2_Write(byte_addr);
IIC2_Start();
IIC2_Write(MEMSIC_READ_ADDR);
X1 = IIC2_Read(1); // 读1字节,返回ACK
X2 = IIC2_Read(1);
Y1 = IIC2_Read(1);
Y2 = IIC2_Read(0); // 读1字节,返回NoACK
IIC2_Stop();
ZuoBiao[2]=(Y1<<8)+Y2;
}
/* 例:
int main(void)
{
Print_USART_Init();
Memsic1_Init(0x00,0x00);
while(1)
{
Memsic1_Read(0x01);
printf("%8d",Ax1);
printf("%8d\n",Ay1);
}
}*/
/*****************首先掉用Memsic1_Init(0x00,0x00);或*****************/
/*******Memsic2_Init(0x00,0x00);函数,初始化加速度传感器***********/
/********以后每次获取加速度数值,掉用Memsic1_Read(0x01);**********/
/*******************或Memsic2_Read(0x01);函数即可********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -