老实说,从专业角度来看,楼主的帖子立意肤浅,文笔晦涩,根本不值一顶;但既然已经上当进来,把帖子点开,不顶,则意味着少积1分,失去早日升级的机会。
  顶,还是不顶?我的思想进行着激烈的斗争。顶,可以为自己增加可耻但宝贵的1分,但崇高的信仰与无暇的品格毁于一旦;不顶,高尚的风范得以保全,若干年后,还可以对孙子说“很久以前,爷爷曾今有过一个机会……”,但毫无疑问永远成为论坛的落后分子。
  我不断地踟蹰着,彷徨着,犹豫着。。。眼看从沙发降到了板凳,又从板凳降到了地板,再不顶,估计首页都不能保住了。。。我一狠心,一咬牙,决定还是昧着良心顶楼主的帖子。作出决定后,一种深深的负罪感强烈地击中了我正直的心灵,一瞬间我泪流满面心如刀绞,意识到在以后的漫漫人生旅途中,我将因为这次不光彩的顶帖而经历长期的灵魂挣扎、精神痛苦乃至于心理煎熬。
javascript + flash

代码示例:

var flashcopier = 'flashcopier';
if (!document.getElementById(flashcopier)) {
var divholder = document.createElement('div');
divholder.id = flashcopier;
document.body.appendChild(divholder);
}
document.getElementById(flashcopier).innerHTML = '';
var divinfo = '<embed src="clipboard.swf" FlashVars="clipboard=' + text2copy + '"
width="0" height="0" type="application/x-shockwave-flash"></embed>';


document.getElementById(flashcopier).innerHTML = divinfo;}
评论:这个方案是一个最流行的方法,著名的Clipboard Copy解决方案 利用一个clipboard.swf作为桥梁,复制内容到剪贴板。原理是:创建一个隐藏的flash文件,同时给给flash的变量FlashVars 赋值“clipboard=..”,通过这个赋值flash就会把复制的内容放到剪贴板。这个方法兼容IE、Firefox、Opera、chrome、 Safari,真可谓“万能”的解决方案。浏览器Flash的安装率非常高,这几乎是一个完美的解决方案。

clipboard.swf 的下载地址:http://watch-life.googlecode.com/files/clipboard.swf。

但是,世界上有完美的事么?这个方法只支持flash 9 ,不支持最新的flash 10。因为flash10中规定了只有在swf上进行了真实的操作(比如鼠标点击)才能访问剪切板,而上述方法只是使用了一个隐藏的swf文件,通过 javascript操作flash的剪贴板,用户并没有对swf文件进行真实的操作,因此这个方法也就失效了。

那么如何解决这个“真实操作”的问题呢?可以使用一个JavaScript库:Zero Clipboard,利用这个js库可以支持利用flash 10 实现复制到剪贴板。这个方法原理是在一个透明的flash(对用户来说是不可见的)上覆盖一个dom元素比如button或div,当点击这个dom时,实际点击的是flash,从而访问flash的剪贴板。真够曲折的。:-)

具体的实现详见如下链接:

DEMO页面 :  http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/

Zero Clipboard项目主页: http://code.google.com/p/zeroclipboard/

支持浏览器:Firefox1.5  firefox2.0  firefox3.0 IE5.5 IE6.0 IE 7.0 opera 8 opera 9 chorme 1.0 chorme 2.0 safari 3


http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/
在一个页面设置一个cookie时,必须刷新或到下一个页面才可以用 $_COOKIE 得到变量的值.

原因是因为当页面第一次被浏览器访问载入时,页面中的 cookie 会被设置,将其发送存储到客户端指定的

存储位置,所以$_COOKIE没有接收到客户端发送过来的 cookie 变量的值,当刷新或到下一个页面时,客户

端会在页面程序在服务器端运行之前,发送与该地址相对应的 cookie到服务器端,所以 $_COOKIE 可以得

到的值! 阅读全文
一个php项目的config 文件的本地测试版本和服务器上的正式版本常常会不同(例如:在 config 中设置 mysql连接的用户名和密码,可是本地测试数据库 跟 服务器上的数据库很可能不同),这就给svn带来了麻烦。虽然可以通过 svn:ignore 属性来忽略这些 config 这些,可是 当config 文件的内容发生变化时,merge 会很麻烦(尤其你通过 ssh 管理服务器的话,没有gui的 diff 工具)。

我的解决办法是将配置数据设置为服务器的环境变量,在config 中使用这些环境变量,例如一个config 文件:
<?
// ... ...

