📄 wds1620.c
字号:
//参考程序A:WDS1620.C
/*DS1620.C 数字温度传感器DS1620测温实验:
P0.2接DQ位 P0.3接 CLK位,P0.4接RST位,P0.0接SDA,P0.1接SCL.
SAA1064驱动四位数码管显示温度值:< 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) 主收发器发送起始位成功.再送从机//写地址.
#define SMB_MTADDACK 0x18 //(MT) 主收发器发送从地址+W成功;收到 ACK.
#define SMB_MTDBACK 0x28 // (MT) 主收发器发送数据字节成功;收到ACK.
#define SMB_MRADDACK 0x40 // (MR) 主收发器发送从地址+R成功;收到 ACK.
#define SMB_MRADDNACK 0x48 // (MR) 主收发器发送从地址+R成功;收到NACK.
#define SMB_MRDBACK 0x50 // (MR) 主收发器接收数据成功;主机发送ACK
#define SMB_MRDBNACK 0x58 // (MR) 主收发器接收数据成功;主机发送NACK
char COMMAND; // 保存从地址加读/写位,用在中断服务程序SMBus ISR中
char WORD; // 保存在SUMBUS总线上传送的数或刚被接受到的数据。
unsigned char totalnumber,sendnumber;
unsigned char xdata SENDMODE;
bit SM_BUSY; //该位在开始接收数据或发送数据时被置位。在中断完成后被清0
unsigned char wr_data[8]; //数组wr_data[8]中存放要写入SAA1064的数据
unsigned char rd_data[8]; //数组rd_data[8]中存放从DS1620中读出的数据
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中读取数据
{
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) //初始化系统时钟
{
int i; // 延时计数器
OSCXCN = 0x67; // 启动外部时钟 (11.0592MHz 晶振)
for (i=0; i < 256; i++);
while (!(OSCXCN & 0x80)); // 等待晶振稳定
OSCICN = 0x88; // 选择外部晶振作系统时钟,时钟丢失检测
}
void PORT_Init (void)
{
XBR0 = 0x01; // 使能 SMBus
XBR2 = 0x44; // 使能交叉开关和弱上拉.
}
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 忙碌标志置1
SMB0CN = 0x44; // 允许SMBus , ACK 应答信号为低
COMMAND = (chip_select | WRITE); // COMMAND = 7位地址加读/写位
STO = 0;
STA = 1; // 数据传送开始
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; //关看门狗
SYSCLK_Init (); //初始化时钟
;OSCICN= 0x14;
PORT_Init (); //初始化IO口
Init1620();
SMB0CN = 0x44; // 使能SMBus ,在确认周期响应(ACK)低电平 (AA = 1)
SMB0CR = 0xc9; // SMBus 速率为100 kHz,系统时钟: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; //最低位对应0.5度
wr_data[0] = 0x00; //将二进制温度值转换为十进制并存放在数组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;//查出字型码并加上小数点
temp = (w%10);
wr_data[5] = Number[temp]; //小数位
SLA_SEND(CHIP_B,wr_data,0x06); //十进制温度值送SAA1064驱动的数码管
sleep_ms(250);
sleep_ms(250);
_nop_();
sleep_ms(250);
sleep_ms(250);
}
}
void SMBUS_ISR (void) interrupt 7 //中断服务程序
{
switch (SMB0STA){ // (SMB0STA 是中断状态寄存器)
case SMB_START: //0x08
SMB0DAT = COMMAND ; // 装入从器件写地址
STA = 0; // 人工清除STA
SI = 0; // 清除中断标致位
break;
case SMB_MTADDACK: //SMB0STA=0x18
SMB0DAT = wr_data[0];
SI = 0; //清除中断标致位
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: //中断状无效,结束传送
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -