Esempio n. 1
0
void DS18B20_Convert(uint8 *pID)//温度转换
{
	OWReset(); //复位
//	OWWriteByte(0xcc);
	DS18B20_SendID(pID);

	OWWriteByte(0x44);//发出转换命令
}
Esempio n. 2
0
unsigned int DS18B20_ReadTemperature(uint8 *pID)
{
	unsigned int Data;
	OWReset(); //复位
	DS18B20_SendID(pID);
	OWWriteByte(0xbe);	//读温度
	Data = OWReadByte();
	Data += (unsigned int)(OWReadByte() << 8);
	return Data;
}
Esempio n. 3
0
// 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();
		}
	}
Esempio n. 4
0
unsigned char *DS18B20_ReadID(unsigned char *u8Rom)
{
	int i;
	OWReset(); //复位
	OWWriteByte(0x33);
	for(i = 0; i < 8; i++)
	{
		u8Rom[i] = OWReadByte();
	}
	return u8Rom;
}
Esempio n. 5
0
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;
}
Esempio n. 8
0
//--------------------------------------------------------------------------
// 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;
}
Esempio n. 9
0
/**
  * @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;
    }
  }
}