应用PIC16F1938中IIC读取LM75A温度

一.概述

LM75A是一个高精度温度传感器,精度高达0.125℃,可以采集的温度范围是-55℃~125℃。PIC16F1938可以通过IIC通信方式对LM75A里面的温度寄存器直接读取,并可设置相关的配置寄存器。每个LM75A的地址信号前四位是一样的(由不同生产厂家决定1001),有三位可选的逻辑地址管脚(A0A1A2,因此IIC总线上可以支持同时挂载8LM75A芯片。LM75A有不同的工作模式,正常模式下是监控环境温度,通过IIC总线读取;OS输出模式有两种可选的工作模式:OS比较模式和OS中断模式,OS输出高低电平来判断温度是否超过设定阈值,默认情况下温度阈值为80℃,滞后温度阈值为75℃。工作电压范围:2.8V~5.5V

二.LM75A管脚

三.LM75A内部寄存器

1.温度寄存器Temp(地址0x00

    温度寄存器中一共有两个数据字节,高数据字节(MS)和低数据字节(LS),其中高数据字节是温度数据的整数部分范围为-25~+125℃,高数据字节第7位是符号位。低数据字节只有高三位有效,即将1℃分为8份,所以精度为0.125℃。

下面是手册上给出的一些温度值示例。

2.配置寄存器Conf(地址0x01

配置寄存器为8位可读可写寄存器,功能如下。

B7~B5

B4~B3

B2

B1

B0

保留

OS故障列队

OS极性

OS比较/中断

关断

OS故障列队:用于故障列队编程,0,1,2,3,代表队列值1,2,4,6,默认是0

OS极性:有效电平选择,1代表OS高有效,0代表OS低有效;

OS比较/中断:比较中断模式选择,1代表OS工作与中断模式,0代表OS工作于比较模式。

关断:期间模式选择,1代表关断,0代表正常模式。

3.滞后温度寄存器Thyst(地址0x02

    滞后温度寄存器可读可写,提供了温度下限温度,默认为75℃。每次采样温度到Temp中和下限温度比较,低于下限温度会在OS脚做出相应反应。

4.过温关断门限温度寄存器Tos(地址0x03

    过温关断门限温度寄存器可读可写,提供了温度上限温度,默认为80℃。每次采样温度到Temp中和上限温度比较,高于下限温度会在OS脚做出相应反应。过温关断门限温度寄存器和滞后温度寄存器均用9位来存储温度,分辨率为0.5℃,数据格式如下;

D15

D14~D8

D7

D6~D0

符号位

温度值

保留

5.地址寄存器Address

    地址寄存器的定义如下;

A7~A4

A3~A1

A0

1001

可选逻辑地址

/

A7~A0为固定地址,厂家决定为1001A3~A1可选地址,对应LM75A的三个地址引脚;A0为读/写功能位,1为读取,0位写入。

四.PIC16F1938IIC通讯模块

    内部集成电路总线(I²C)是多主器件串行数据通信总线。器件可以在主/ 从环境下通信,在该环境下,由主器件发起通信。可通过寻址控制从器件。IIC总线指定两种信号连接:串行时钟(SCL)和串行数据(SDA)。

1.PIC16F1938配置IIC

PIC16F1938中的主同步串行端口(MSSP)配置为IIC工作的主发送模式(通过将SSPCON1寄存器中的SSPM1并将SSPEN1),主模式下,SCLSDL均有MCU控制,用户需要将RC3RC4引脚设为输入(TRISC3 1TRISC4 1;),设置SCL上的时钟频率(通过SSPADD寄存器来设置)

2. PIC16F1938IIC模块主模式发送序列

  • 用户通过将SSPCON2 寄存器的SEN 位置1 来产生启动条件。
  • 启动条件完成时, SSPIF 由硬件置1
  • SSPIF 由软件清零。
  • 在发生任何其他操作之前,MSSP 模块将等待所需的启动时间。
  • 用户将要发送的从地址装入SSPBUF
  • 地址将移出SDA 引脚,直到所有8 位发送完毕。写SSPBUF 时便开始发送。
  • MSSP 模块移入来自从器件的ACK 位,并将其值写入SSPCON2 寄存器的ACKSTAT 位。
  • 在第9 个时钟周期结束时, MSSP 模块通过将SSPIF 位置1 产生中断。
  • 用户将8 位数据装入SSPBUF
  • 数据被移出SDA 引脚,直到所有8 位发送完毕。
  • MSSP 模块移入来自从器件的ACK 位,并将其值写入SSPCON2 寄存器的ACKSTAT 位。
  • 对于所有发送的数据字节,重复第8-11 步。
  • 用户通过将SSPCON2 寄存器的PEN RSEN位置1 来产生停止或重复启动条件。停止/ 重复启动条件完成时产生中断。

3. PIC16F1938IIC模块主模式接受序列

  • 用户通过将SSPCON2 寄存器的SEN 位置1 来产生启动条件。
  • 启动条件完成时, SSPIF 由硬件置1
  • SSPIF 由软件清零。
  • 用户将要发送的从地址写入SSPBUF R/W 位置1
  • 地址将移出SDA 引脚,直到所有8 位发送完毕。写SSPBUF 便开始发送。
  • MSSP 模块移入来自从器件的ACK 位,并将其值写入SSPCON2 寄存器的ACKSTAT 位。
  • 在第9 个时钟周期结束时, MSSP 模块通过将SSPIF 位置1 产生中断。
  • 用户将SSPCON2 寄存器的RCEN 位置1,且主器件随着时钟移入来自从器件的字节。
  • SCL 信号的第8 个下降沿之后,SSPIF BF1
  • 主器件清零SSPIF,并从SSPUF 中读取接收到的字节,清零BF 位。
  • 主器件在SSPCON2 寄存器的ACKDT 位中设置将要发送给从器件的ACK 值,并通过将ACKEN位置1 发送ACK
  • 主器件随着时钟将ACK 移出到从器件, SSPIF1
  • 用户清零SSPIF
  • 对于每个从从器件接收的字节,重复第8-13 步。
  • 主器件发送非ACK 或停止位以结束通信。

五.使用PIC16F1936读取LM75A温度值

    从上面的读取可以看到PIC16F1936IIC模块每次读取8位,二LM75A的温度数据是两个8位存放在一个地址里面,因此需要读取1个字节数据后应答0,再接收第2个数据后主机应答1来停止通过过程。具体读写C语言代码如下:

 

 1 unsigned char IIC_Read_Byte(void)
 2 {
 3     //Read one byte
 4     unsigned char b;
 5     RCEN = 1; //使能IIC接收模式
 6     while (!SSPIF);
 7     SSPIF = 0;
 8     b = SSPBUF;
 9     BF = 0;
10     return b;
11 }
12 
13 void IIC_Write_Byte(unsigned char d)
14 {
15     SSPBUF = d; //将从机地址装入SSPBUF进行传送,以准备进行数据读
16     while (!SSPIF); //等待发送结束
17     SSPIF = 0; //SSPIF标志清0
18 }
19 
20 void IIC_ACK(unsigned char x)
21 {
22     //The master ACK 0 or 1
23     ACKDT = (x & 0x01); //ACK 0 or 1, 0 is active
24     ACKEN = 1; //在SDA和SCL引脚上启动应答顺序,并发送ACKDT数据位
25     while (!SSPIF); //等待应答发送结束
26     SSPIF = 0; //SSPIF标志清0
27 }
28 
29 void IIC_Start(void)
30 {
31     SEN = 1; // Start signal
32     //  asm("CLRWDT");
33     //  asm("CLRWDT");
34     do
35     {
36         RSEN = 1;
37     }
38     while (!SSPIF); //等待启动结束,如果没启动,反复重启动
39     SSPIF = 0; //SSPIF标志清0
40 }
41 
42 void IIC_Stop(void)
43 {
44     PEN = 1; //产生IIC停止信号
45     while (!SSPIF); //等待发送结束
46     SSPIF = 0; //SSPIF标志清0
47 }
48 
49 unsigned int IIC_Read_LM75A(void)
50 {
51     // Read procedure = PDF274
52     unsigned char bytebuf1 = 0;
53     unsigned char bytebuf2 = 0;
54     unsigned int temp=0;
55 
56     IIC_Start();
57     IIC_Write_Byte(0x91);
58     bytebuf1 = IIC_Read_Byte();
59     IIC_ACK(0);
60     bytebuf2 = IIC_Read_Byte();
61     IIC_ACK(1);
62     //IIC_Stop();
63     if ((bytebuf1 != 0xff))
64     {
65         //temp|=0x8000;
66         temp+=bytebuf1;
67     }
68     return temp;
69 }
posted @ 2018-01-03 22:00  心中一座坟  阅读(2441)  评论(0编辑  收藏  举报