📄 lm92.c
字号:
//====================================================================
// File Name : 2410IIC.c
// Function : S3C2410 IIC-bus Master Tx/Rx mode Test Program
// (Interrupt / Non Interrupt (Polling))
// Program : Shin, On Pil (SOP)
// Date : May 21, 2002
// Version : 0.0
// History
// 0.0 : Programming start (March 11, 2002) -> SOP
//====================================================================
#include <string.h>
#include "2410addr.h"
#include "2410lib.h"
#include "def.h"
#include "lm92.h"
static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt,mm=0;
//===================================================================
// SMDK2410 IIC configuration
// GPE15=IICSDA, GPE14=IICSCL
// "Interrupt mode" for IIC block
//===================================================================
//******************[ Test_Iic ]**************************************
//===========================================
//名称:LM92_Iic
//功能:读取温度寄存器并转化为数字形式
//============================================
void LM92_Iic(void)
{
double temper;
int a,b,int_temper,_temper;
unsigned int i,j,save_E,save_PE;
static U8 data[256];
//_iicDataCount = 1;
Uart_Printf("[ IIC Test(Interrupt) using lm92 ]\n");
// 保留原来端口设置
save_E = rGPECON;
save_PE = rGPEUP;
// 设置端口
//GPEUP [15:14] = 11 : Pull-up disable
rGPEUP |= 0xc000; //Pull-up disable
//GPECON [15:14] = 1010 : GPE15:IICSDA
// GPE14:IICSCL
rGPECON |= 0xa0000000; //GPE15:IICSDA , GPE14:IICSCL
//rGPECON &= 0xafffffff;
// 设置IIC控制寄存器
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
// If PCLK 15.0MHz, IICCLK = 29.296KHz, Tx Clock = 0.198MHz
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition & Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 1 : IICCLK = fPCLK /512
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0x4<<0);
// 设置从机地址
//IICADD Slave address [7:0] = 00000010 : 2410 slave address = [7:1]
rIICADD = 0x10; //2410 slave address = [7:1]
//IICSTAT Last-received bit status flag [0 ] = 0 : Last-received bit is 0 (ACK was received).
//IICSTAT Address zero status flag [1 ] = 0 : Cleared when START/STOP condition was detected.
//IICSTAT Address-as-slavestatus flag [2 ] = 0 : Cleared when START/STOP condition was detected
//IICSTAT Arbitration status flag [3 ] = 0 : Bus arbitration successful
//IICSTAT Serial output [4 ] = 1 : Enable Rx/Tx
//IICSTAT Busy signal status /START STOP condition
// [5 ] = 0 : read) Not busy (when read) write) STOP signal generation
//IICSTAT Mode selection [7:6] = 00: Slave receive mode
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
// 挂接中断
pISR_IIC = (unsigned)IicInt;
//取消中断屏蔽
rINTMSK &= ~(BIT_IIC);
while(!Uart_GetKey())
{
WrLM92(lm92_addr ,point);//向LM92写入温度寄存器的地址
RdLM92(lm92_addr,&(data[0]),&(data[1])); //读出温度值
//获得数据转换成温度值
a=(int) data[0];
b=(int) data[1];
b=b>>3;
a=a<<5;
temper=((a+b)*0.0625)*10;//读取温度值
int_temper=temper/10;//得到整数位
_temper=temper-int_temper*10;//得到小数位
Uart_Printf(" %d.%d\n",int_temper,_temper);
Delay(1000);//LM92两次读书之间需要一定时间
}
Uart_Printf("TEST FINISHED.\n");
rINTMSK |= BIT_IIC;
rGPEUP = save_PE;
rGPECON = save_E;
}
void WrLM92(U32 addr,U8 poin)
{
_iicMode = WRDATA; //通信模式
_iicPt = 0; //通信指针
_iicData[0] = (U8)poin;//通信数据
_iicDataCount = 1; //通信计数
//IICDS 数据寄存器 [7:0] Addr LM92芯片的地址
rIICDS = addr ;
//IICSTAT Serial output [4 ] = 1 : Enable Rx/Tx
//IICSTAT Busy signal status /START STOP condition
// [5 ] = 1 : read) Busy (when read) write) START signal generation.
//IICSTAT Mode selection [7:6] = 11: Master transmit mode
rIICSTAT = 0xf0;
while(_iicDataCount!=-1);
}
//================================
//名称:RdLM92
//功能:读取LM92内温度寄存器的值
//================================
void RdLM92(U32 addr,U8 *data1,U8 *data2)
{
_iicMode = RDDATA;//通信模式
_iicPt = 0; //通信指针
_iicDataCount = 2; //通信计数
//IICDS 数据寄存器 [7:0] Addr LM92芯片的地址
rIICDS = addr;
//IICSTAT Serial output [4 ] = 1 : Enable Rx/Tx
//IICSTAT Busy signal status /START STOP condition
// [5 ] = 1 : read) Busy (when read) write) START signal generation.
//IICSTAT Mode selection [7:6] = 10: Master receive mode
rIICSTAT = 0xb0; //MasTx,Start
// rIICCON = 0xe4; //Resumes IIC operation.
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1);
*data1 = _iicData[1];
*data2 = _iicData[2];
}
//==================================
//名称:IicPoll
//功能:中断模式下的IIC通信模式
//==================================
void __irq IicInt(void)
{
U32 iicSt,i;
rSRCPND = BIT_IIC; //Clear pending bit
rINTPND = BIT_IIC;
iicSt = rIICSTAT;
if(iicSt & 0x8){} //When bus arbitration is failed.
if(iicSt & 0x4){} //When a slave address is matched with IICADD
if(iicSt & 0x2){} //When a slave address is 0000000b
if(iicSt & 0x1){} //When ACK isn't received
switch(_iicMode)
{
case POLLACK:
_iicStatus = iicSt;
break;
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = rIICDS;
//IICSTAT Serial output [4 ] = 1 : Enable Rx/Tx
//IICSTAT Busy signal status /START STOP condition
// [5 ] = 0 : read) Not busy (when read)
// write) STOP signal generation
//IICSTAT Mode selection [7:6] = 10: Master receive mode
rIICSTAT = 0x90; //Stop MasRx condition
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = 0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
_iicData[_iicPt++] = rIICDS; //The last data has to be read with no ack.
if((_iicDataCount)==0)
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 0 : disable
rIICCON = 0x2f; //Resumes IIC operation with NOACK.
else
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = 0xaf; //Resumes IIC operation with ACK
break;
case WRDATA:
if((_iicDataCount--)==0)
{
//IICSTAT Last-received bit status flag [0 ] = 0 : Last-received bit is 0 (ACK was received).
//IICSTAT Address zero status flag [1 ] = 0 : Cleared when START/STOP condition was detected.
//IICSTAT Address-as-slavestatus flag [2 ] = 0 : Cleared when START/STOP condition was detected
//IICSTAT Arbitration status flag [3 ] = 0 : Bus arbitration successful
//IICSTAT Serial output [4 ] = 1 : Enable Rx/Tx
//IICSTAT Busy signal status /START STOP condition
// [5 ] = 0 : read) Not busy (when read)
// write) STOP signal generation
//IICSTAT Mode selection
rIICSTAT = 0xd0; //Stop MasTx condition
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = 0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//The pending bit will not be set after issuing stop condition.
break;
}
rIICDS = _iicData[_iicPt++]; //_iicData[0] has dummy.
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = 0xaf; //resumes IIC operation.
break;
case SETRDADDR:
// Uart_Printf("__irq IicInt SETDADDR [ S%d ]",_iicDataCount);
if((_iicDataCount--)==0)
break; //IIC operation is stopped because of IICCON[4]
rIICDS = _iicData[_iicPt++];
for(i=0;i<10;i++); //For setup time until rising edge of IICSCL
//IICCON Transmit clockvalue [3:0] = 1111 : Tx clock = IICCLK/(IICCON[3:0]+1).
//IICCON Interrupt pending flag [4 ] = 0 : 1) No interrupt pending (when read).
// 2) Clear pending condition &
// Resume the operation (when write).
//IICCON Tx/Rx Interrupt [5 ] = 1 : Enable
//IICCON Tx clock source selection [6 ] = 0 : IICCLK = fPCLK /16
//IICCON Acknowledge generation [7 ] = 1 : Enable
rIICCON = 0xaf; //Resumes IIC operation.
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -