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

📄 main.c

📁 ds18b20在stc89c58rd+下使用C语言调试通过
💻 C
字号:
#include <P8XC5X2.H>
 #include <intrins.H>
#include "sja_bcanconf.h"
#include "X5045.h"
sbit io=P2^6;
/*CAN通信定义*/
volatile unsigned char bdata flag_init; 	//保存中断寄存器值
sbit rcv_flag=flag_init^0; 		//接收中断标志
sbit err_flag=flag_init^2; 		//错误中断标志
unsigned char SendBuf[6];	   	//CAN发送缓冲区
unsigned char SampleHVal[8],SampleLVal[8];  //模拟量采集结果
#define		BaseID			0
#define		RTR				0
#define		DLC				4

#define V_T1s		255		//1秒
#define V_T1m		20
#define V_T50ms		10		//100ms
#define V_TH0   	0xEA  	/*10ms ,!notice: crystal 24MHz */
#define V_TL0   	0x00

#define TERMINAL	0x00		//主机命令CAN通信标识兼功能码 

volatile unsigned char CanID;			      //当前CAN节点的标识
void LedTest()
{
	static char led=1;
	led=!led;
	io=led;	
}
void InitWtd()
{
	wren_dog();				//看门狗写使能
	wrsr_dog(0x03);			//看门狗周期1.4秒
	wrdi_dog();				//看门狗写禁止	
}
void FeedDog()
{
	 rest_dog();	
} 
void delayUs()
{
    _nop_();
}

void delayMs(unsigned char a)
{
    unsigned char i, j;
    for(i = a; i > 0; i--)
        for(j = 100; j > 0; j--);
}

/**//*****************************DS18B20*******************************/
sbit ds = P1^0;
//初始化DS18B20
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
void dsInit()
{
    //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us
    unsigned char i;  
    ds = 0;
    i = 100;   //拉低约800us, 符合协议要求的480us以上
    while(i>0) i--;
    ds = 1;    //产生一个上升沿, 进入等待应答状态
    i = 5;
    while(i>0) i--;
}

void dsWait()
{
      unsigned char i;
      while(ds)FeedDog(); 
      while(~ds)FeedDog();  //检测到应答脉冲
	  //LedTest();
	  i = 4;
      while(i > 0) i--;
}

//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
    unsigned char i;
    bit b;
    ds = 0;
    i++;   //延时约8us, 符合协议要求至少保持1us
    ds = 1; 
    i++; i++; //延时约16us, 符合协议要求的至少延时15us以上
    b = ds;
    i = 10; 
    while(i>0) i--;  //延时约64us, 符合读时隙不低于60us要求
    return b;
}

//读取一字节数据, 通过调用readBit()来实现
unsigned char readByte()
{
    unsigned char i;
    unsigned char j, dat;
    dat = 0;
    for(i=0; i<8; i++)
    {
        j = readBit();
        //最先读出的是最低位数据
        dat = (j << 7) | (dat >> 1);
    }
    return dat;
}

//向DS18B20写入一字节数据
void writeByte(unsigned char dat)
{
    unsigned char i;
    unsigned char j;
    bit b;
    for(j = 0; j < 8; j++)
    {
        b = dat & 0x01;
        dat >>= 1;
        //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
        if(b)   
        {
            ds = 0;
            i++; i++; i++; //拉低约16us, 符号要求15~60us内
            ds = 1;    
            i = 10; while(i>0) i--;  //延时约64us, 符合写时隙不低于60us要求
        }
        else  //写"0", 将DQ拉低60us~120us
        {
            ds = 0;
            i = 10; while(i>0) i--;  //拉低约64us, 符号要求
            ds = 1;
            i++; i++;  //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
        }
    }
}

//向DS18B20发送温度转换命令
void sendChangeCmd()
{
    dsInit();   //初始化DS18B20, 无论什么命令, 首先都要发起初始化
    dsWait();   //等待DS18B20应答
    delayMs(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
    writeByte(0x44); //写入温度转换命令字 Convert T
}

//向DS18B20发送读取数据命令
void sendReadCmd()
{
    dsInit();
    dsWait();
    delayMs(1);
    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
    writeByte(0xbe); //写入读取数据令字 Read Scratchpad
}

//获取当前温度值
void getTmpValue()
{
    sendReadCmd();
    //连续读取两个字节数据 
    SampleLVal[0] = readByte(); 
    SampleHVal[0] = readByte();
	//if(SampleHVal[0]==0xFF)LedTest();
}
/**//*****************************DS18B20*******************************/
void InitCPU()
{
	EX0	=1;
	PX0	=1;
}
void CheckCan()
{
	if(rcv_flag)                                //if there is receive charerrupt
    {					
	}			
	if(err_flag)
	{
		 EA=0;
		 err_flag=0;                            //错误标志位清零
         Config_SJA();                        	//初始化SJA
		 EA=1;		
	}	
}
void SendByCan()
{
	SendBuf[0]=TERMINAL;		//主机标识
	SendBuf[1]=0x00|DLC;		//标识低3位和RTR以及请求数据位数
	SendBuf[2]=CanID;			//本地CAN标识
	SendBuf[3]=0;				//第i路遥测值
	SendBuf[4]=SampleLVal[0];	//遥测低字节值
	SendBuf[5]=SampleHVal[0];	//遥测高字节值
	BCAN_DATA_WRITE(SendBuf);
	BCAN_CMD_PRG(TR_CMD);			
}
void InitCanID()
{
	//读入P2口状态,其中0~3为跳线设置
	CanID=~P2;
	CanID&=0x0f;
	CanID|=0x80;
}

void main()
{
	InitCanID();			//计算当前节点的CAN标识
	Config_SJA();		   	//CAN初始化,SJA1000配置
	InitCPU();				//CPU初始化	
	P3_4=0;
	P1=0;
	InitWtd();				//看门狗电路初始化
	sendChangeCmd();
    while(1)
    {
		CheckCan();
        delayMs(255); //温度转换时间需要750ms以上
		FeedDog();
		delayMs(255);
		delayMs(255);
		FeedDog();
		delayMs(255);
		delayMs(255);
		FeedDog();
		delayMs(255);
		delayMs(255);
        getTmpValue();
		SendByCan();
		//LedTest();
        sendChangeCmd();
		FeedDog();
    }
}
void SJA_INTR() interrupt 0 using 1
{
	SJA_BCANAdr=REG_INTERRUPT; 					//指针指向中断寄存器
	flag_init=*SJA_BCANAdr; 					//保持中断寄存器值
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -