⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wds1620.c

📁 C8051F.rar
💻 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 + -