// 数据库 首选参数
JCAT_DB::$sPreferredFactory                = 'JCAT_DBFactoryMySQL41' ;
JCAT_DB::$sPreferredDBServer            = 'localhost' ;
JCAT_DB::$sPreferredDBName                = SameDB' ;
JCAT_DB::$sPreferredDBUser                = 'root' ;
JCAT_DB::$sPreferredDBPassword            = '' ;      

// ... ...
?>
可以 改为:
<?
// ... ...

// 数据库 首选参数
JCAT_DB::$sPreferredFactory                = $_SERVER['DBPreferredFactory'];
JCAT_DB::$sPreferredDBServer            = $_SERVER['DBPreferredServer'];
JCAT_DB::$sPreferredDBName                = $_SERVER['DBPreferredName'];
JCAT_DB::$sPreferredDBUser                = $_SERVER['DBPreferredUser'];
JCAT_DB::$sPreferredDBPassword            = $_SERVER['DBPreferredPassword'];  

// ... ...
?>

然后在 apache 的配置文件中(或 .htaccess) 中设置:

SetEnv DBPreferredFactory 'JCAT_DBFactoryMySQL41'
SetEnv DBPreferredServer 'localhost'
SetEnv DBPreferredName 'SameDB'
SetEnv DBPreferredUser 'root'
SetEnv sPreferredDBPassword ''

(说明:SetEnv 属于 mod_env.so 所以必须先确保该模块可用)

在 php.ini 设置
safe_mode_allowed_env_vars=DB


重启 apache
在 svnsync sync 开始以后,会在目标版本库的 0版本(0 rev)上设置一个 svn:sync-lock 属性,在同步完成以后删除这个属性。只要目标版本库在存在这个属性,其它进程就无法向这个版本库执行同步工作,以避免两个进程同时相同一个版本库执行同步操作造成冲突。

但是由于网络断线或其它突发状况,svnsync sync 未能在正常结束工作以后删除 svn:sync-lock 属性,重新执行 svnsync sync 就会因为已经存在 svn:sync-lock 而遇到错误。 (使用 google code 的svn经常会遇到这样的情况)

Failed to get lock on destination repos, currently held by 'alee-desktop:99572f2d-0e43-4cb6-8a8e-2b326a85a177'
Failed to get lock on destination repos, currently held by 'alee-desktop:99572f2d-0e43-4cb6-8a8e-2b326a85a177'

只要手工清除目标版本库上 0版本的 svn:sync-lock 属性就可以了,执行:
svn propdel svn:sync-lock --revprop -r 0 XXXXXXXXXXX

XXXXXXXX 换成你的目标版本库。
在 Windows 中 通过命令 可以打开网页:
start http://www.baidu.com
或
start iexplorer http://www.baidu.com
第二种方式 是 指定用 ie 打开网页,前一种使用系统默认浏览器



在 Linux Gnome 环境下可以使用命令 :
gnome-open http://www.baidu.com

至于 Kde、Xfce、Openbox 大概都有自己的方式吧 ... ...
在 Gtk 中 用类 GtkStatusIcon 来创建一个系统托盘对象,以实现像 QQ 那样在 windows 桌面右下角显示 一个 小图标。这个类要求 Gtk 高于2.10 。在 www.kksou.com 上有关于这个类的一系列介绍: http://www.kksou.com/php-gtk2/articles/set-up-an-application-to-run-in-the-system-tray-using-GtkStatusIcon---Part-1.php 。
阅读全文
今天项目,由于性能问题,需要修改排序算法。

根据项目实际情况,数据采用了分页结构,每页30条数据,对于第一页的数据,我只需要排出top30,第二页排出top60,所以不需要进行全部排序。

这样会导致一个问题,越靠后面的页数,性能越差,但在实际应用中,这里是要进行的是排序(排行),排行榜后面的数据也无意义,所以限制的最大排序量为top4000,足够了。
阅读全文
+: 相同的数组键值以第一个为准,不会被覆盖。
PHP代码如下:

php arr.php  
Array
(
    [0] => 1
)

用array_merge后:
空数组合并也不报警告错:
可以用:$verBugsReturnArr = (array)json_decode($sucStrReturn2,True); 来代替:
$bugsReturnArr = array();这样的初始化。





php arr.php
Array
(
    [0] => 1
    [1] => 22
)


有一样的数组值,且键值一样的情况:

