51单片机两个IO口分别接ds18b20程序

51单片机两个IO口分别接ds18b20程序,第1张

//DS从机程序

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

#define SLAVE 0x01

#define BN 6

sbit LCD_RS = P2^5; /定义LCD控制端口/

sbit LCD_RW = P2^6;

sbit LCD_EN = P2^7;

sbit DS1=P1^0;

sbit DS2=P1^1;

sbit key3=P3^5;

sbit tem=P3^3;

sbit win=P3^4;

sbit key1=P3^6;

sbit key2=P3^7;

uint temp1,temp2,tempH,tempL; // variable of temperature

uchar flag1,aa,we;

uchar A1,A2,A3,A4,B1,B2,B3,B4; // sign of the result positive or negative

uchar dis1[16]={76,45,84,'0','0','','0',32,32,72,45,84,'0','0','','0'};

uchar dis2[16]={48,49,32,'0','0','','0',32,32,48,50,32,'0','0','','0'};

uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9'};

uchar trbuf[6];

bit tready;

bit rready;

void str(void);

void sre(void);

void delay(int ms)

{

int i;

while(ms--)

{

for(i = 0; i< 250; i++)

{

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

result = (bit)(P0&0x80);

LCD_EN = 0;

return result;

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos|0x80); //数据指针=80+地址变量

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x0c); //显示开,关光标

delay(5);

lcd_wcmd(0x06); //移动光标

delay(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay(5);

lcd_wcmd(0x06); //向右移动光标

delay(5);

}

//

/ /

/ 闪动子程序 /

/ /

//

void flash()

{

delay(600); //控制停留时间

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200); //延时

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200);

}

/void delay(uint count) //delay

{

uint i;

while(count)

{

i=100;

while(i>0)

i--;

count--;

}

} /

///////功能:串口初始化,波特率9600,方式1///////

void Init(void)

{

TMOD=0x20;

TL1=0xfd;

TH1=0xfd;

PCON=0x00;

TR1=1;

SCON=0xf0;

ES=1;

EA=1;

}

void dsreset(uchar DS) //send reset and initialization command 18B20复位,初始化函数

{

uint i;

if(DS==1)

{

DS1=0;

i=103;

while(i>0)i--;

DS1=1;

i=4;

while(i>0)i--;

}

if(DS==2)

{

DS2=0;

i=103;

while(i>0)i--;

DS2=1;

i=4;

while(i>0)i--;

}

}

bit tmpreadbit(uchar DS) //read a bit 读DS2 1位数据函数

{

uint i;

bit dat;

if(DS==1)

{

DS1=0;i++; //i++ for delay

DS1=1;i++;i++;

dat=DS1;

i=8;while(i>0)i--;

}

if(DS==2)

{

DS2=0;i++; //i++ for delay

DS2=1;i++;i++;

dat=DS2;

i=8;while(i>0)i--;

}

return (dat);

}

uchar tmpread(uchar DS) //read a byte date 读1字节函数

{

uchar i,j,dat;

dat=0;

if(DS==1)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(1);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

if(DS==2)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(2);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

return(dat);

}

void tmpwritebyte(uchar dat,uchar DS) //write a byte to ds18b20 向1820写一个字节数据函数

{

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(DS==1)

{

if(testb) //write 1

{

DS1=0;

i++;i++;

DS1=1;

i=8;while(i>0)i--;

}

else

{

DS1=0; //write 0

i=8;while(i>0)i--;

DS1=1;

i++;i++;

}

}

if(DS==2)

{

if(testb) //write 1

{

DS2=0;

i++;i++;

DS2=1;

i=8;while(i>0)i--;

}

else

{

DS2=0; //write 0

i=8;while(i>0)i--;

DS2=1;

i++;i++;

}

}

}

}

void tmpchange(uchar DS) //DS18B20 begin change 开始获取数据并转换

{

if(DS==1)

{

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,1);

} // initiates a single temperature conversion 写温度转换指令

if(DS==2)

{

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,2);

} // initiates a single temperature conversion 写温度转换指令

}

uint tmp1(void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1);

tmpwritebyte(0xbe,1);

a=tmpread(1); //读低8位

b=tmpread(1); //读高8位

temp1=b;

temp1<<=8; //two byte compose a int variable 两个字节组合为1个字

temp1=temp1|a;

tt=temp100625; //温度在寄存器中是12位,分辨率是00625

temp1=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp1=temp1+5; //误差补偿

return temp1;

}

uint tmp2( void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2);

tmpwritebyte(0xbe,2);

a=tmpread(2); //读低8位

b=tmpread(2); //读高8位

temp2=b;

temp2<<=8; //two byte compose a int variable 两个字节组合为1个字

temp2=temp2|a;

tt=temp200625; //温度在寄存器中是12位,分辨率是00625

temp2=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp2=temp2+5; //误差补偿

return temp2;

}

void delay10ms() //delay

{

uchar a,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

uchar display(uint temp1,uint temp2) //显示程序

{

uchar i;

A1=temp1/100;

A2=temp1%100/10;

A3=temp1%100%10;

B1=temp2/100;

B2=temp2%100/10;

B3=temp2%100%10;

trbuf[0]=A1;

trbuf[1]=A2;

trbuf[2]=A3;

trbuf[3]=B1;

trbuf[4]=B2;

trbuf[5]=B3;

dis1[3]=tab[tempL10/100];

dis1[4]=tab[tempL10%100/10];

dis1[6]=tab[tempL10%100%10];

dis1[12]=tab[tempH10/100];

dis1[13]=tab[tempH10%100/10];

dis1[15]=tab[tempH10%100%10];

dis2[3]=tab[A1];

dis2[4]=tab[A2];

dis2[6]=tab[A3];

dis2[12]=tab[B1];

dis2[13]=tab[B2];

dis2[15]=tab[B3];

delay(1);

lcd_pos(0); //设置显示位置为第一行的第1个字符

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis1[i]);

}

