打印

1-Wire/HDQ16等单总线终被菜农倒塌,发帖自贺~~~

[复制链接]
12778|65
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hotpower|  楼主 | 2008-2-28 01:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1-Wire/HDQ16等单总线终于脱离了IO软件模拟,能被任何的MCU/ARM/DSP的
通用异步串口硬件控制收发,在串口中断模式或DMA模式下实现"零耗时"~~~

故发帖自贺~~~

哈哈~~~网上的ds18b20/ds1990/bq2060/bq...等软件模拟的例程都被倒塌~~~

累了,脑浆要休眠~~~改日写篇"作文"~~~

哈哈~~~农忙第一天就有收获~~~今年好收成~~~

HotPower@126.com 2008.2.28 1.08 于雁塔菜地
相关链接:https://bbs.21ic.com/club/bbs/list.asp?boardid=57&page=1&t=2868810

相关帖子

沙发
HWM| | 2008-2-28 08:24 | 只看该作者

坐沙发,等待下文。

使用特权

评论回复
板凳
lpf336| | 2008-2-28 08:32 | 只看该作者

板凳

使用特权

评论回复
地板
phoenixmy| | 2008-2-28 08:37 | 只看该作者

呵呵



地下室

使用特权

评论回复
5
wjhhhh| | 2008-2-28 09:15 | 只看该作者

几个月了,看到了“下文”

但愿不出三二十天看到**甚至看到代码。
  

使用特权

评论回复
6
hotpower|  楼主 | 2008-2-28 09:38 | 只看该作者

哈哈~~~让人们从繁重的体力劳动(模拟IO)中解放出来~~~

wjhhhh 发表于 2008-2-28 09:15 侃单片机 ←返回版面    

5楼: 几个月了,看到了“下文” 

但愿不出三二十天看到**甚至看到代码。
 
 
倒塌了~~~菜地的蔬菜品种太多,时间不够用呀~~~

有时真想右脑用左手,左脑用右脚一起忙活呀~~~

使用特权

评论回复
7
dai_weis| | 2008-2-28 10:34 | 只看该作者

好哇,等待下文

使用特权

评论回复
8
古道热肠| | 2008-2-28 10:49 | 只看该作者

哈哈,期待中

用UART与单总线器件通讯,俺舍不得,用IO模拟最划算,UART一般都用于下载,通信,监控,仿真。

使用特权

评论回复
9
gyt| | 2008-2-28 14:18 | 只看该作者

恭喜恭喜

使用特权

评论回复
10
hotpower|  楼主 | 2008-2-28 15:54 | 只看该作者

先开个批斗会~~~谁来先找出错误~~~

使用特权

评论回复
11
lpf336| | 2008-2-28 16:24 | 只看该作者

打不开

使用特权

评论回复
12
hotpover| | 2008-2-28 18:44 | 只看该作者

~~

使用特权

评论回复
13
keer_zu| | 2008-2-28 19:45 | 只看该作者

期待大叔最终结果共享


dddddddd

使用特权

评论回复
14
hotpower|  楼主 | 2008-2-28 21:34 | 只看该作者

可以打开呀~~~谁给找找错误~~~



使用特权

评论回复
15
5_0_5| | 2008-2-28 21:40 | 只看该作者

大叔在线,帮忙定

使用特权

评论回复
16
hotpower|  楼主 | 2008-2-28 21:42 | 只看该作者

通用接口电路

使用特权

评论回复
17
hotpower|  楼主 | 2008-2-28 22:39 | 只看该作者

回复古道热肠同志:若是采用ARM等就不愁UART不够用了~~~

现在还蹲守MCU阵地是时代的倒退~~~实现硬件单总线控制器肯定爽歪歪~~~

使用特权

评论回复
18
hotpower|  楼主 | 2008-2-28 23:04 | 只看该作者

先转载一个例程,以后可以比较论证

温度传感器18B20驱动程序(C语言)

/************************************************************
*18B20驱动程序,DQ为数据口,接于P2.1
*11.0592M晶振,上拉4.7k电阻
*Author:fyb
*2005-3-25 11:23,OK!
*************************************************************/
#i nclude
#i nclude

#define uchar unsigned char
#define uint unsigned int