php arr.php
Array
(
    [0] => 1
    [1] => 1
)
于是,如果有相同,则需要去重,一般如下来使用:
$deAndOpratorArr = array_unique(array_merge($opratorArr,$de));//数组合并并去重
if(in_array($currentUser,$deAndOpratorArr))
{
       ......
}


转载:http://user.qzone.qq.com/165162897/blog/1258271003

在bbs的一个项目中,有的时候需要将一个查询的结果集,追加到另一个结果集的后面,使用了array_merge最加了数据,当数据量大的时候发现性能不是很好,像下面这个调用经常30秒没有返回。

$tplData = array_merge($tplData, $rows);

检查了下手册,说明如下。

  array_merge() 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。

如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。

如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
可见,array_merge是用来合并两个数组的,他本身是要进行健名比较判断的,对健的查找肯定要消耗时间了。
而我之前用的array_merge仅仅是做追加用,不需要判断key是否重复。故略做改动,仅仅进行追加,性能提升很多。


PHP合并数组+与array_merge的区别:
PHP中两个数组合并可以使用+或者array_merge,但之间还是有区别的,而且这些区别如果了解不清楚项目中会要命的! 主要区别是两个或者多个数组中如果出现相同键名,键名分为字符串或者数字,需要注意 1)键名为数字时,array_merge()不会覆盖掉原来的值,但+
PHP中两个数组合并可以使用+或者array_merge,但之间还是有区别的,而且这些区别如果了解不清楚项目中会要命的!
主要区别是两个或者多个数组中如果出现相同键名,键名分为字符串或者数字,需要注意
1)键名为数字时,array_merge()不会覆盖掉原来的值,但+合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉(不是覆盖)
2)键名为字符时,+仍然把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉,但array_merge()此时会覆盖掉前面相同键名的值
需要注意的是数组键形式 '数字' 等价于 数字





————————————————————————————————————————————————————————
http://php.net/manual/en/function.array-merge.php
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
————————————————————————————————————————————————————————
查看php的手册,array_merge函数的定义如下,(php有函数 可以在合并的时候保留?)合并数组的时候如何保留key?这样做就成有一个是字母就会把5和'5'保留下来:

---------- 调试PHP ----------
Array
(
    [0] => 5
    [1] => 1
    [2] => 33
    [3] => 4
    [k] => v
)

输出完成 (耗时 0 秒) - 正常终止
——————————这玩意用得小心—————————————————————————————————————
今天在使用时发现两个环境出现了不一致的情况:
$array1 = array();
$array2 = array("3337997418592025"=>"15043435569");

环境1:php:5.2.9   Linux 2.6.18
运行array_merge后结果数组为 array("3337997418592025"=>"15043435569");
环境2:php:5.2.14  linux版本不明
运行array_merge后结果数组为 array("15043435569");

结论:
2:64位系统与32位系统差异,导致“3337997418592025”分别解析为float?和正整数

来自:http://blog.sina.com.cn/s/blog_48f073080100syau.html
这两函数在PHP中用于将数据对象序列化成文本,或将文本反序列化成数据对象。

经常用于PHP的cache处理中,可以将一个数据库的查询结果,缓存到本地的硬盘中。

今天因为种种原因,需要将一个大数据集的数组(10W条数据),序列化存储,但是由于数据集比较大序列化和反序列化的速度异常的慢,大约需要10秒才能执行完毕。



分析数据发现,序列化的数据中有一些信息是冗余的,我10W条数据,其实对我有用的就是有些统计信息

比如说{s:2:"pv";i:0;s:2:"uv";i:0;s:8:"topCount";i:0;s:10:"eliteCount";i:0;s:12:"articleCount";i:0;s:10:"replyCount";i:0;s:14:"unionUserCount";i:0;s:6:"online";i:0;s:2:"id";s:2:"79";s:8:"pathInfo";a:1:{s:2:"id";s:2:"79";}},但实际存储中发现,之前为了减少读取文件的次数,我把很多无用的信息冗余的也存储到这里了,比如说一个用户的基本信息,姓名,年龄,还有版面的基本信息等(我相信很多人也经常这样做,用空间来换取时间),但这样构成的数组就太庞大了。



后来仔细研究了下,发现在这里用空间换时间是不可取的,相反速度会慢,因为我的一页只有30条数据,那些信息完全可以时时查找的,与其将其冗余存储到这10W条数据里,还不如等分完页后我在获取那些信息,组合起来,还节省了很多内存,经过这一步的改造

     程序的响应时间,提高了5s。
    序列化的文件大小 由原先的1.95M缩减到了326K



