//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文件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)