⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ow_comm.#2

📁 硬件平台:C8051F314 包括键盘扫描程序
💻 #2
字号:
//------------------------------------------------------------------------------------
//
// FILE NAME      : ow_comm.c
// TARGET DEVICE  : C8051F314
// CREATED ON     : 07/14/06
// CREATED BY     : Jzp
//
// Revision 1.0  

// 功能描述:1-wire总线通信处理程序
//    DQ -> P3.1
// 说明:本机中只支持两个从器件
//------------------------------------------------------------------------------------

#include <C8051F310.H>
#include "..\\inc\\define.h" 
#define OW_COMM_GLOBALS
#include "..\\inc\\ow_comm.h" 

//#define OW_DEBUG
//sbit DQ = P3^1;

// definitions
#define FALSE 0
#define TRUE  1
#define DS2762_FC 0X30
#define DS2415_FC 0Xa4

// method declarations
UCHAR  ow_first();
UCHAR  ow_next();
//UCHAR  OWSearch();
UCHAR  docrc8(UCHAR value);
void   delay_us(UINT us);
//void find_ow_dev(void);

// global search state
UCHAR xdata ROM_NO[8];
UCHAR xdata LastDiscrepancy;
UCHAR xdata LastFamilyDiscrepancy;
UCHAR xdata LastDeviceFlag;
UCHAR xdata crc8;
//UCHAR xdata DevAddr[2][8];     // 存储从机地址

// global variable

//SCHAR xdata BatVol[2];   // 精度4.88mV
//SCHAR xdata BatCur[2];   // 精度15.625uV
//UCHAR xdata RtcClk[4];   // 精度1s

// CRC TABLE
UCHAR code dscrc_table[] = {
        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};



// 考虑到可位寻址资源有限,不要使用bit变量

/************************************************************
-----延时程序-----
功能: 延时us微妙
参数: us 
说明: SYSCLK = 24.5MHZ,所以它的机器周期约为0.04us
//void delay_us(UINT us)
*************************************************************/

void delay_us(UINT us)
{
  UINT i;
  UCHAR j;
  for(i = 0; i < us; i++)
  {
    for(j = 0; j < 2; j++);    // 约1us<input type="text" <input type="text" >>
  }
}

/************************************************************
-----1-wire总线复位程序-----
说明: 每次启动1-wire通信时,主机都要先复位总线
//UCHAR ow_reset(void)
*************************************************************/

UCHAR ow_reset(void)
{
//  UINT i;
//  UCHAR j;
  bit ack_flag = 1;
  
  DQ = 0;
  delay_us(480);       // 总线拉低480us
  DQ = 1;
  delay_us(40);         // 总线释放50us    15us<t<60us
  
  ack_flag = DQ;       // 读取从设备应答脉冲
  delay_us(300);       // NOTICE: 必须等待完成一个周期,否则会出错
  if(ack_flag)
    return 0;          // 无响应,表示总线上无设备
  else
    return 1;          // 有响应,表示总线上有设备
}

/************************************************************
-----1-wire总线写入1bit位程序-----
说明: 
//void ow_bit_wr(UCHAR level)
*************************************************************/

void ow_bit_wr(UCHAR level)
{
  DQ = 0;
  delay_us(15);      // 拉低总线15us
  if(level)
    DQ = 1;
  else
    DQ = 0;
  delay_us(40);      // 保持45us
  DQ = 1;            
  delay_us(2);       // 释放总线至少1us
}

/************************************************************
-----1-wire总线读入1bit位程序-----
说明: 
//UCHAR ow_bit_rd(void)
*************************************************************/

UCHAR ow_bit_rd(void)
{
  UCHAR retbit;

  DQ = 0;
  delay_us(1);      // 拉低总线1us

  DQ = 1;            
  delay_us(15);     // 释放总线保持15us

  retbit = DQ;      // 读取总线数据
  delay_us(45);     // NOTICE:等待一个读时隙完成,否则会出错
  DQ = 1;            
  delay_us(1);      // 释放总线至少1us
  return retbit;
}

/************************************************************
-----1-wire总线写入1字节程序-----
说明: 字节写入顺序为低位在前
//void ow_byte_wr(UCHAR wdata)
*************************************************************/

void ow_byte_wr(UCHAR wdata)
{
  UCHAR i;
  UCHAR bitval = 0;
  
  for(i = 0; i < 8; i++)
  {
    if((wdata >> i)&0x01)
      bitval = 1;
    else
      bitval = 0;
    ow_bit_wr(bitval); 
  }
}