哈哈 看来数据分页所带来的好处还是蛮多的啊。

转自哥们延年的QQ空间!

MOC3061光耦电路

WEB2.0 jack 2009-11-15 07:50
过零检测双向可控硅输出光电藕合器,通态电流100ma,触发电流15ma,峰值电压600V,浪涌电流1A Vtm3v,Itm100ma ,隔离电压7.5KV,工作温度-40~85℃ 双6脚用于驱动双向晶闸管,不但具有隔离功能.而且还可用于输出通道作为开关器件使用.用于高电压及较大电流的场合.MOC306 系列可用于115/240V交流电源下的带有可控硅驱动的逻辑接口电路,如固态继电器.工业控制电路.电机.螺线管等.说明见新编实用集成电路选型手册. 第624页
请问一下,单片机能直接控制双向可控硅的门控制端吗??
可以这样控制可控硅而控制交流电吗??
那个门控制端的控制电平的范围应该多大??
比如说BT131-600,那个控制端口怎么与单片机连接而达到控制啊??

如果仅仅是为了控制交流负载,建议使用固态继电器使用方便,电路简单,单片机可直接驱动。
不可以,需要加光隔如MOC3020.电路相对复杂。


用ATmega16的ADC0引脚采集电位器的0-5V电压信号,再用采集的信号去控制内部定时器1的PWM脉宽调制占空比。
我以下几点问题我想问一下:
1、PWM脉宽调制波要设置多少频率为合适(控制市电220V/50HZ的白炽灯)
2、据我所知好像还要进行可控硅过零检测,请问过零检测的具体电路怎么弄
3、还有没有其它需要注意和重视的地方,搞过这方面的朋友帮忙说一下啊

问题补充:

我以前看到过有一个小IC可以完成这个功能,好象是摩托罗拉公司生产的,具体型号不记的了(好像是什么MOS6031),不知可不可以,本身就带过零检测和光电隔离

1. 不需要PWM调整占空比输出,只需要固定为50%占空比脉冲信号输出,也可以用定时器控制产生,频率500Hz~1KHz,
2. 过零检测信号可以用半波整流获得
3. 用ATmega16控制市电220V/50HZ的白炽灯过于奢侈,最多用ATmega8L即可。注意电源设计,一般不隔离,调试注意安全。可控硅驱动电流需要足够大,过大或者过小都会烧可控硅。

原理很简单,用可控硅的调光台灯电路到处都有,把上边电位器那一部分换成单片机的一个输出端,使用单片机输出PWM信号,即可得到不同的控制电压,以控制可控硅的导通情况。
复杂一点的需要做闭环系统,也就是通过ADC输入后,形成一个闭环的电压监测,依据此值来控制输出,使输出电压与预设的电压一致。

得用光耦,要不 就是用三极管放大一下。

我用过一种叫光电可控硅(MOC3061),可以用IO直接控制,然后用次级的可控硅控制大电流可控硅,是一种可以可靠的电路,
通过单片机io口信号控制可控硅导通角
用来实现对交流电压的调压控制
如何来实现那?
单片机是个什么样的信号,怎么样控制可控硅的导通角那?
请高手给个提示!

原理很简单,用可控硅的调光台灯电路到处都有,把上边电位器那一部分换成单片机的一个输出端,使用单片机输出PWM信号,即可得到不同的控制电压,以控制可控硅的导通情况。
复杂一点的需要做闭环系统,也就是通过ADC输入后,形成一个闭环的电压监测,依据此值来控制输出,使输出电压与预设的电压一致。

自动调光台灯电路工作原理:

电路工作原理:

电路如图152所示。交流电压经桥堆整流后,一路经R1由稳压管VD钳位后得9V的脉动直流电压供控制电路使用;另一路加到电灯H和可控硅VS两端。改变VS的导通角即可改变电灯H的亮度;H中通过的是脉动直流电流。控制电路使用脉动直流电源可保证输出的触发脉冲与可控硅VS的阳极电压同步。
点击在新窗口中浏览此图片
图152

