关闭

zigbee网关 cc2530裸机驱动温度传感器LM75A

标签: 网关zigbee网关zigbee温度传感器LM75A
812人阅读 评论(0) 收藏 举报
分类:

LM75A,数字温度传感器,IIC接口,读取简单,只需要读取2个寄存机的值就可计算出来温度


手里里有个贴片的LM75A,在一块废弃的pcb板上利用0805电阻脚把lm75a的sda和scl脚焊好,其它的引脚用插针焊好


现在lm75a对外有4个引脚,分别是VCC,GND,SDA,SCL

把5,6,7,8,脚焊在了一起,这样根据pdf介绍

它的iic地址为1001111,即0x4F。

把VCC,GND,SDA,SCL与cc2530网关开发板的终端开发板连接起来


LM75A与CC2530终端开发板连接方式
    LM75A    CC2530终端开发板
VCC +3.3V
GND GND
SDA P0_6
SCL P0_7

先写软件模拟iic,cc2530根普通的51单片机单片机,普通的51单片机读取io状态的时候把io置高直接读就可以了,而cc2530需要专门专门设定寄存器来制定当前的io是输入还是输出,因此多写了写了2个宏用于寄存器赋值

#define SDA P0_6//数据线
#define SCL P0_7//时钟线
#define _nop_() asm("nop");

#define set_sda_in()  P0DIR &= ~(1<<6)
#define set_sda_out() P0DIR |= 1<<6


软件模拟iic的驱动如下:

#include "iic.h"
/*
I2C通信使用delay()函数
一个_nop_()延时1us,总线要求延时大于4.7us 
单片机频率执行周期不同时按实际需要修改
sck时钟频率400k
*/
void delay()
{
  int i = 0;
  for(i = 0; i < 32*4.7; i++)
	_nop_();
	
}

//总线初始化
//将总线都拉高以释放总线
void iic_init()
{
        set_sda_out();
	SCL = 1;
	delay();
	SDA = 1;
	delay();
}

//启动信号
//SCL在高电平期间,SDA由高电平向低电平的变化定义为启动信号
void iic_start()
{
  set_sda_out();
	SDA = 1;
	delay();
	SCL = 1;
	delay();
	SDA = 0;
	delay();
}

//停止信号
//SCL在高电平期间,SDA由低电平向高电平的变化定义为停止信号
void iic_stop()
{
  set_sda_out();
	SDA = 0;
	delay();
	SCL = 1;
	delay();
	SDA = 1;
	delay();
}

//应答信号
//SCL在高电平期间,SDA被从设备拉为低电平表示应答
//其中(SDA == 1)&&(i<255)表示若在一段时间内没有收到从器件的应答则主器件默认从器件已经收到数据而不再等待应答信号
//若没有这部分代码,程序会停在这里,实际运用中不允许这种情里发生,或者return ture或false,方便调试

//等待从设备产生应答
void iic_srespons()
{
  set_sda_in();
	unsigned char i = 0;
	SCL = 1;
	delay();
	while((SDA == 1)&&(i<254))
		i++;
	SCL = 0;
	delay();
}

//由主设备发出应答
//从设备在发送完一字节后将SDA拉高(SDA被释放),主设备将SDA拉低产生应答
void iic_mrespons()
{
  set_sda_out();
	SDA = 0;//直接将SDA拉低,再操纵SCL
	delay();
	SCL = 1;
	delay();
	SCL = 0;
	delay();
}

//主设备不应答
void iic_nrespons()
{
  set_sda_out();
	SDA = 1;//SDA高电平为不应答
	delay();
	SCL = 1;
	delay();
	SCL = 0;
	delay();
}

//写入
//串行发送一个字节时,需要把这个字节中的8位一位一位地发出去,“temp=temp<<1;”
//表示将temp左移一位,最高位将移入PSW寄存器的CY位中,然后将CY赋给SDA进而在SCL的控制下发送出去
//最后将SDA拉高,以等待从设备产生应答
void iic_write(unsigned char data)
{
  set_sda_out();
	unsigned char i, temp;
        
	temp = data;
	for(i=0; i<8; i++)
	{
		SCL = 0;
		delay();
		SDA = temp/128;
		delay();
		SCL = 1;
		delay();
      		temp = temp << 1;
        }
	SCL = 0;
	delay();
	SDA = 1;
	delay();
}

//读出
//串行接受一个字节时需了、将8位一位一位地接受,然后再组合成一个字节,
//代码定义了k,将k左移一位后与SDA进行“或”运算,一次把8个独立的位放入一个字节中来完成接收
unsigned char iic_read()
{
  set_sda_in();
	unsigned char i, k;
	SCL = 0;
	delay();
	SDA = 1;
	delay();
	for(i=0; i<8; i++)
	{
		SCL = 1;
		delay();
		k = (k<<1)|SDA;
		SCL = 0;
		delay();
	}
	delay();
	return k;
}


在main函数中开启的串口用于显示温度,因为不读只往外写

串口初始化函数

</pre><pre name="code" class="cpp">void uart_init(void)
{
    PERCFG = 1<<1;              //uart1:P1 alt2 
    P0SEL = (1<<2)|(1<<3);      //P0_2,P0_3用作串口,第二功能 
    P0DIR &= ~(1<<2);           //P0_2 rxd input
    P0DIR |= (1<<3);            //P0_3 txd output
 
    P2DIR &= ~0XC0;             //P0优先作为UART0
    U0CSR |= 0x80;              //UART方式
    U0GCR |= 11;                       
    U0BAUD |= 216;              //波特率设为115200    其中关于修改波特率值的问题                     
    UTX0IF = 1;                 //具体参看用户手册的串口部分
//U0CSR |= 0x40;              //允许接收 
 //   UTX0IF = 0;                 //UART0 TX中断标志初始置位0
    //IEN0 |= 1<<2;               // 开总中断,接收中断   
}


串口发送函数

void uart_send(char *p_data,unsigned char length)
{
    int i=0;
    for(i=0;i<length;i++)
    { 
        U0DBUF = p_data[i]; 
        while(UTX0IF == 0) ; 
        UTX0IF = 0;
    }
}


读取温度函数,根据pdf寄存器读出的第一个数的全部位+第二个数的高3位组成的值*0.125就是当前的温度值


float ReadTemp(void)
{
    int temphigh, templow;
    iic_start();
    iic_write(IIC_ADDR);//硬件地址1001111,读模式,LM75不需要指定地址,直接连续读2字节温度
    iic_srespons();
    temphigh = iic_read();
    iic_mrespons();
    templow = iic_read();
    iic_nrespons();
    iic_stop();
    
    if(temphigh > 127)//负温度的处理,理论可行,尚未测试
    {
       temphigh = (~temphigh) + 1;//~优先级低于+
       templow = (~templow) + 1;
       temphigh = temphigh << 3;
       templow = templow >> 5;
       return -(temphigh+templow)*0.125;
    }

    temphigh = temphigh << 3;
    templow = templow >> 5;
    return (temphigh+templow)*0.125;
}

main主函数

void main()
{
  int i = 0;
  char buffer[20];
  system_init();
  iic_init();//I2C总线初始化
  uart_init();
   uart_send("system initial success...\r\n",27);
  while(1) 
  {
    uart_send(buffer,sprintf(buffer,"Temperature is: %2.1f\r\n", ReadTemp()));
    for(i=0;i<10000;i++) delay();//延迟1s 
  }
}


上电查看效果:


成功!温度上升是因为我那电烙铁烤了它。

源码下载链接: 点击打开链接

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:59162次
    • 积分:1169
    • 等级:
    • 排名:千里之外
    • 原创:59篇
    • 转载:1篇
    • 译文:0篇
    • 评论:10条
    文章分类
    最新评论