/************************************************************
-----1-wire总线读出1字节程序-----
说明: 字节读出顺序为低位在前
//UCHAR ow_byte_rd()
*************************************************************/

UCHAR ow_byte_rd(void)
{
  UCHAR i;
  UCHAR bitval = 0;
  UCHAR rdata = 0x00;
  
  for(i = 0; i < 8; i++)
  {
//    shift_val = 0x80;
    bitval = ow_bit_rd();
    if(bitval == 1)
      rdata = rdata|(0x01<<i);
  }
  return rdata;
}


/************************************************************
-----1-wire总线读出1字节程序-----
说明: 字节读出顺序为低位在前
//UCHAR ow_byte_rd()
*************************************************************/

ow_comm(void)
{
  if(ow_reset() == 1)  // 有1-wire器件存在
  {
    
  }
}

/************************************************************
-----1-wire总线主机获取总线上所有器件地址的程序-----
说明: 字节读出顺序为低位在前
//UCHAR ow_seach_dev()
*************************************************************/


//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire bus
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : no device present
//
UCHAR ow_first()
{
   // reset the search state
   LastDiscrepancy = 0;
   LastDeviceFlag = FALSE;
   LastFamilyDiscrepancy = 0;

   return OWSearch();
}

//--------------------------------------------------------------------------
// Find the 'next' devices on the 1-Wire bus
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : device not found, end of search
//
UCHAR ow_next()
{
   // leave the search state alone
   return OWSearch();
}

//--------------------------------------------------------------------------
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
// search state.
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : device not found, end of search
//
UCHAR OWSearch()
{
   UCHAR id_bit_number;
   UCHAR last_zero, rom_byte_number, search_result;
   UCHAR id_bit, cmp_id_bit;
   UCHAR rom_byte_mask, search_direction;

   // initialize for search
   id_bit_number = 1;
   last_zero = 0;
   rom_byte_number = 0;
   rom_byte_mask = 1;
   search_result = 0;
   crc8 = 0;

   // if the last call was not the last one
   if (!LastDeviceFlag)
   {
      // 1-Wire reset
      if (!ow_reset())
      {
         // reset the search
         LastDiscrepancy = 0;
         LastDeviceFlag = FALSE;
         LastFamilyDiscrepancy = 0;
         return FALSE;
      }

      // issue the search command 
      ow_byte_wr(0xF0);  

      // loop to do the search
      do
      {
         // read a UCHAR and its complement
         id_bit = ow_bit_rd();
         cmp_id_bit = ow_bit_rd();

         // check for no devices on 1-wire
         if ((id_bit == 1) && (cmp_id_bit == 1))
            break;
         else
         {
            // all devices coupled have 0 or 1
            if (id_bit != cmp_id_bit)
               search_direction = id_bit;  // UCHAR write value for search
            else
            {
               // if this discrepancy if before the Last Discrepancy
               // on a previous next then pick the same as last time
               if (id_bit_number < LastDiscrepancy)
                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
               else
                  // if equal to last pick 1, if not then pick 0
                  search_direction = (id_bit_number == LastDiscrepancy);

               // if 0 was picked then record its position in LastZero
               if (search_direction == 0)
               {
                  last_zero = id_bit_number;

                  // check for Last discrepancy in family
                  if (last_zero < 9)
                     LastFamilyDiscrepancy = last_zero;
               }
            }

            // set or clear the UCHAR in the ROM byte rom_byte_number
            // with mask rom_byte_mask
            if (search_direction == 1)
              ROM_NO[rom_byte_number] |= rom_byte_mask;
            else
              ROM_NO[rom_byte_number] &= ~rom_byte_mask;

            // serial number search direction write UCHAR
            ow_bit_wr(search_direction);

            // increment the byte counter id_bit_number
            // and shift the mask rom_byte_mask
            id_bit_number++;
            rom_byte_mask <<= 1;

            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
            if (rom_byte_mask == 0)
            {
                docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC
                rom_byte_number++;
                rom_byte_mask = 1;
            }
         }
      }
      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7

      // if the search was successful then
      if (!((id_bit_number < 65) || (crc8 != 0)))
      {
         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
         LastDiscrepancy = last_zero;

         // check for last device
         if (LastDiscrepancy == 0)
            LastDeviceFlag = TRUE;
         
         search_result = TRUE;
      }
   }

   // if no device found then reset counters so next 'search' will be like a first
   if (!search_result || !ROM_NO[0])
   {
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      search_result = FALSE;
   }

   return search_result;
}