sbit dq = P1^7;
bit flag;
uint Temperature;
uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
uchar id_buff[8];
uchar *p;
uchar crc_data;
uchar code CrcTable [256]={
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
//
/************************************************************
*Function:延时处理
*parameter:
*Return:
*Modify:
*************************************************************/
void TempDelay (uchar us)
{
   while(us--);
}
/************************************************************
*Function:18B20初始化
*parameter:
*Return:
*Modify:
*************************************************************/
void Init18b20 (void)
{
dq=1;
_nop_();
dq=0;
TempDelay(86);   //delay 530 uS//80
_nop_();
dq=1;
TempDelay(14);   //delay 100 uS//14
_nop_();
_nop_();
_nop_();

if(dq==0)
   flag = 1;   //detect 1820 success!
else
   flag = 0;    //detect 1820 fail!
TempDelay(20);       //20
_nop_();
_nop_();
dq = 1;
}
/************************************************************
*Function:向18B20写入一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
void WriteByte (uchar wr) //单字节写入
{
uchar i;
for (i=0;i<8;i++)
{
   dq = 0;
   _nop_();
   dq=wr&0x01;
   TempDelay(5);   //delay 45 uS //5
   _nop_();
   _nop_();
   dq=1;
   wr >>= 1;
}
}
/************************************************************
*Function:读18B20的一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
uchar ReadByte (void)     //读取单字节
{
uchar i,u=0;
for(i=0;i<8;i++)
{
   dq = 0;
   u >>= 1;
   dq = 1;
   if(dq==1)
   u |= 0x80;
   TempDelay (4);
   _nop_();
}
return(u);
}
/************************************************************
*Function:读18B20
*parameter:
*Return:
*Modify:
*************************************************************/
void read_bytes (uchar j)
{
uchar i;
for(i=0;i {
    *p = ReadByte();
    p++;
}
}
/************************************************************
*Function:CRC校验
*parameter:
*Return:
*Modify:
*************************************************************/
uchar CRC (uchar j)
{
   uchar i,crc_data=0;
for(i=0;i    crc_data = CrcTable[crc_data^temp_buff]];
    return (crc_data);
}
/************************************************************
*Function:读取温度
*parameter:
*Return:
*Modify:
*************************************************************/
void GemTemp (void)
{
   read_bytes (9);
   if (CRC(9)==0) //校验正确
   {
     Temperature = temp_buff[1]*0x100 + temp_buff[0];
//     Temperature *= 0.625;
   Temperature /= 16;
   TempDelay(1);
    }
}
/************************************************************
*Function:内部配置
*parameter:
*Return:
*Modify:
*************************************************************/
void Config18b20 (void) //重新配置报警限定值和分辨率
{
     Init18b20();
     WriteByte(0xcc); //skip rom
     WriteByte(0x4e); //write scratchpad
     WriteByte(0x19); //上限
     WriteByte(0x1a); //下限
     WriteByte(0x7f);     //set 11 bit (0.125)
     Init18b20();
     WriteByte(0xcc); //skip rom
     WriteByte(0x48); //保存设定值
     Init18b20();
     WriteByte(0xcc); //skip rom
     WriteByte(0xb8); //回调设定值
}
/************************************************************
*Function:读18B20ID
*parameter:
*Return:
*Modify:
*************************************************************/
void ReadID (void)//读取器件 id
{
Init18b20();
WriteByte(0x33); //read rom
read_bytes(8);
}
/************************************************************
*Function:18B20ID全处理
*parameter:
*Return:
*Modify:
*************************************************************/
void TemperatuerResult(void)
{
p = id_buff;
ReadID();
Config18b20();
Init18b20 ();
WriteByte(0xcc);   //skip rom
WriteByte(0x44);   //Temperature convert
Init18b20 ();
WriteByte(0xcc);   //skip rom
WriteByte(0xbe);   //read Temperature
p = temp_buff;
GemTemp();
}

相关链接:http://blog.edu.cn/user4/gzlce/archives/2008/2056035.shtml

使用特权

评论回复
19
hotpower|  楼主 | 2008-2-28 23:09 | 只看该作者

再来一个转载(为一主多从做准备)

四个DS1820温度读取C源程序
// 以下是四个DS1820温度读取程序
//使用时先调用"rom()"子程序读出每个器件的序列号
//再将各个序列号填入SN数组中才能读出各个温度

#i nclude <reg52.h>
#define uchar unsigned char 

sbit TMDAT = P0^1; //根据实实际情况设定
uchar TMP[4];  //读取后的4个温度值,将其除以2即可得出实际温度;
uchar SN[4][8];  //4个器件的序列号,先读出单个序列号后填上才可以读取温度
uchar f[4];  //结果是否为负温,“0”为正温,“1”为负温。  

////////////////////////////////////////延时部分//////////////////////////
void dmsec (unsigned int count)       //
{         //
 unsigned int i;              // 
 while (count)       //
 {        //
  i = 115;      //
  while (i>0) i--;     //
  count--;      //
    }         //
}         //
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////////// 发送复位//////////////////////////
void tmreset (void)       //
{                          //
 unsigned int i;       //
 TMDAT = 0;       //
 i = 103;       //
 while (i>0) i--;          // 延时 900 uS(11.0592Mhz时) //
 TMDAT = 1;       //
 i = 4;        //
 while (i>0) i--;      //
}         //
//////////////////////////////////////////////////////////////////////////

//判断DS1820是否存在的子程序。最好不要用,因为当器件不存在时将会进入死循环

////////////////////////////////////// 等待存在脉冲///////////////////////
void tmpre (void)   //判断器件是否存在  //
{                            //
 unsigned int i;       //
 while (TMDAT);       //
 while (~TMDAT);       //
 i = 4; while (i>0) i--;      //
}         //
//////////////////////////////////////////////////////////////////////////

///////////////////////////////////// 读一位//////////////////////////////
bit tmrbit (void)       //
{                          //  
 unsigned int i;       //
 bit dat;       //
 TMDAT = 0; i++;       //
 TMDAT = 1; i++; i++;  //微量延时   //
 dat = TMDAT;       //
 i = 8; while (i>0) i--;  // 延时    //
 return (dat);       //
}         //
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////// 读一个字节///////////////////////
unsigned char tmrbyte (void)        //
{                 //
 unsigned char i,j,dat;      //
 dat = 0;       //
 for (i=1;i<=8;i++)      //
 {        //
  j = tmrbit ();      //
  dat = (j << 7) | (dat >> 1);    //
 }        //
 return (dat);       //
}         //
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////////// 写一个字节////////////////////////
void tmwbyte (unsigned char dat)     //
{                       //
 unsigned int i;       //
 unsigned char j;      //
 bit testb;       //
 for (j=1;j<=8;j++)      //
 {        //
  testb = dat & 0x01;     //
  dat = dat >> 1;      //
  if (testb)      //
  {       //
   TMDAT = 0;                           // 写0  //
   i++; i++;                              //
   TMDAT = 1;     //
   i = 8; while (i>0) i--;                //
  }       //
  else       //
  {       //
   TMDAT = 0;                           // 写0  //
   i = 8; while (i>0) i--;                //
   TMDAT = 1;     //
   i++; i++;                              //
  }       //
 }        //
}         //
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////发送ds1820 开始转换//////////////////////
void tmstart (void)       //
{                          //
 tmreset ();  //复位     //
 //tmpre ();  //等待存在脉冲    //
 dmsec (1);  //延时     //
 tmwbyte (0xcc);  //跳过序列号命令,对所有器件有效  //
 tmwbyte (0x44);  //发转换命令 44H,   //
}         //
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////读取温度////////////////////////////////
void tmrtemp ()        //
{                          //
 uchar i,j;       //
 uchar a,b;       //
 for(j=0;j<4;j++)      //
 {        //
  tmreset();  //复位    //
  dmsec(1);  //延时    //
  tmwbyte(0x55);  //发送ROM匹配命令  //
  for(i=0;i<8;i++)     //
  {       //
   tmwbyte(SN[j]); //发送64位序列号 //
  }       //
  tmwbyte (0xbe);  //发送读取命令    //
  a = tmrbyte ();  //连续读取两位温度  //
  b = tmrbyte ();       //
  f[j]=b;   //若b为1则为负温  //
  if(f[j])      //
  {       //
   TMP[j]=~a+1; //如果为负温则去除其补码 //
  }       //
  else       //
  {       //
   TMP[j]=a;     //
  }       //
 }        //
}         //
//////////////////////////////////////////////////////////////////////////


//以下是读取器件序列号的子程序,需要读取序列时可在程序中调用;
//调用时确保总线中只有一只器件,若有多个器件时则读取出来的号码无效;
//将读取出来的序列号填到前面的数组中即可使用;
//平时可以将此子程序删除以节约空间。
  
//////////////////////////读取器件序列号子程序////////////////////////////
void rom()         //
{         //
 //以下是定义8个序列号变量     //
 uchar sn1;       //
 uchar sn2;       //
 uchar sn3;       //
 uchar sn4;       //
 uchar sn5;       //
 uchar sn6;       //
 uchar sn7;       //
 uchar sn8;       //
         //
 tmreset ();  //复位     //
 dmsec (1);  //延时     //
 tmwbyte(0x33);  //发送读序列号子程序   //
 sn1=tmrbyte();  //读取第一个序列号,应为16H;  //
 sn2=tmrbyte();  //读取第二个序列号,应为10H;  //
 sn3=tmrbyte();       //
 sn4=tmrbyte();       //
 sn5=tmrbyte();       //
 sn6=tmrbyte();       //
 sn7=tmrbyte();       //
 sn8=tmrbyte();       //
}         //
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
main()         //
{         //
 do{      //
  rom(); //调用读序列号子程序   //
  //tmstart();      //
  dmsec(100); //如果是不断地读取的话可以不延时 //
  //tmrtemp(); //读取温度,执行完毕温度将存于TMP[]数组中//
 }while(1);       //
}         //
//////////////////////////////////////////////////////////////////////////


抱歉~~~去除后面的广告部分
相关链接:http://blog.edu.cn/user4/gzlce/archives/2007/1974624.shtml

使用特权

评论回复
20
hotpower|  楼主 | 2008-2-28 23:19 | 只看该作者

俺干什么都是"读写一体化"---HDQ16单总线测试代码

LPC_INT16U  HDQReadWriteData (LPC_INT8U command)
{
LPC_INT8U valuel;
LPC_INT8U valueh;
LPC_INT16U value;
  HDQStart();//190us
  HDQReadWriteByte(command);
  valuel = HDQReadWriteByte(0xff);
  valueh = HDQReadWriteByte(0xff);
  value = (valueh << 8) | valuel;
  return value;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1460

主题

21619

帖子

506

粉丝