图152中光敏电阻RG用作探头。VT1(9012)、R2、R3等组成误差放大器,VT1实质上起到一个可变电阻的作用。VT2(BT33)、C1等组成张弛振荡器,作为VS的触发电路。当探头处的照度发生变化时,如改变探头和灯泡的距离使探头处照度降低,则RG 的阻值增大,VT1的基极电位降低,其集电极电流增加,从而使C2的充电时间缩短,使触发脉冲相位前移、VS导通角增大,灯的亮度增加;反之,当探头处照度增加时,会使灯的亮度减弱。可见若探头处的照度基本保持不变,就可实现自动调光的目的。同上分析,在探头位置不变的情况下,当电源电压发生波动时,也能使灯的亮度保持不变,起到稳光作用。C1、L组成噪音滤波电路,可抑制对其他电子设备的射频干扰。

元件选择与安装调试:

整流桥堆用1A/400V的;VS用1A/400V的单向可控硅;VT2用分压比η<0.7的单结晶体管,如BT33B,其基极间电阻Rbb应尽量大一些,以控制电路的总电流。光敏电阻RG电好选用亮阻在5~10KΩ之间的,如MG4354、MG4534等。

整个装置除RG外可装在台灯的底座内。RG用两根导线引出装在带透明窗内的塑料盒内作探头用。

调试工作应在自然光线较暗的情况下进行。调试时将探头放在离灯泡40~50cm处,调节R4,亮度应明显发生变化。在探头附近放一个照度计,可凭自己的直观确定。如果R4调到最大时灯泡仍然没有变暗,则说明RG的亮阻太大,应调换或增大R4的阻值。经上述调试后,在一定范围内改变探头与灯泡的距离,灯泡的亮度应发生变化,而探头处的照度基本保持不变。
我想用MSComm,或者用其他免费控件控制串口,要实现的功能如下:
只要利用串口输出的电压控制一个继电器的开和关就行了。因为我从来没做过这方面的,请给出完整的程序和继电器的型号,可行立即加分,不够可再加。
Reader_1 »
使用串口的RTS和DTR信号可以进行简单的控制。
下面的工程的窗体包含4个按钮,一个MSComm控件


[code]Private Const COMPORT = 1
Private Sub Command1_Click()
MSComm1.RTSEnable = True
End Sub

Private Sub Command2_Click()
MSComm1.RTSEnable = False
End Sub


Private Sub Command3_Click()
MSComm1.DTREnable = True
End Sub

Private Sub Command4_Click()
MSComm1.DTREnable = False
End Sub

Private Sub Form_Load()
'
Command1.Caption = "打开继电器 1"
Command2.Caption = "关闭继电器 1"
Command3.Caption = "打开继电器 2"
Command4.Caption = "关闭继电器 2"

On Error GoTo PortErr
MSComm1.CommPort = COMPORT
MSComm1.PortOpen = True
Exit Sub

PortErr:
MsgBox "无法打开通讯口" & COMPORT, vbCritical
End
End Sub

Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub[/code]

Reader_2 »
串口输出特性:
1: 输出电压 -3- -25 伏
0: 输出电压 3-25 伏
实际在PC上面,不接负载的话
1: 输出电压 -3- -12 伏,基本在-12伏左右
0: 输出电压 3 - 12 伏 基本在12伏左右

你至少要进行简单的隔离,然后在连接继电器。
Reader_3 »
请问 kensu 要怎样隔离啊?能再说详细一点吗? Reader_4 »
串口的电流太小, 驱不动继电器,应该用外接电源。然后用串口发信息,控制外接电路。 Reader_5 »
你这种做法不太妥,只能勉强试试:
用一个发光二极管,串接一个适当电阻(或可调电位器),再接光电隔离集成块4N25的输入,
输出可至74ls244(42?记不太清了)或74ls373,最好还是要接一个功放驱动集成块去驱动继电器。 Reader_6 »
我认为瓦特说的对.
因为我做过的就是这样的.
继电器外接电源.
通过上位机想串口发指令控制它
在学校或企业,经常会使用电铃,但电铃声同消防铃声太相似.能否用电脑播放歌曲,并用串口控制开关扩音机? 某些此类的专业设备和软件非常贵,其实你可以DIY,而且并不复杂.

     原理:

      串口被软件打开后,串口DB9的4脚(DTR)会有一个10V的电压.当关闭串口后,电压即消失.

     软件开发.

       串口软件的开发可以利用API FUNCTION和Mscomm控件来开发.由于此项目非常简单,只涉及开关串口,所以使用api开发更为简单,以下是主要代码 :

打开串口:  


BOOL CTimerDlg::OpenComPort(){

hCom=CreateFile(_T("COM1"),GENERIC_READ/*|GENERIC_WRITE*/,0,NULL,OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
   NULL);
if(hCom==INVALID_HANDLE_VALUE)
   return false;
else
   return true;

}

