1
OneWire_Functions.cpp
- Committer:
- ChesterLin
- Date:
- 2017-11-27
- Revision:
- 0:3e574710804f
File content as of revision 0:3e574710804f:
#include "OneWire_Functions.h" Serial pc2(USBTX,USBRX); OneWire::OneWire (PinName wire): _pin(wire) { //default alram temperture sca[2]=0x50; //+80 'C sca[1]=0xec; //-25 'C //default resolution sca[0]=Twebitresolution; reso = Twebitresolution; } //initialization 1-wire devices int OneWire::init() { int result; //define a value for read presence pulse _pin.output(); //set pin as output _pin = 0; //pull the bus low wait_us(480); //minimum rest pulse is 480 µs _pin.input();//set pin as input, bus pull up by pullup resistor wait_us(70); //wait for slave response result = _pin.read(); //read presence pulse wait_us(410); return result; //return the presence pulse. 0->TURE. 1->FALSE } //write a bite void OneWire::write_bit(uint8_t data) { data = data & 0x01; //only transmit LSB if (data) { //Write '1' wait_us(1); _pin.output(); //set pin as output _pin = 0; //pull the bus low wait_us(10); //write '1' need pull up within 15µs _pin.input();//set pin as input, bus pull up by pullup resistor wait_us(60); //rest duration time + recovery time } else { //Write '0' wait_us(1); _pin.output();//set pin as output _pin = 0; //pull the bus low wait_us(60); //rest duration time _pin.input();//set pin as input, bus pull up by pullup resistor wait_us(10); //recovery time } } //read a bite int OneWire::read_bit() { int result; //define a value for read result wait_us(1); _pin.output(); //set pin as output _pin = 0; //pull the bus low wait_us(5); _pin.input(); wait_us(10); result = _pin; //sample the bus wait_us(65); //rest duration time + recovery time return result; } //write a byte void OneWire::write_byte(uint8_t data) { int loop; for(loop = 0; loop < 8; loop++) { write_bit(data & 0x01); data = (data >> 1); } } //read a byte int OneWire::read_byte() { int result,loop; for(loop = 0; loop < 8; loop++) { result = (result >> 1); if (read_bit()) { result |= 0x80; } } return result; } //get tempreture from a device char * OneWire::init_Match_Get_Temp(char addr[8]) { int loop,i=0; char sc[2]; init(); write_byte(0x55); for (loop = 0; loop < 8; loop++) { write_byte(addr[i]); i++; } write_byte(0xbe); i=0; for (loop = 0; loop < 2; loop++) { sc[i]=read_byte(); i++; } return sc; } //get scratchpad from a device //char* OneWire::init_Match_Read_Scratchpad(char addr[8]) //{ //int loop, i = 0; //char sc[9]; //init(); //write_byte(0x55); // for(loop = 0; loop<8; loop++) { //write_byte(addr[i]); //i++; //} //i=0; //write_byte(0xbe); //for(loop = 0; loop < 9; loop++) { //sc[i] = read_byte(); //i++; //} //return sc; //} //write Th, Tl and configuration register to a device void OneWire::init_Match_Write_Scratchpad(char addr[8],char Scratchpad[3]) { int loop,i=0; init(); write_byte(0x55); for(loop = 0; loop<8; loop++) { write_byte(addr[i]); i++; } write_byte(0x4e); write_byte(Scratchpad[2]);//write Th write_byte(Scratchpad[1]);//write Tl write_byte(Scratchpad[0]);//write resolution } //all device on the bus convert t int OneWire::Skip_Convert_T() { int relt = init(); if (!relt) { write_byte(0xcc); write_byte(0x44); wait_us(1000); return TRUE; } else { return FALSE; } } //search any alarm on bus, if ture, send email int OneWire::Read_alarm_Email() { Skip_Convert_T(); //all device convert temperature int rslt = OWSearch_alarm(); //find first device if (rslt) { //find one device have alarm. send email pc2.printf("Sending Email...\n\r"); //get time first ntp.setTime("pool.ntp.org"); time_t ctTime = time(NULL); //send email smtp.setFromAddress(FROM_ADDRESS); smtp.setToAddress(TO_ADDRESS); char msg[]= "One of 1-wire device is burning."; smtp.setMessage(SUBJECT,msg); smtp.sendmail(SERVER, USER, PWD, DOMAIN,PORT,SMTP_AUTH_PLAIN); return TRUE; } return FALSE; } //read all devices temperature on the bus int OneWire::Read_Temp_On_bus() { char temp[2]; int i=OneWireTempReg-1; int rslt = Skip_Convert_T(); //all device convert temperature if (rslt) { OWFirst();//find first device strcpy(temp,init_Match_Get_Temp(ROM_NO)); //read temp from that sensor alltemp[i]=temp[1]; alltemp[i-1]=temp[0]; rslt = OWNext(); //strat search next 1-wire device while(rslt) { i=i-2; strcpy(temp, init_Match_Get_Temp( ROM_NO)); //read temp from that sensor alltemp[i]=temp[1]; alltemp[i-1]=temp[0]; rslt = OWNext(); //strat search next 1-wire device } return TRUE; } else { return FALSE; } } //set resolution to all 1-wire device void OneWire::Change_Res() { int rslt = OWFirst(); //search first device on bus if (rslt) { //found first device init_Match_Write_Scratchpad(ROM_NO, sca); //change resolution or alarm temperature rslt = OWNext(); //find next device while(rslt) { //found next device init_Match_Write_Scratchpad(ROM_NO, sca); //change resolution or alarm temperature rslt = OWNext(); //find next device } } } //read the address when there is only one slave on the bus //char* OneWire::init_Read_ROM() //{ //char addr[8]; //int loop,i; //i=0; //init(); //write_byte(0x33); //for ( loop = 0; loop < 8; loop++) { //addr[i] = read_byte(); //i++; //} //return addr; //} //read temperature when there is only one slave on the bus //char* OneWire::init_Skip_Get_Temp() //{ //int loop, i; //char temp[2]; //i = 0; //init(); //write_byte(0xcc); //write_byte(0x44); //wait_us(1000); //init(); //write_byte(0xcc); //write_byte(0xbe); //for(loop = 0; loop < 2;loop++){ //temp[i] = read_byte(); //i++; //} //return temp; //} //int OneWire::init_Skip_Read_Scratchpad() //{ //} //void OneWire::init_Skip_Write_Scratchpad(char Scratchpad[7]) //{ //} // 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 // int OneWire::OWSearch() { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; unsigned char 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 (init()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // issue the search command write_byte(0xF0); // loop to do the search do { // read a bit and its complement id_bit = read_bit(); cmp_id_bit = read_bit(); // 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; // bit 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 bit 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 bit write_bit(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; } // Perform the 1-Wire Search alarm 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 // int OneWire::OWSearch_alarm() { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; unsigned char 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 (init()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // issue the search alarm command write_byte(0xEC); // loop to do the search do { // read a bit and its complement id_bit = read_bit(); cmp_id_bit = read_bit(); // 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; // bit 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 bit 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 bit write_bit(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; } //-------------------------------------------------------------------------- // Verify the device with the ROM number in ROM_NO buffer is present. // Return TRUE : device verified present // FALSE : device not present // int OneWire::OWVerify() { unsigned char rom_backup[8]; int i,rslt,ld_backup,ldf_backup,lfd_backup; // keep a backup copy of the current state for (i = 0; i < 8; i++) rom_backup[i] = ROM_NO[i]; ld_backup = LastDiscrepancy; ldf_backup = LastDeviceFlag; lfd_backup = LastFamilyDiscrepancy; // set search to find the same device LastDiscrepancy = 64; LastDeviceFlag = FALSE; if (OWSearch()) { // check if same device found rslt = TRUE; for (i = 0; i < 8; i++) { if (rom_backup[i] != ROM_NO[i]) { rslt = FALSE; break; } } } else rslt = FALSE; // restore the search state for (i = 0; i < 8; i++) ROM_NO[i] = rom_backup[i]; LastDiscrepancy = ld_backup; LastDeviceFlag = ldf_backup; LastFamilyDiscrepancy = lfd_backup; // return the result of the verify return rslt; } // Setup the search to find the device type 'family_code' on the next call // to OWNext() if it is present. // void OneWire::OWTargetSetup(unsigned char family_code) { int i; // set the search state to find SearchFamily type devices ROM_NO[0] = family_code; for (i = 1; i < 8; i++) ROM_NO[i] = 0; LastDiscrepancy = 64; LastFamilyDiscrepancy = 0; LastDeviceFlag = FALSE; } // Setup the search to skip the current device type on the next call // to OWNext(). // void OneWire::OWFamilySkipSetup() { // set the Last discrepancy to last family discrepancy LastDiscrepancy = LastFamilyDiscrepancy; LastFamilyDiscrepancy = 0; // check for end of list if (LastDiscrepancy == 0) LastDeviceFlag = TRUE; } // Find the 'first' devices on the 1-Wire bus // Return TRUE : device found, ROM number in ROM_NO buffer // FALSE : no device present // int OneWire::OWFirst() { // 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 // int OneWire::OWNext() { // leave the search state alone return OWSearch(); } // TEST BUILD const unsigned char dscrc_table[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 }; //-------------------------------------------------------------------------- // Calculate the CRC8 of the byte value provided with the current // global 'crc8' value. // Returns current global crc8 value // unsigned char OneWire::docrc8(unsigned char value) { // See Application Note 27 // TEST BUILD crc8 = dscrc_table[crc8 ^ value]; return crc8; }