A. ds18820与单片机怎么连接啊,请求高手指教,小妹比较菜,希望能说详细点,谢咯
DS18B20资料先下一份。
连接方法灰常简单。加电。其中DQ连到单片机某个管脚,最好上拉5.1K电阻。
程序如下:
//Author:seuzhouww
#include <reg52.h>
#define FAILURE 0
#define SUCCESS 1
#define uchar unsigned char
#define uint unsigned int
#ifdef F110592MHZ
#define DELAY1820_30 30 //30us时基
#endif
#define SKIPROM 0xcc //取消配置或预置地址(单个DS18B20应用情况下)。
#define MATCROM 0x55 //配置或预置地址
#define WRSCRAT 0x4e //写中间暂存器内容(报警阈值)2字节,后面跟TH,TL.
#define RDSCRAT 0xbe //读中间暂存器内容(报警阈值)9字节
#define CPSCRAT 0x48 //备份中间暂存器内容(报警阈值)需要延迟10mS等待编程。
#define CONVTEM 0x44 //转换温度命令。
#define CURRADD 0x8701 //0x00000000 00008701,64位ROM地址。
#define ALARMTEMPL 0x00
#define ALARMTEMPH 0x50
bit Reset1820(void); //复位DS18B20,返回在线信息。
unsigned char Read1820(void); //获取1个字节。
void Write1820(unsigned char dd);
void Control1820(unsigned char); //向DS18B20发命令。
unsigned int ReadTemp(void); //此函数直接读取温度.
sbit DQ =P3^5; //第一版为P3.3 第二版为P3.5
unsigned char CurTempL; //当前温度L
unsigned char CurTempH; //当前温度H
unsigned char AlarmTempL; //当前温度L
unsigned char AlarmTempH;
bit Reset1820(void) //复位DS18B20,返回在线信息。
{
uchar i;
DQ=1;
DQ=0;
for(i=0;i<255;i++); //复位低脉宽480-960uS.
DQ=1;
for(i=0;i<DELAY1820_30;i++);
for(i=0;i<DELAY1820_30;i++);
i=0;
while((DQ==1)&&(i<DELAY1820_30)){i++;}
if(i==DELAY1820_30)return FAILURE;//器件在线情况下的ACK.
for(i=0;i<200;i++); //等待器件验证结束.
DQ=1;
return SUCCESS;
}
uchar Read1820(void) //获取1个字节。
{
uchar i=0;
uchar j=0;
uchar k=0;
for(k=0;k<8;k++) //读取8位
{
DQ=1;
DQ=1;
j>>=1;
DQ=0;
DQ=1; //在读取前先置1 !!!
for(i=9;i<DELAY1820_30;i++); //14uS
if(DQ==1) j+=0x80; //(LSB)D0 First.
for(i=0;i<DELAY1820_30;i++);
for(i=0;i<DELAY1820_30;i++);
DQ=1;
}
return j;
}
void Write1820(uchar dat)
{
uchar i=0;
uchar j=dat;
uchar k=0;
for(k=0;k<8;k++) //读取8位
{
DQ=1;
DQ=1;
DQ=0;
DQ=0;
DQ=0;
if((j&1)==1) //(LSB)D0 First.
DQ=1;
for(i=0;i<DELAY1820_30;i++);
for(i=0;i<DELAY1820_30;i++);
for(i=0;i<DELAY1820_30;i++);
j>>=1;
DQ=1;
}
}
void Control1820(uchar command) //向DS18B20发命令。
{
uint add;
uchar crc;
uchar i;
switch(command)
{
case SKIPROM:// 0xcc //取消配置或预置地址(单个DS18B20应用情况下)。
Write1820(SKIPROM);
break;
case MATCROM:// 0x55 //配置或预置地址
Write1820(MATCROM);
add=CURRADD;
Write1820(add&0xff);
Write1820(add>>8);
for(i=0;i<6;i++)
Write1820(0); //64bit ROM add.
break;
case WRSCRAT:// 0x4e //写中间暂存器内容(报警阈值)2字节,后面跟TH,TL.
Write1820(WRSCRAT);
Write1820(ALARMTEMPL);
Write1820(ALARMTEMPH);
break;
case RDSCRAT:// 0xbe //读中间暂存器内容(报警阈值)9字节
Write1820(RDSCRAT);
CurTempL=Read1820(); //当前温度L
CurTempH=Read1820(); //当前温度H
AlarmTempL=Read1820(); //当前温度L
AlarmTempH=Read1820(); //当前温度H
crc=Read1820();
crc=Read1820();
crc=Read1820();
crc=Read1820();
crc=Read1820();
break;
case CPSCRAT:// 0x48 //备份中间暂存器内容(报警阈值)需要延迟10mS等待编程。
Write1820(CPSCRAT);
//delay 6mS
add=6500;
while((add--)!=0);
break;
case CONVTEM:// 0x44 //转换温度命令。
Write1820(CONVTEM);
break;
default:
break;
}
}
uint ReadTemp(void) //此函数直接读取温度./获取温度。
{
//以下考虑的是仅单个传感器的读取。Table5
uint temp;
bit presence;
presence=Reset1820();
if(presence==FAILURE) return 0;
Control1820(SKIPROM);
Control1820(CONVTEM);
while(Read1820()!=0xff);
presence=Reset1820();
if(presence==FAILURE) return 0;
Control1820(SKIPROM);
Control1820(RDSCRAT);
presence=Reset1820();
if(presence==FAILURE) return 0;
temp=CurTempH;
temp<<=8;
temp+=CurTempL;
return temp;
}
B. 普通单片机与加有前缀ds的单片机有什么区别
都是Microchip公司的PIC系列的单片机。
但你说的后者PIC30F2010不存在。不信去PIC单片机的官方网站查:www.microchip.com
PIC单片机有很多种。PIC10、PIC12、PIC16、PIC18这些都是8位的单片机
而你说的dsPIC30和dsPIC33系列单片机是属于带DSP(数字信号处理)功能的16位单片机。而PIC24系列是跟dsPIC30系列单片机相似,就是不带DSP的16位单片机。
还有就是PIC32系列是32位的单片机,是microchip为了和ARM争夺高端32位嵌入式芯片市场而生产地。
补充:有dsPIC字样的是带DSP功能的16位单片机,可以理解为有ds字样的就是DSP芯片。DSP芯片:数字处理芯片,可以在一个时钟周期里完成一个MAC,就是16位乘上16位数,其积再加上一个32位数这两个操作一个时钟周期完成。在dsPIC中,就是两个晶振周期完成,如果晶振是4MHz的话,就是说上述乘法和加法的操作能在2微秒内完成。这MAC是衡量DSP芯片的一个指标。还有就是FFT(快速傅里叶变换)等等。
PIC18和PIC24系列的也有内部的乘法器,但他们的乘法器速度远远追不上DSP芯片的MAC。 你可以看看网络对DSP的详解。
DSP怎么用,举个例子:有的语音DSP芯片,可以做一个数字滤波器,两个人同时说话,麦克风录入这些声音到这个滤波器里,滤波器的喇叭可以实时算出某个人的声音,并且只输入这个人的声音(实时的,旁观者根本分辨不出延时)。这就是DSP芯片的快速数字运算能力所决定的。不要跟我说计算机的CPU也有这么快,计算机的微处理器只是频率高,在某些工程数学运算场合,它根本比不上DSP芯片。
至于Microchip的dsPIC30系列,因为它是面向于对电机、变频器的数字控制,所以它要实现上述的语音实时滤波比较困难。至于dsPIC33系列的,因为我没用过这系列的DSP,所以不敢确定是否能实现上述功能。
使用DSP芯片的快速运算功能需要编程者有《信号与系统》《复变函数》《有限元分析》《小波变换》等等的研究生才学的课程,如果只是拿来做普通单片机,那就太大材小用了。
C. 单片机 DS18B20
意思是说在电气结构上此时要经过一个足够的电阻上拉,这样才能确保之后18B20有能力把总线拉低。
总线主控端有义务产生符合要求的初始化时序,所以才要写程序啊……
D. DS1820 怎么用于单片机哦
他靠单线端口通讯,就是它只需要一根线和单片机连接,剩下两根分别接电源正极和负极。
编程如下:
先使用一段汇编语言,将其保存为ds.asm
/*-------------------------------------------
程序名: 温度数据汇编精确时间采集
编写人: 杜洋
-------------------------------------------*/
DSSP SEGMENT CODE ;程序段
PUBLIC DSS ;入口地址,跳转到DL标号处执行汇编程序
RSEG DSSP ;程序段
IN EQU P1.6
FLAG1 EQU 05H ;DS18B20器件存在标志
TTL EQU 07H ;温度读出值(高位在TTL-1中,低位在TTL中)
;-------------------------------------------DS18B20读数据程序(0~99度)
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB IN
NOP
CLR IN
;主机发出延时537微秒的复位低脉冲
MOV R1,#18;#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB IN;然后拉高数据线
NOP
NOP
NOP
NOP;12倍
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV R0,#0DEH;#25H
TSR2:
JNB IN,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R7,#6
TSR6:
MOV R0,#117
DJNZ R0,$ ; 时序要求延时一段时间 */
DJNZ R7,TSR6 ; 时序要求延时一段时间 */
TSR7:
SETB IN
RET
;------------------------------------------读出转换后的温度值
DSS:
DS1820PRO:
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
SETB IN
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
jmp BCD33 ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
CALL DL1MS
SETB IN
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200; 将读出的温度数据保存到35H/36H
MOV A,TTL
MOV B,TTL-1
MOV C,B.0;将28H中的最低位移入C
RRC A
MOV C,B.1
RRC A
MOV C,B.2
RRC A
MOV C,B.3
RRC A
MOV TTL,A
BCD33:
JB FLAG1,BCD44
mov R7,#0FFH
JMP TORET
BCD44:
MOV R7,TTL
TORET:
RET
;--------------------------------写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR IN
MOV R3,#36;#6
DJNZ R3,$
RRC A
MOV IN,C
MOV R3,#192;#23
DJNZ R3,$
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,WR1
SETB IN
RET
;-----------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TTL ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB IN
MOV R3,#54;#9
RE10:
DJNZ R3,RE10
MOV C,IN
MOV R3,#138;#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
DL1MS:
MOV R7,#6
DL1MS2:
MOV R6,#255
DJNZ R6,$
DJNZ R7,DL1MS2
RET
END
然后可以这样在C语言中调用(在Keil中,且主程序文件与ds.asm放于同一文件夹内,以下是配合带中文字符库的128×64LCD显示屏,完整程序Hi我)
sbit DQ = P1 ^ 6; //DS18B20温度传感器定义
unsigned char DSS (void); //汇编语言读18B20温度程序声明
i = DSS();//将DSS汇编程序取得的温度值放入温度寄存器变量
if(i < 60){//读不出温度数据时不显示温度字样
lcm_w_test(0,0x9C); //温度在LCM上的写入位置
lcm_w_word("温度"); //度C
lcm_w_test(1,i/10+0x30); //显示温度十位
lcm_w_test(1,i%10+0x30); //个位
lcm_w_word("℃"); //度C
}
}
E. 单片机中DS03H什么意思
DS03H没有任何特别意义,或许应该是D503H,这是一个双字节16进制数。
F. DS单片机例如(DS12CR887+5)如何下载程序,例如要用到什么软件、什么线或者什么驱动的
根据你使用的单片机来决定软件
另外DS12C887是一款RTC芯片不是单片机
G. 单片机ds18b20程序翻译
将定时器的初值改一下,4毫秒扫描可能稍微有点短,改为5毫秒试试。
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
H. dsPIC单片机
没有真没有
I. 单片机dsdi,dsdo dsck什么意思
dsck: 时钟信号。
dsdi: 数据输入。
dsdo:数据输出。
上图是 MPC850的时序图,圆圈内是芯片参数说明的序号,你忽略即可。
J. 51单片机与DS18B20程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P2^2; //数据口define interface
sbit la = P2^6; //数码管段选
sbit wela = P2^7; //数码管位选
uint temp; //温度值 variable of temperature
//不带小数点
unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//带小数点
unsigned char code table1[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
/*************精确延时函数*****************/
void delay(unsigned char i)
{
while(--i);
}
/******************************************
此延时函数针对的是12Mhz的晶振
delay(0):延时518us 误差:518-2*256=6
delay(1):延时7us (原帖写"5us"是错的)
delay(10):延时25us 误差:25-20=5
delay(20):延时45us 误差:45-40=5
delay(100):延时205us 误差:205-200=5
delay(200):延时405us 误差:405-400=5
*******************************************/
/*****************DS18B20******************/
void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command
{
DQ = 1; //DQ复位,不要也可行。
delay(1); //稍做延时
DQ = 0; //单片机拉低总线
delay(250); //精确延时,维持至少480us
DQ = 1; //释放总线,即拉高了总线
delay(100); //此处延时有足够,确保能让DS18B20发出存在脉冲。
}
uchar Read_One_Byte() //读取一个字节的数据read a byte date
//读数据时,数据以字节的最低有效位先从总线移出
{
uchar i = 0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 0; //将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
_nop_(); //至少维持了1us,表示读时序开始
dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位。
DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay(1); //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ) //控制器进行采样
{
dat |= 0x80; //若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0
}
delay(10); //此延时不能少,确保读时序的长度60us。
}
return (dat);
}
void Write_One_Byte(uchar dat)
{
uchar i = 0;
for(i=8;i>0;i--)
{
DQ = 0; //拉低总线
_nop_(); //至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ = dat&0x01; //从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
delay(10); //必须让写时序持续至少60us
DQ = 1; //写完后,必须释放总线,
dat >>= 1;
delay(1);
}
}
uint Get_Tmp() //获取温度get the temperature
{
float tt;
uchar a,b;
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0x44); //温度转换指令
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0xbe); //读暂存器指令
a = Read_One_Byte(); //读取到的第一个字节为温度LSB
b = Read_One_Byte(); //读取到的第一个字节为温度MSB
temp = b; //先把高八位有效数据赋于temp
temp <<= 8; //把以上8位数据从temp低八位移到高八位
temp = temp|a; //两字节合成一个整型变量
tt = temp*0.0625; //得到真实十进制温度值
//因为DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
temp = tt*10+0.5; //放大十倍
//这样做的目的将小数点后第一位也转换为可显示数字
//同时进行一个四舍五入操作。
return temp;
}
/****************数码码动态显示函数**************/
void Display(uint temp) //显示程序
{
uchar A1,A2,A3;
A1 = temp/100; //百位
A2 = temp%100/10; //十位
A3 = temp%10; //个位
la = 0;
P0 = table[A1]; //显示百位
la = 1; //打开段选,对应74573的锁存位,高电平不锁存
la = 0;
wela = 0;
P0 = 0x7e;
wela = 1; //打开位选
wela = 0;
delay(0);
la = 0;
P0 = table1[A2]; //显示十位,使用的是有小数点的数组(因为temp值扩大了10倍,虽然是十位,实际为个位)
la = 1;
la = 0;
wela = 0;
P0 = 0x7d;
wela = 1;
wela = 0;
delay(0);
P0 = table[A3]; //显示个位
la = 1;
la = 0;
P0 = 0x7b;
wela = 1;
wela = 0;
delay(0);
}
void main()
{
while(1)
{
Display(Get_Tmp());
}
}