delay(2);

lcd_pos(0x40);

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis2[i]);

}

return (A1,A2,A3,B1,B2,B3);

}

void TemC()

{

if(temp1<=(tempL10)||temp2<=(tempL10)) tem=0;

else tem=1;

if (temp1>=(tempH10)||temp2>=(tempH10)) win=0;

else win=1;

}

uchar chan()

{

if(key1==0)

{

tempL++;

while(key1==0);

if(tempL>35)

tempL=0;

}

if(key2==0)

{

tempH++;

while(key2==0);

if(tempH>35)

tempH=0;

}

return (tempH,tempL);

}

//

void main()

{ //uchar a;

//uchar i;

delay(10);

lcd_init();

Init();

tempH=35;

tempL=15;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

tready=1;

rready=1;

}

}

void ssio(void)interrupt 4

{

uchar a;

RI=0;

ES=0;

if(SBUF!=SLAVE)

{

ES=1;

goto reti;

}

SM2=0;

SBUF=SLAVE;

while(TI!=1);

TI=0;

while(RI!=1);

RI=0;

if(RB8==1)

{

SM2=1;

ES=1;

goto reti;

}

a=SBUF;

if(a==0x02)

{

if(tready==1)

SBUF=0x02;

else

SBUF=0x00;

while(TI!=1);

TI=0;

str();

goto reti;

}

else

{

SBUF=0x08;

while(TI!=1);

TI=0;

SM2=1;

ES=1;

}

reti:RI=0;

SM2=1;

ES=1;

}

void str(void)

{

uchar i;

tready=0;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

for(i=0;i<BN;i++)

{

SBUF=trbuf[i];

while(TI!=1);

TI=0;

}

while(RI!=1);

RI=0;

if(RB8==1)goto loop;

}

loop:SM2=1;

ES=1;

}

是实物开发板吗?单片机是STC12C5A60S2吧?接DS1302的IO脚P11,要根据读写设置成不同模式,在读1302时为高阻输入模式,在写1302时,恢复成双向IO模式。试一下,看行不行,我就是采用这种方法解决的。

licenses文件夹没有的话需要在相应系统的路径下手动建立,然后将拷贝到之前建立的那个licenses文件夹,DSLicSRvtxt在破解文件夹里,好好找找,其实就是个服务地址+端口的,确实找不到的话自己手动建一个,默认内容是127001:4085

$NOMOD51

$INCLUDE (src\main\pininc)

NAME DS2438

PRinitializeDS2438 SEGMENT CODE

PR_writeDS2438 SEGMENT CODE

PRreadDS2438 SEGMENT CODE

PR_function0x0BEDS2438 SEGMENT CODE

EXTRN CODE ( CCSTPTR )

PUBLIC _function0x0BE

; static void initialize( void )

RSEG PRinitializeDS2438

initialize:

USING 0

SETB DQ

NOP

CLR DQ

MOV R7, #240

DJNZ R7, $

SETB DQ

MOV R7, #240

DJNZ R7, $

RET

; static void write( char x )

RSEG PR_writeDS2438

_write:

USING 0

MOV R0, #8

loop1:

RRC A

CLR DQ

NOP

MOV DQ, C

MOV R7, #60

DJNZ R7, $

SETB DQ

DJNZ R0, loop1

RET

; static char read( void )

RSEG PRreadDS2438

read:

USING 0

MOV R0, #8

loop2:

CLR DQ

NOP

SETB DQ

NOP

MOV R7, #6

DJNZ R7, $

MOV C, DQ

RRC A

MOV R7, #22

DJNZ R7, $

DJNZ R0, loop2

RET

; void function0x0BE( char pc )

RSEG PR_function0x0BEDS2438

_function0x0BE:

USING 0

LCALL initialize

MOV A, #0CCH

LCALL _write

MOV A, #044H

LCALL _write

LCALL initialize

MOV A, #0CCH

LCALL _write

MOV A, #0BEH

LCALL _write

LCALL read

ANL A, #0F0H

MOV R4, A

LCALL read

ANL A, #00FH

ORL A, R4

SWAP A

;passing generic ptr in R3-R1(type/MSB/LSB)

LCALL CCSTPTR

RET

END

;仅限于KEIL编译器和89C51或兼容系列单片机的DS18B20汇编程序

;我截断了温度的小数部分,觉得精度不够的话,楼主可以修改部分或全部的代码

;能给点分咩楼主~~

si、di分别是源、目的变址寄存器,bx是数据基址寄存器,bp是栈基址寄存器,SS、DS是段地址寄存器。

物理地址=段地址×16+偏移地址,指令中出现BP作地址,则其段地址为SS,否则就为DS。

汇编语言比机器语言易于读写、易于调试和修改,同时也具有机器语言执行速度快,占内存空间少等优点,但在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。

以上就是关于51单片机两个I/O口分别接ds18b20程序全部的内容,包括:51单片机两个I/O口分别接ds18b20程序、帮忙看一下DS1302的程序、catia v5-6(r2014)安装过程中 将DS应用程序连接到DSLS时找不到licenses文件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9700858.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存