⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 two_memsic_lib.c

📁 美新加速度传感器
💻 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 + -