//--------------------------------------------------------------------------
// Calculate the CRC8 of the byte value provided with the current 
// global 'crc8' value. 
// Returns current global crc8 value
//
UCHAR docrc8(UCHAR value)
{
   // See Application Note 27
   
   // TEST BUILD
   crc8 = dscrc_table[crc8 ^ value];
   return crc8;
}

/************************************************************
-----1-wire总线主机获取总线上所有器件地址的程序-----
说明: 根据搜索算法查找所有器件的64位地址并存储于指定位置
       并根据器件地址的家族号判断,总线上为何种设备
出口参数:
	     如果存在DS2762,HasDs2762 = 1
	     如果存在DS2415,HasDs2415 = 1
//void find_ow_dev(void)
*************************************************************/

UCHAR find_ow_dev(void)
{
   UCHAR rslt,j;//,cnt;
   SCHAR i;     // i一定要为有符号数,否则会出错
   for(j = 0; j < 2; j++)
   {
     if(j == 0) 
       rslt = ow_first();
     else
       rslt = ow_next();
     if(rslt == 1)          // 
     {
       for (i = 7; i >= 0; i--)
         g_romaddr[j].romaddr[i] = ROM_NO[i];    // 存储64bit地址
       if(ROM_NO[0] == DS2762_FC)                // 判断是何器件
         HasDs2762 = 1;
       else if(ROM_NO[0] == DS2415_FC)
         HasDs2415 = 1;
     }
     else
       break;
   }
   return j;   // 返回数量
}

/************************************************************
-----1-wire总线主机查询DS2762寄存器的程序-----
说明: 写读取命令69H,0CH,读取电池输出电压
       写读取命令69H,0EH,读取电池电流
//void read_ds2762(void)
*************************************************************/

void read_ds2762(void)
{
  UCHAR i;
  ow_reset();                    // 一个完整的总线动作之前都要复位总线
  ow_byte_wr(0x55);              // 发送NET ADDRESS COMMAND(MATCHE NETWORK ADDRESS)
  for(i = 0; i < 8; i++)         // 发送前面搜索到的地址
  {
    if(g_romaddr[0].st_romaddr.familycode == DS2415_FC)
      ow_byte_wr(g_romaddr[0].romaddr[i]);
    else
      ow_byte_wr(g_romaddr[1].romaddr[i]);    
  }
  ow_byte_wr(0x69);
  ow_byte_wr(0x00);
  for(i = 0; i < 9; i++)
  {
    BatVol[i] = ow_byte_rd();
  }
//  for(i =0; i < 2; i++)
//  {
//    BatCur[i] = ow_byte_rd();
//  }
  ow_reset();                    // 读完后要复位总线
}

/************************************************************
-----1-wire总线主机查询DS2415寄存器的程序-----
说明: 写读取命令66H,读取RTC CLOCK
       写设置命令69H,0EH,读取电池电流
//void read_ds2415(void)
*************************************************************/

void read_ds2415(void)
{
  UCHAR i;
  ow_reset();                    // 一个完整的总线动作之前都要复位总线
  ow_byte_wr(0x55);              // 发送NET ADDRESS COMMAND(MATCHE NETWORK ADDRESS)
  for(i = 0; i <8; i++)          // 发送前面搜索到的地址
  {
    if(g_romaddr[0].st_romaddr.familycode == DS2415_FC)
      ow_byte_wr(g_romaddr[0].romaddr[i]);
    else
      ow_byte_wr(g_romaddr[1].romaddr[i]);    
  }
  ow_byte_wr(0x66);
  for(i = 0; i < 4; i++)         // 接收4字节clock
  {
    RtcClk[i] = ow_byte_rd();
  }
  ow_reset();                    // 读完后一定要复位,否则会一直读
}

/************************************************************
-----ONE WIRE 通信任务-----
功能: 主程序调用该任务,与ow器件通信
参数: 行列号(ex。0x31 表示第3行第1列) 
//说明: 
//void task_owcomm(void)
*************************************************************/

void task_owcomm(void)
{
  if(gOwdevNum != 0)
  {
  	if(HasDs2762 == 1)
  	{
  	  read_ds2762();
  	}
  	if(HasDs2415 == 1)
  	{
  	  read_ds2415();
  	}
  }	
}
// debug function
//#ifdef OW_DEBUG
void ow_test(void)
{
  UCHAR i;
  if(ow_reset())
  {
    ow_byte_wr(0x33);    // issue READ ROM command
    DQ = 1;
    delay_us(3);
    for(i = 0; i < 8; i++)
    {
      g_testaddr.romaddr[i] = ow_byte_rd();
    }
  }
}
//#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -