?? wds1620.c
字號:
//參考程序A:WDS1620.C
/*DS1620.C 數(shù)字溫度傳感器DS1620測溫實(shí)驗(yàn):
P0.2接DQ位 P0.3接 CLK位,P0.4接RST位,P0.0接SDA,P0.1接SCL.
SAA1064驅(qū)動四位數(shù)碼管顯示溫度值:< 0 1 3. 4>
*/
#include <c8051f020.h> // SFR declarations
#include <intrins.h>
#define WRITE 0x00 // 寫位
#define READ 0x01 // 讀位
#define CHIP_B 0x70 // SAA1064地址
#define SMB_START 0x08 //(MT & MR) 主收發(fā)器發(fā)送起始位成功.再送從機(jī)//寫地址.
#define SMB_MTADDACK 0x18 //(MT) 主收發(fā)器發(fā)送從地址+W成功;收到 ACK.
#define SMB_MTDBACK 0x28 // (MT) 主收發(fā)器發(fā)送數(shù)據(jù)字節(jié)成功;收到ACK.
#define SMB_MRADDACK 0x40 // (MR) 主收發(fā)器發(fā)送從地址+R成功;收到 ACK.
#define SMB_MRADDNACK 0x48 // (MR) 主收發(fā)器發(fā)送從地址+R成功;收到NACK.
#define SMB_MRDBACK 0x50 // (MR) 主收發(fā)器接收數(shù)據(jù)成功;主機(jī)發(fā)送ACK
#define SMB_MRDBNACK 0x58 // (MR) 主收發(fā)器接收數(shù)據(jù)成功;主機(jī)發(fā)送NACK
char COMMAND; // 保存從地址加讀/寫位,用在中斷服務(wù)程序SMBus ISR中
char WORD; // 保存在SUMBUS總線上傳送的數(shù)或剛被接受到的數(shù)據(jù)。
unsigned char totalnumber,sendnumber;
unsigned char xdata SENDMODE;
bit SM_BUSY; //該位在開始接收數(shù)據(jù)或發(fā)送數(shù)據(jù)時被置位。在中斷完成后被清0
unsigned char wr_data[8]; //數(shù)組wr_data[8]中存放要寫入SAA1064的數(shù)據(jù)
unsigned char rd_data[8]; //數(shù)組rd_data[8]中存放從DS1620中讀出的數(shù)據(jù)
sbit RST = P0^4; // RST位
sbit CLK = P0^3; // CLK位
sbit DQ = P0^2; // DQ位
void Delay(unsigned int TT) //延時
{
unsigned int k;
for(k=0;k<TT;k++){
_nop_();
}
}
void Write1620(unsigned char m) //向DS1620寫命令
{
unsigned char k,b=1;
RST = 1;
for(k=0;k<10;k++)
{
CLK = 0;
DQ = (m&b);
CLK = 1;
b = (b<<1);
}
return;
}
unsigned char INDS1620(void)
{
unsigned char j,k=0,b=1;
k=0;
b=1;
for (j=0;j<8;j++)
{
P2 = P2|0x20;
CLK =0;
if(DQ) k|=b;
CLK = 1;
b=(b<<1);
}
return k;
}
void OUTDS1620(unsigned char m)
{
unsigned char k,b=1;
RST =1;
for (k=0;k<8;k++)
{
CLK = 0;
DQ = (m&b);
CLK = 1;
b=(b<<1);
}
return;
}
void Init1620(void)
{
P2 = 0x00;
RST = 0;
RST = 1;
OUTDS1620(0x01);
Write1620(0x4c);
RST = 0;
RST = 1;
OUTDS1620(0x02);
Write1620(0x18);
RST = 0;
_nop_();
}
unsigned int RDDS1620(void) //從DS1620中讀取數(shù)據(jù)
{
unsigned char Temp_L,Temp_H;
RST = 1;
OUTDS1620(0xee);
RST = 0;
Delay(16);
RST = 1;
OUTDS1620(0xaa);
Temp_L = INDS1620(); //低8位溫度值
Temp_H = INDS1620(); //高8位溫度值
RST = 0;
return(Temp_H*0x100+Temp_L);
}
void sleep_ms(unsigned int count) //延時
{
unsigned char ii,jj;
for(ii=0;ii<count;ii++)
{
for(jj=0;jj<250;jj++)
_nop_();
}
}
void SYSCLK_Init (void) //初始化系統(tǒng)時鐘
{
int i; // 延時計(jì)數(shù)器
OSCXCN = 0x67; // 啟動外部時鐘 (11.0592MHz 晶振)
for (i=0; i < 256; i++);
while (!(OSCXCN & 0x80)); // 等待晶振穩(wěn)定
OSCICN = 0x88; // 選擇外部晶振作系統(tǒng)時鐘,時鐘丟失檢測
}
void PORT_Init (void)
{
XBR0 = 0x01; // 使能 SMBus
XBR2 = 0x44; // 使能交叉開關(guān)和弱上拉.
}
void SLA_SEND(char chip_select, char *wr_data, char number)
{
SENDMODE=0x01;
totalnumber=number;
sendnumber=number;
while(SM_BUSY); // SMBus 忙碌則等待
SM_BUSY = 1; // SMBus 忙碌標(biāo)志置1
SMB0CN = 0x44; // 允許SMBus , ACK 應(yīng)答信號為低
COMMAND = (chip_select | WRITE); // COMMAND = 7位地址加讀/寫位
STO = 0;
STA = 1; // 數(shù)據(jù)傳送開始
while(SM_BUSY);
}
void main (void)
{
unsigned char temp;
unsigned int w;
unsigned char data Number[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
WDTCN = 0xde;
WDTCN = 0xad; //關(guān)看門狗
SYSCLK_Init (); //初始化時鐘
;OSCICN= 0x14;
PORT_Init (); //初始化IO口
Init1620();
SMB0CN = 0x44; // 使能SMBus ,在確認(rèn)周期響應(yīng)(ACK)低電平 (AA = 1)
SMB0CR = 0xc9; // SMBus 速率為100 kHz,系統(tǒng)時鐘:11.0592MHZ
EIE1 |= 2; // SMBus 中斷使能
SM_BUSY = 0; // 釋放總線,開使傳輸
SI = 0;
EA=1; //開中斷
for (;;)
{
sleep_ms(250);
sleep_ms(250);
sleep_ms(250);
w = RDDS1620(); //從DS1620讀取溫度值并存放在W中
w = w*5; //最低位對應(yīng)0.5度
wr_data[0] = 0x00; //將二進(jìn)制溫度值轉(zhuǎn)換為十進(jìn)制并存放在數(shù)組wr_data[]中
wr_data[1] = 0x17;
wr_data[2] = 0x00;
temp = (w%1000)/100; //十位
wr_data[3] = Number[temp];
temp = (w%100)/10; //個位
wr_data[4] = Number[temp]|0x80;//查出字型碼并加上小數(shù)點(diǎn)
temp = (w%10);
wr_data[5] = Number[temp]; //小數(shù)位
SLA_SEND(CHIP_B,wr_data,0x06); //十進(jìn)制溫度值送SAA1064驅(qū)動的數(shù)碼管
sleep_ms(250);
sleep_ms(250);
_nop_();
sleep_ms(250);
sleep_ms(250);
}
}
void SMBUS_ISR (void) interrupt 7 //中斷服務(wù)程序
{
switch (SMB0STA){ // (SMB0STA 是中斷狀態(tài)寄存器)
case SMB_START: //0x08
SMB0DAT = COMMAND ; // 裝入從器件寫地址
STA = 0; // 人工清除STA
SI = 0; // 清除中斷標(biāo)致位
break;
case SMB_MTADDACK: //SMB0STA=0x18
SMB0DAT = wr_data[0];
SI = 0; //清除中斷標(biāo)致位
break;
case SMB_MTDBACK: //SMB0STA=0x28
switch (SENDMODE){ // Check only lower 4 bits.
// OP_CODE is a READ. Send repeated START.
case 1:
sendnumber--;
if(sendnumber)
SMB0DAT = wr_data[totalnumber-sendnumber];
else{
STO=1;
SM_BUSY=0;
}
break;
case 0:
STO = 0;
STA = 1;
break;
default: //中斷狀無效,結(jié)束傳送
STO = 1;
SM_BUSY = 0;
break;
}
SI = 0;
break;
case SMB_MRDBNACK: //SMB0STA=0x58
rd_data[0] = SMB0DAT;
STO = 1;
SM_BUSY = 0;
AA = 1; // Set AA for next transfer
SI = 0;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -