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

原创 2015年11月19日 15:48:48

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 
  }
}


上电查看效果:


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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

zigbee网关 zstack CC2530添加iic温度传感器lm75a

lm75a已经裸机驱动起来,下一步准备添加在zstack中zigbee网关 cc2530裸机驱动温度传感器LM75A 把iic.c, iic.h, lm75a.c, lm75a.h拷贝到zigbeeG...

cc2530实现i2c数据线

本帖最后由 L.fish 于 2010-7-29 15:47 编辑 本人尊重原文作者,这篇文章非本人原创,feibit论坛是个不错的论坛,希望大家多看看这个网站。 [注:本文源自www.f...

zigbee网关 cc2530终端裸机串行驱动12864(字库ST7920)

由于CC2530终端的IO端口很紧张,所以驱动12864屏幕采用串行驱动,接法很简单,只需要三根线 首先将PSB引脚接地,使12864处于串口模式;更简单的接法CS引脚都可以省略,直接将CS接到5...

Microduino中LM75温度传感器的使用

因为做项目需要,接触到了LM75温度传感器。LM75A 是一个高速I2C 接口的温度传感器,可以在-55℃~+125℃的温度范围内将温度 直接转换为数字信号,并可实现0.125℃的精度。 IIC 即I...

Zigbee网关 cc2530 zstack添加1602驱动

1602的驱动已经写好了,但是发现不怎么稳定,走了很多弯路,一直以为是自己的指令没有用好,最后实在没辙放出了大招,用逻辑分析仪查看波形,发现波形很乱,尤其是E的下降沿之后的延迟时间非常短,因此简单的进...

LM75A(数字温度传感器)

  • 2010-04-14 17:58
  • 706KB
  • 下载

LM75A数字温度传感器

  • 2012-02-09 20:47
  • 367KB
  • 下载

zigbee网关 CC2530 zstack用手机控制1602显示

在zigbee工程里面ZigbeeGateWay.h增加一个CLUSTERID #define ZIGBEEGATEWAY_LCD_UPDATE_CLUSTERID 9 这样CLUSTERID的...

LM75温度传感器程序

LM75 温度传感器

  • 2010-09-17 16:28
  • 40KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)