关闭串口:
void CTimerDlg::CloseComPort(){
  
CloseHandle(hCom);


}


硬件设计:

1。选用继电器控制;
2。用双向可控硅,控制导通角;
因为在交流电时,单向可控硅反向关断,负载仅一半压降!

可控硅(SCR)基本概念:  http://www.go-gddq.com/html/2006-08/406155.htm


/***************************** 延时t毫秒 **********************************/

void delay_1ms(uint t)

{

       uint i;

       while(t--)

       {

              /* 对于11.0592M时钟,约延时1ms */

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

       }

}

/******************************* 延时10us *********************************/

void delay_10us(uchar y)               // 延时子程序10us

{

    uchar x;

    for(x=y;x>0;x--);

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**************************   温度测量模块_Strat *****************************/


uchar tplsb,tpmsb;                           // 温度值低位、高位字节

sbit DQ = P2^0;                              // DS18B20数据引脚DQ


/*********** 产生复位脉冲初始化DS18B20 ***********/

void TxReset(void)

{

       uint i;

       DQ = 0;

       /* 拉低约900us */

       i = 100;

       while (i>0)    i--;  

       DQ = 1;                                    // 产生上升沿

       i = 4;

       while (i>0)    i--;

}

/****************** 等待应答脉冲 ****************/

void RxWait(void)

{

       uint i;

       while(DQ);

       while(~DQ);                             // 检测到应答脉冲

       i = 4;

       while (i>0) i--;

}

/******** 读取数据的一位,满足读时隙要求 ********/

bit RdBit(void)

{

       uint i;

       bit b;

       DQ = 0;

       i++;

       DQ = 1;

       i++;i++;    // 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效

       b = DQ;

       i = 8;

       while(i>0) i--;

       return (b);

}

/***************** 读取数据的一个字节 *******************/

uchar RdByte(void)

{

       uchar i,j,b;

       b = 0;

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

       {

              j = RdBit();

              b = (j<<7)|(b>>1);             //测量的位的值(0或1)放在最高位,然后往右移动1位,

                                                        //把空出的最高位放接下去测的位的值(0或1)。

       }

       return(b);

}


/******** 写数据的一个字节,满足写1和写0的时隙要求 ********/

void WrByte(uchar b)

{

       uint i;

       uchar j;

       bit btmp;

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

       {

              btmp = b&0x01;

              b = b>>1;                          // 取下一位(由低位向高位)

              if (btmp)

              {

                     /* 写1 */

                     DQ = 0;

                     i++;i++;                      // 延时,使得15us以内拉高

                     DQ = 1;

                     i = 8;

                     while(i>0) i--;             // 整个写1时隙不低于60us

          }

              else

              {

                     /* 写0 */

                     DQ = 0;              

                     i = 8;

                     while(i>0) i--;             // 保持低在60us到120us之间

                     DQ = 1;

                     i++;

                     i++;

              }

       }

}

/*************** 启动温度转换 ***************/

void convert(void)

{

       TxReset();                                // 产生复位脉冲,初始化DS18B20

       RxWait();                                 // 等待DS18B20给出应答脉冲

       delay_1ms(1);                          // 延时

       WrByte(0xcc);                          // skip rom 命令

       WrByte(0x44);                         // convert T 命令

}

/*************** 读取温度值 *****************/

float temperature=0;                       // 转换之后的实际温度值

void RdTemp(void)

{

       TxReset();                                // 产生复位脉冲,初始化DS18B20

       RxWait();                                 // 等待DS18B20给出应答脉冲

       delay_1ms(1);                          // 延时

       WrByte(0xcc);                          // skip rom 命令

       WrByte(0xbe);                         // read scratchpad 命令

       tplsb = RdByte();                     // 温度值低位字节(其中低4位为二进制的“小数”部分)

       tpmsb = RdByte();                   // 高位值高位字节(其中高5位为符号位)

                                                        // 温度转换,把高低位做相应的运算转化为实际温度

       temperature=((tpmsb*256)+tplsb)*0.0625;

}


/* 读取的温度值最终存放在tplsb和tpmsb变量中。tplsb其中低4位为

二进制的“小数”部分;tpmsb其中高5位为符号位。真正通过数码管输出时,

需要进行到十进制有符号实数(包括小数部分)的转换。 */

/************************   温度测量模块_End *******************************/
分页: 225/338 第一页 上页 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 下页 最后页 [ 显示模式: 摘要 | 列表 ]