void DS18B20_Convert(uint8 *pID)//温度转换 { OWReset(); //复位 // OWWriteByte(0xcc); DS18B20_SendID(pID); OWWriteByte(0x44);//发出转换命令 }
unsigned int DS18B20_ReadTemperature(uint8 *pID) { unsigned int Data; OWReset(); //复位 DS18B20_SendID(pID); OWWriteByte(0xbe); //读温度 Data = OWReadByte(); Data += (unsigned int)(OWReadByte() << 8); return Data; }
// legge il codice del SINGOLO dispositivo sul bus // e lo memorizza nell'array ID passato come argomento void OWReadRom(unsigned char *ID) { OWReset(); // resetto la linea one-wire OWWriteByte(OW_READ_ROM); // invio il comando readrom, che si può usare solo se sulla linea c'è una sola sonda for(unsigned char a=0; a<8; a++)// ciclo per leggere gli 8 bytes restituiti dal dispositivo { // eseguo la lettura del byte a-esimo: ID[a]=OWReadByte(); } }
unsigned char *DS18B20_ReadID(unsigned char *u8Rom) { int i; OWReset(); //复位 OWWriteByte(0x33); for(i = 0; i < 8; i++) { u8Rom[i] = OWReadByte(); } return u8Rom; }
uint8_t doSlave(uint8_t* message) { uint8_t i; uint8_t cmd = message[0]; uint8_t datalen = 0; uint8_t retval = 0; debugPrint("command=%x\r\n", cmd); if (cmd == 0x10) { } else if (cmd == 0x11) { message[2] = OWFirst() ? 1 : 0; datalen = 1; } else if (cmd == 0x12) { message[2] = OWNext() ? 1 : 0; datalen = 1; } else if (cmd == 0x13) { datalen = 8; for (i = 0; i < 8; i++) { message[i + 2] = getROM_NO(i); } } else if (cmd == 0x16) { OWTargetSetup(0x00); } else if (cmd == 0x19) { message[2] = OWReadByte(); datalen = 1; } else if (cmd == 0x1B) { uint8_t len; uint8_t* _buf; len = message[1]; _buf = message + 2; retval = OWBlock(_buf, len) ? 0x00 : 0xFF; memcpy(message + 2, _buf, len); datalen = len; } else if (cmd == 0x1C) { message[2] = OWReset(); datalen = 1; } else if (cmd == 0x1D) { // OWWriteByte(message[1]); uint8_t len; uint8_t* _buf; len = message[1]; _buf = message + 2; retval = OWBlock(_buf, len) ? 0x00 : 0xFF; memcpy(message + 2, _buf, len); datalen = len; } else if (cmd == 0x1E) { // OWLevel(MODE_NORMAL); } else if (cmd == 0x1F) { OWTargetSetup(message[1]); } else if (cmd == 0x20) { OWFamilySkipSetup(); } else if (cmd == 0x21) { uint8_t address[8]; memcpy(address, message + 2, 8); message[2] = OWSearchROM(address); datalen = 1; } else if (cmd == 0x22) { uint8_t address[8]; memcpy(address, message + 2, 8); message[2] = OWMatchROM(address); datalen = 1; } else { retval = 0xFF; } message[0] = retval; if (retval == 0xFF) { datalen = 0; } message[1] = datalen; return datalen; }
//-------------------------------------------------------------------------- //! 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 OWSearch() { int id_bit_number; int last_zero, rom_byte_number, search_result; int 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 (!OWReset()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // issue the search command OWWriteByte(0xF0); // loop to do the search do { // read a bit and its complement id_bit = OWReadBit(); cmp_id_bit = OWReadBit(); // 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 if (id_bit_number == LastDiscrepancy) search_direction = 1; else search_direction = 0; // 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 OWWriteBit(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; }
//-------------------------------------------------------------------------- // The 'OWSearch' function does a general search. This function // continues from the previos search state. The search state // can be reset by using the 'OWFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // Returns: TRUE (1) : when a 1-Wire device was found and it's // Serial Number placed in the global ROM // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // int DallasOneWire::OWSearch(void) { DATA(F("OWSearch")); unsigned char last_zero,pos; unsigned char tmp_rom[8]; unsigned char readbuffer[20],sendpacket[40]; unsigned char i,sendlen=0; // if the last call was the last one if (LastDeviceFlag) { DATA(F("OWSearch: the last call was the last one")); // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // reset the 1-wire // if there are no parts on 1-wire, return FALSE if (!OWReset()) { DEBUG(F("OWSearch: there are no parts on 1-wire, return FALSE")); // reset the search LastDiscrepancy = 0; LastFamilyDiscrepancy = 0; return FALSE; } // build the command stream // call a function that may add the change mode command to the buff // check for correct mode if (UMode != MODSEL_DATA) { DATA(F("OWSearch: UMode != MODSEL_DATA")); UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // search command sendpacket[sendlen++] = 0xF0; // change back to command mode UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search mode on sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed); // change back to data mode UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; // set the temp Last Discrepancy to 0 last_zero = 0; // add the 16 bytes of the search pos = sendlen; for (i = 0; i < 16; i++) sendpacket[sendlen++] = 0; // only modify bits if not the first search if (LastDiscrepancy != 0) { DATA(F("OWSearch: LastDiscrepancy != 0")); // set the bits in the added buffer for (i = 0; i < 64; i++) { // before last discrepancy if (i < (LastDiscrepancy - 1)) bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,&ROM_NO[0]), (short)(i * 2 + 1), &sendpacket[pos]); // at last discrepancy else if (i == (LastDiscrepancy - 1)) bitacc(WRITE_FUNCTION,1,(short)(i * 2 + 1), &sendpacket[pos]); // after last discrepancy so leave zeros } } // change back to command mode UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search OFF command sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed); // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(17,readbuffer) == 17) { // interpret the bit stream for (i = 0; i < 64; i++) { // get the ROM bit bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),i, &tmp_rom[0]); // check LastDiscrepancy if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) && (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0)) { last_zero = i + 1; // check LastFamilyDiscrepancy if (i < 8) LastFamilyDiscrepancy = i + 1; } } // do dowcrc crc8 = 0; for (i = 0; i < 8; i++) docrc8(tmp_rom[i]); // check results if ((crc8 != 0) || (LastDiscrepancy == 63) || (tmp_rom[0] == 0)) { // error during search // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // successful search else { // set the last discrepancy LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) LastDeviceFlag = TRUE; // copy the ROM to the buffer for (i = 0; i < 8; i++) ROM_NO[i] = tmp_rom[i]; return TRUE; } } } WARNING(F("OWSearch: an error occured so re-sync with DS2480B")); // an error occured so re-sync with DS2480B DS2480B_Detect(); // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; }
//-------------------------------------------------------------------------- // The 'OWSearch' function does a general search. This function // continues from the previous search state. The search state // can be reset by using the 'OWFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // Returns: TRUE (1) : when a 1-Wire device was found and its // Serial Number placed in the global ROM // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // int 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, status; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = FALSE; crc8 = 0; // if the last call was not the last one if (!LastDeviceFlag) { // 1-Wire reset if (!OWReset()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // issue the search command OWWriteByte(0xF0); // loop to do the search do { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < LastDiscrepancy) { if ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0) search_direction = 1; else search_direction = 0; } else { // if equal to last pick 1, if not then pick 0 if (id_bit_number == LastDiscrepancy) search_direction = 1; else search_direction = 0; } // Perform a triple operation on the DS2482 which will perform 2 read bits and 1 write bit status = DS2482_search_triplet(search_direction); // check bit results in status byte id_bit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR); cmp_id_bit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB); search_direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? 0x01 : 0x00; // check for no devices on 1-Wire if ((id_bit) && (cmp_id_bit)) break; else { if ((!id_bit) && (!cmp_id_bit) && (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] &= (uint8_t)~rom_byte_mask; // 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) { calc_crc8(ROM_NO[rom_byte_number]); // accumulate the CRC rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); // (do-while) 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] == 0)) { LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; search_result = FALSE; } return search_result; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { char test[25]; unsigned int an1, an2, an3, an4, an5; float Ta=0; int i; long msum[4]; float fm[4], T1, T2, T3, SP; unsigned int DSState = 0; unsigned long DSTimer=0, t0, t1, dt, HTimer, TTimer, t_sec, t_min; unsigned char data[2]; unsigned char out=0; unsigned int decval; volatile float pp, pi, pd, f_error, error_old=0, pid_out, pid_out_i, pid_out_p, pid_out_d, error_i=0; u8 Send_Buffer[25]; u8 tmp[4]; //char no_windup = 0; RCC_Configuration(); NVIC_Configuration(); /* SysTick end of count event each 1ms with input clock equal to 9MHz (HCLK/8, default) */ SysTick_SetReload(9000); /* Enable SysTick interrupt */ SysTick_ITConfig(ENABLE); /* Enable the SysTick Counter */ SysTick_CounterCmd(SysTick_Counter_Enable); GPIO_Setup(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /* SPI2 Config -------------------------------------------------------------*/ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); /* Enable SPI1 */ SPI_CalculateCRC(SPI2, DISABLE); SPI_Cmd(SPI2, ENABLE); InitADC1(); // ADC1 Init OWInit(&OneWire, GPIOB, GPIO_Pin_8); /* Connect Key Button EXTI Line to Key Button GPIO Pin */ //GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_Pin_7); /* Configure Key Button EXTI Line to generate an interrupt on falling edge */ //EXTI_InitStructure.EXTI_Line = EXTI_Line7; //EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //EXTI_InitStructure.EXTI_LineCmd = ENABLE; //EXTI_Init(&EXTI_InitStructure); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 55000; TIM_TimeBaseStructure.TIM_Prescaler = 12; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* TIM2 PWM2 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_Channel = TIM_Channel_1; TIM_OCInitStructure.TIM_Pulse = 1;//20000; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInit(TIM3, &TIM_OCInitStructure); /* TIM2 configuration in Input Capture Mode */ TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM3, &TIM_ICInitStructure); /* One Pulse Mode selection */ TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single); /* Input Trigger selection */ TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2); /* Slave Mode selection: Trigger Mode */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger); ST7565_st7565_init(); ST7565_st7565_command(CMD_SET_BIAS_9); ST7565_st7565_command(CMD_DISPLAY_ON); ST7565_st7565_command(CMD_SET_ALLPTS_NORMAL); ST7565_st7565_set_brightness(0x0C); OWSearch(&OneWire, addr); /*sprintf(test, "%02X %02X %02X %02X %02X %02X %02X %02X", addr[7],addr[6], addr[5],addr[4], addr[3],addr[2], addr[1],addr[0]); ST7565_drawstring(6, 6, test); */ USB_Init(); ST7565_display(); // show splashscreen t0 = millis(); HTimer = millis(); TTimer = millis(); pp = 10; pi = 0; pd = 150; while(1) { msum[0] = 0; msum[1] = 0; msum[2] = 0; msum[3] = 0; for (i = 0; i < 1000; i++) { an1 = GetADC1Channel(ADC_Channel_1); an2 = GetADC1Channel(ADC_Channel_2); an3 = GetADC1Channel(ADC_Channel_3); an4 = GetADC1Channel(ADC_Channel_4); an5 = GetADC1Channel(ADC_Channel_5); msum[0] += an1; msum[1] += an3 - an2; msum[2] += an4 - an2; msum[3] += an5 - an2; //DelayuS(333); } SP = round((msum[0] / 1000.0) * (60.0 / 4096)) * 5; fm[1] = (msum[1] / 1000.0); fm[2] = (msum[2] / 1000.0) + 12; fm[3] = (msum[3] / 1000.0) - 7; T1 = (T1 + Ta + Dac2Dt(fm[1])) / 2; T2 = (T2 + Ta + Dac2Dt(fm[2])) / 2; T3 = (T3 + Ta + Dac2Dt(fm[3])) / 2; t1 = millis(); dt = t1 - t0; t0 = t1; if (millis() - HTimer > 1000) { f_error = SP - T2; //if (noerror_i += error; pid_out_p = pp * f_error; pid_out_i = pi * error_i; pid_out_d = pd * (f_error - error_old); pid_out = pid_out_p + pid_out_i + pid_out_d; error_old = f_error; //out = pid_out; if (pid_out > 99) { out = 99; } else if (pid_out < 0) { out = 0; } else { out = round(pid_out); } TIM_SetCompare1(TIM3, 55000-PowerValues[out]); HTimer += 1000; //error_old = 10; sprintf(test, "T1 : %5.1f E %5.1f ", T1, f_error); ST7565_drawstring(6, 0, test); sprintf(test, "T2 : %5.1f ", T2); ST7565_drawstring(6, 1, test); sprintf(test, "T3 : %5.1f ", T3); ST7565_drawstring(6, 2, test); sprintf(test, "SP : %5.1f P %6.1f ", SP, pid_out_p); ST7565_drawstring(6, 3, test); sprintf(test, "Ta : %5.1f I %6.1f ", Ta, pid_out_i); ST7565_drawstring(6, 4, test); sprintf(test, "dt : %5lu D %6.1f ", dt, pid_out_d); ST7565_drawstring(6, 5, test); sprintf(test, "out: %3u %% %6.1f ", out, pid_out); ST7565_drawstring(6, 6, test); t_sec = (millis() - TTimer) / 1000; t_min = floor(t_sec / 60); t_sec %= 60; Send_Buffer[0] = 0x07; decval = round(T1 * 100); memcpy(&Send_Buffer[1], &decval, 2); decval = round(T2 * 100); memcpy(&Send_Buffer[3], &decval, 2); decval = round(T3 * 100); memcpy(&Send_Buffer[5], &decval, 2); decval = round(SP * 100); memcpy(&Send_Buffer[7], &decval, 2); memcpy(&Send_Buffer[9], &out, 1); //sprintf(test, "%02X %02X %02X %02X ", Send_Buffer[1], Send_Buffer[2], Send_Buffer[3], Send_Buffer[4]); //ST7565_drawstring(6, 7, test); UserToPMABufferCopy(Send_Buffer, ENDP1_TXADDR, 9); SetEPTxCount(ENDP1, 9); SetEPTxValid(ENDP1); ST7565_display(); } if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { TTimer = millis(); } //onewire switch (DSState){ case 0: OWReset(&OneWire); OWWrite(&OneWire, 0xCC); // skip ROM OWWrite(&OneWire, 0x44); // start conversion DSTimer = millis(); DSState++; break; case 1: if((millis() - DSTimer) >= 1000){ OWReset(&OneWire); OWSelect(&OneWire, addr); OWWrite(&OneWire, 0xBE); // Read Scratchpad data[0] = OWRead(&OneWire); data[1] = OWRead(&OneWire); Ta = ((data[1] << 8) | data[0]) / 16.0; DSState = 0; } break; } } }