蓝桥杯赛前一周传感器模块总结

传感器模块总结

1、PCF8591

在这里插入图片描述

通讯方式:IIC

寄存器
在这里插入图片描述
最高位(第七位):固定为0
第六位:DAC功能使能
第五,四位:通道读取方式选择
第三位:默认为0
第二位:自动增量模式使能
第一,零位:通道选择

通讯步鄹:
见代码注释

通讯时易错点:
①、ADC时每次读取完数据就发送非应答位。
②、弱需要DAC功能,不论ADC模式下还是DAC模式下发送功能数据时,控制位第6位必须置1!
③、中断对其无影响。
④、PCF8591转换始终位八个SCL周期,即IIC传送一个字节的时间,因此需要先将PCF8591读取一个空字节,第二次读取的数值才为真实数值。

驱动代码

//IIC读取八位ad转换数值
uint8 IIC_GetVal()
{
	uint8 Val;
	IIC_Start();				//IIC启动
	IIC_SendByte(0x90); //IIC选择地址,并发送写指令
	IIC_WaitAck();			//等待IIC应答
	IIC_SendByte(0x43);	//选择模拟量输入通道
	IIC_WaitAck();
	IIC_Stop();    			//IIC停止,接下来开始读取数据
	
	IIC_Start();				//IIC启动
	IIC_SendByte(0x91); //IIC选择地址,并发送读指令
	IIC_WaitAck();			//IIC等待应答
	IIC_RecByte();			//接收PCF8591空字节
	IIC_SendAck(0);			//发送应答位
	Val = IIC_RecByte();	//接收PCF8591数据
	IIC_SendAck(1);			//发送非应答位
	IIC_Stop();
	
	return Val;
}

uint8 IIC_GetLit()
{
	uint8 Val;
	IIC_Start();				//IIC启动
	IIC_SendByte(0x90); //IIC选择地址,并发送写指令
	IIC_WaitAck();			//等待IIC应答
	IIC_SendByte(0x41);	//选择模拟量输入通道
	IIC_WaitAck();
	IIC_Stop();    			//IIC停止,接下来开始读取数据
	
	IIC_Start();				//IIC启动
	IIC_SendByte(0x91); //IIC选择地址,并发送读指令
	IIC_WaitAck();			//IIC等待应答
	IIC_RecByte();			//接收PCF8591空字节
	IIC_SendAck(0);			//发送应答位
	Val = IIC_RecByte();	//接收PCF8591数据
	IIC_SendAck(1);			//发送非应答位
	IIC_Stop();
	
	return Val;
}

void DAC(uint8 a_Data)
{
	a_Data = a_Data*(256/5);

	IIC_Start();				//IIC启动
	IIC_SendByte(0x90); //IIC选择地址,并发送写指令
	IIC_WaitAck();			//等待IIC应答
	IIC_SendByte(0x43);	//选择模拟量输入通道
	IIC_WaitAck();
	IIC_SendByte(a_Data); //IIC选择地址,并发送读指令
	IIC_WaitAck();			//IIC等待应答
	IIC_Stop();  
}

2、EEPROM

通讯方式:IIC

通讯步鄹:
见代码

通讯易错点:
①视情况需要关闭中断
②连续读数据时,在读最后一位之前回应的应答位都为ACK(0)来表示可以继续读数据(用NACK(1)应答会导致无法读出下一个数据)。
③当数据读入最后一位时,用NACK(1)来应答(实际上用ACK(0)应答也可以,但是用NACK(1)更规范)
④初始化有两种方法,一是根据要存入的数据范围判断是否存入,二是可以设置多余的标志位。
⑤每次写数据之间需要有间隔,若用按键改变数据的值化,可把写数据的操作放在按键中。

代码

void EEPROM_Write(uint8 addr,uint8 dat)
{
	EA = 0;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
	EA = 1;
	
}

uint8 EEPROM_Read(uint8 addr, bit ack)
{
	uint8 Val;
	EA = 0;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	Val = IIC_RecByte();
	IIC_Ack(ack);
	IIC_Stop();
	EA = 1;
	return Val;
}

EEPROM初始化
方法一

void Init_EEPROM()
{
	if(EEPROM_Read(0x38,0)==0x38)//当标志位存在
	{
		此处根据需要读取EEPROM的存储的值
		当读取最后一个字节时应答位为NACK(1)
	}
	else						//当标志位不存在
		EEPROM_Write(0x38,0x38);
}

方法二

void Init_EEPROM()
{
	uint8 x = 0xff;
	x = EEPROM_Read(addr,0);
	if(x > n1 && x < n2) 		//(n1,n2)为所存储数值的范围
	{
		此处根据需要读取EEPROM的存储的值
		当读取最后一个字节时应答位为NACK(1)
	}
	else						//当读取数值不在此范围
		EEPROM_Write(0x38,0x38);
}

3、DS18B20

在这里插入图片描述

通讯方式
onewire单总线传输

配置寄存器
在这里插入图片描述
在这里插入图片描述

通讯步鄹:

  • 初始化DS18B20
  • 写入0xcc指令,跳过rom操作
  • 写入0x44指令,开始温度转换
  • 延迟大概700ms,等待温度转换
  • 写入0xcc指令,跳过rom操作
  • 写入0xbe指令,开始读取温度
  • 读取高八位
  • 读取低八位
  • 高低八位数据合并转换计算

通讯易错点
①onewire单总线传输无时钟线,对时序要求高,因此需要关闭中断。
②延迟700ms读取温度器件可以不关闭中断,此时可以执行普通工作。
③整理后的16位数据,前四位为符号,中间八位为整数,后四位为小数。

代码

uint16 rd_temperature()
{
	uint8 LSB,MSB;
	uint16 temp_Val;
	/********发送指令********/
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	/********延迟********/
	Delay_OneWire(100);
	
	/********发送指令********/
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	/********读取数据********/
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	
	/********温度数据转换********/
	temp_Val = MSB;
	temp_Val = (temp_Val<<8)|LSB;
	temp_Val = temp_Val>>4;
	
	return temp_Val;//此处温度被转换成整数
}

4、DS1302

在这里插入图片描述

通讯方式
类SPI通讯

寄存器
在这里插入图片描述
秒寄存器CH位时钟停止标志位,置1开启,置0关闭。
第八个寄存器WP位写保护位,置1开启,置0关闭。

通讯步鄹:
见代码

通讯细节与易错点
①需要写入DS1302的数值时,应该WP位置1,启动时置0。
②设置DS1302时,可CH位置1,停止时钟震动,设置完毕在开启。
③设置时关闭循环中对DS1302数值的读取,防止设置的数被读取函数改变。
④SPI通讯有时钟线,因此可以不关闭中断。

代码

unsigned char Write_DS1302_adrr[7] = 
{0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8E};
unsigned char Read_DS1302_adrr[7] = 
{0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
unsigned char Timer[7];

void DS1302_Config()
{
	unsigned char i;
	Write_Ds1302_Byte( 0x8e, 0x00);
	for(i = 0; i < 7; i++)
	{
		Write_Ds1302_Byte( Write_DS1302_adrr[i], Timer[i]);
	}
	Write_Ds1302_Byte( 0x8e, 0x80);
}

void Read_DS1302_Timer()
{
	unsigned char i;
	for(i = 0; i < 7; i++)
	{
		Timer[i] = Read_Ds1302_Byte( Read_DS1302_adrr[i] );
	}
}

后记

由于一些事情,咕了许久,第九届之后的赛题写了懒得更新 ,这些传感器整会了,赛题就轻松多了。

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值