Пример #1
0
/*****************************************************************************
*   Function name :   DS18B20_StartAllDevicesConverting
*   Parameters :    bus - вывод микроконтроллера, который выполн¤ет роль 1WIRE шины
*   Purpose :      «апускает измерение на всех устройствах одновременно,
*                  ждет окончани¤ преобразовани¤
*****************************************************************************/
void DS18B20_StartAllDevicesConverting(unsigned char bus){
    OWI_DetectPresence(bus);
    OWI_SkipRom(bus);
    OWI_SendByte(DS18B20_CONVERT_T, bus);

    /*ждем, когда датчик завершит преобразование*/ 
	//while (!OWI_ReadBit(bus));
	_delay_ms(750);
}
Пример #2
0
/*
 * owiADCConvert(unsigned char bus_pattern, unsigned char * id)
 *
 *
 * this function implements the convert function
 * using the 0x3C command
 *
 * CRC checks are not performed
 *
 * input:
 *    bus_pattern:
 *                 pattern of bus lines to send command to
 *    id         :
 *                 1-wire device id 8 byte char array
 *                    - if set, i.e. not NULL, only device with this id is addressed (MATCH_ROM)
 *                    - else every device is used (ROM_SKIP)
 *
 * return:
 *    0: ok
 *    1: failed
 *
 */
uint8_t owiADCConvert(unsigned char currentPins, unsigned char * id)
{
	printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("bus_pattern: %#x starting conversion sequence"), currentPins );

	static uint16_t maxConversionTime = OWI_ADC_MAX_CONVERSION_TIME_MILLISECONDS;
	static uint32_t count;
	static uint32_t maxcount;
	static unsigned char timeout_flag;
	uint8_t trialsCounter = 0;
	uint8_t result = RESULT_OK;
    uint16_t receive_CRC;

	maxcount = ( OWI_ADC_CONVERSION_DELAY_MILLISECONDS > 0 ) ? maxConversionTime / OWI_ADC_CONVERSION_DELAY_MILLISECONDS : 1;
	count = maxcount;
	timeout_flag = FALSE;

	/*
	 * CONVERT [3CH]
	 *
	 * The Convert command is used to initiate the analog to digital conversion for one or more channels at the
	 * resolution specified in memory page 1, control/status data. The conversion takes between 60 and 80 μs
	 * per bit plus an offset time of maximum 160 μs every time the convert command is issued. For four
	 * channels with 12-bit resolution each, as an example, the convert command will not take more than
	 * 4x12x80 μs plus 160 μs offset, which totals 4 ms. If the DS2450 gets its power through the VCC pin, the
	 * bus master may communicate with other devices on the 1-Wire bus while the DS2450 is busy with A/D
	 * conversions. If the device is powered entirely from the 1-Wire bus, the bus master must instead provide a
	 * strong pullup to 5V for the estimated duration of the conversion in order to provide sufficient energy.
	 *
	 * The conversion is controlled by the input select mask (Figure 7a) and the read-out control byte (Figure
	 * 7b). In the input select mask the bus master specifies which channels participate in the conversion. A
	 * channel is selected if the bit associated to the channel is set to 1. If more than one channel is selected, the
	 * conversion takes place one channel after another in the sequence A, B, C, D, skipping those channels that
	 * are not selected. The bus master can read the result of a channel’s conversion before the conversion of all
	 * the remaining selected channels is completed. In order to distinguish between the previous result and the
	 * new value the bus master uses the read-out control byte. This byte allows presetting the conversion readout
	 * registers for each selected channel to all 1’s or all 0’s. If the expected result is close to 0 then one
	 * should preset to all 1’s or to all 0’s if the conversion result will likely be a high number. In applications
	 * where the bus master can wait until all selected channels are converted before reading, a preset of the
	 * read-out registers is not necessary. Note that for a channel not selected in the input select mask, the
	 * channel’s read-out control setting has no effect. If a channel constantly yields conversion results close to
	 * 0 the channel’s output transistor may be conducting. See section Device Registers for details.
	 *
	 * INPUT SELECT MASK (CONVERSION COMMAND) Figure 7a
	 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
	 * “don’t care” D C B A
	 *
	 * READ-OUT CONTROL (CONVERSION COMMAND) Figure 7b
	 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
	 * Set D Clear D Set C Clear C Set B Clear B Set A Clear A
	 *
	 * Set Clear Explanation
	 * 0 0 no preset, leave as is
	 * 0 1 preset to all 0’s
	 * 1 0 preset to all 1’s
	 * 1 1 (illegal code)
	 *
	 * Following the Convert command byte the bus master transmits the input select mask and the read-out
	 * control byte. Now the bus master reads the CRC16 of the command byte, select mask and control byte.
	 * The conversion will start no earlier than 10 μs after the most significant bit of the CRC is received by the
	 * bus master.
	 *
	 * With a parasitic power supply the bus master must activate the strong pullup within this 10 μs window for
	 * a duration that is estimated as explained above. After that, the data line returns to an idle high state and
	 * communication on the bus can resume. The bus master would normally send a reset pulse to exit the
	 * Convert command. Read data time slots generated after the strong pullup has ended but before issuing a
	 * reset pulse should result in all 1’s if the conversion time was calculated correctly.
	 *
	 * With VCC power supply the bus master may either send a reset pulse to exit the Convert command or
	 * continuously generate read data time slots. As long as the DS2450 is busy with conversions the bus
	 * master will read 0’s. After the conversion is completed the bus master will receive 1’s instead. Since in a
	 * open-drain environment a single 0 overwrites multiple 1’s the bus master can monitor multiple devices
	 * converting simultaneously and immediately knows when the last one is ready. As in the parasite
	 * powered scenario the bus master finally has to exit the Convert command by issuing a rest pulse.
	 *
	 * from data sheet: http://datasheets.maximintegrated.com/en/ds/DS2450.pdf
	 */

	while( trialsCounter < OWI_SEND_BYTE_MAX_TRIALS )
	{
		trialsCounter++;
        receive_CRC = 0;
    	result = RESULT_OK;

		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("bus_pattern: %#x sending command, mask, readout byte"),currentPins );
		/* select one or all, depending if id is given */
		if ( NULL == id)
		{
			/*
			 * SKIP ROM [CCH]
			 *
			 * This command can save time in a single drop bus system by allowing the bus master to access the
			 * memory/convert functions without providing the 64-bit ROM code. If more than one slave is present on
			 * the bus and a read command is issued following the Skip ROM command, data collision will occur on the
			 * bus as multiple slaves transmit simultaneously (open drain pulldowns will produce a wired-AND result).
			 */
			OWI_SkipRom(currentPins);

			result = owiSendBytesAndCheckCRC16(currentPins, 3,
					DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL);
			result = RESULT_OK; /*disable CRC check for skip rom*/
		}
		else
		{
			/*
			 * MATCH ROM [55H]
			 *
			 * The match ROM command, followed by a 64-bit ROM sequence, allows the bus master to address a
			 * specific DS2450 on a multidrop bus. Only the DS2450 that exactly matches the 64-bit ROM sequence
			 * will respond to the following memory/convert function command. All slaves that do not match the 64-bit
			 * ROM sequence will wait for a reset pulse. This command can be used with a single or multiple devices
			 * on the bus.
			 */
			OWI_MatchRom(id, currentPins); // Match id found earlier
			result = owiSendBytesAndCheckCRC16(currentPins, 3,
					DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL);
			result = RESULT_OK; /*disable CRC check for skip rom*/
		}

		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 3 bytes %#x ?"), owiComputeCRC16(0x0000, 3, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 4 bytes %#x ?"), owiComputeCRC16(0x0000, 4, OWI_ROM_SKIP, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 3 bytes %#x ?"), owiComputeCRC16(0xFFFF, 3, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 4 bytes %#x ?"), owiComputeCRC16(0xFFFF, 4, OWI_ROM_SKIP, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );


		if ( RESULT_OK == result )
		{
			break;
		}
		else
		{
			if (OWI_SEND_BYTE_MAX_TRIALS != trialsCounter)
			{
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("CRC16 check send byte failed - trial no. %i, computed %#x != received %#x"), trialsCounter);

				/* ending the Convert command sequence in any case by issuing a Reset Pulse*/
				OWI_DetectPresence(currentPins); /*the "DetectPresence" function includes sending a Reset Pulse*/
				continue;
			}
			else
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("CRC16 check reached max trials (%i) on send byte"), OWI_SEND_BYTE_MAX_TRIALS);
				result = RESULT_FAILURE;
				break;
			}
		}
	}

	//loop that waits for the conversion to be done
	if ( RESULT_OK == result )
	{
		result = RESULT_OK;
		while ( OWI_ReadBit(currentPins) == 0 )
		{
			_delay_ms(OWI_ADC_CONVERSION_DELAY_MILLISECONDS);

			/* timeout check */
			if ( 0 == --count)
			{
				timeout_flag = TRUE;
				result = RESULT_FAILURE;
				break;
			}
		}
		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("waited %i times a delay of %i ms"), maxcount - count, OWI_ADC_CONVERSION_DELAY_MILLISECONDS);

		/* ending the Convert command sequence in any case by issuing a Reset Pulse*/
		OWI_DetectPresence(currentPins); /*the "DetectPresence" function includes sending a Reset Pulse*/
	}

	/* post conversion status analysis*/
	if (RESULT_OK == result)
	{
		owiAdcTimeoutAndFailureBusMask &= ~(currentPins);
		result = RESULT_OK;
		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI ADC Conversion failed (bus_pattern: %#x)"), currentPins);
	}
	else
	{
		result = RESULT_FAILURE;

		if ( NULL == id )
		{
			owiAdcTimeoutAndFailureBusMask |= currentPins;
			if ( FALSE != timeout_flag )
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion timeout (bus_pattern: %#x"), currentPins);
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI Adc Conversion timeout (>%i ms) on bus_mask (%#x)"),  maxConversionTime, currentPins);
			}
			CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion failed (bus_pattern: %#x)"), currentPins);
		}
		else
		{
			owiCreateIdString(owi_id_string, id);
			if ( FALSE != timeout_flag )
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion timeout (id: %s"), owi_id_string);
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI Adc Conversion timeout (>%i ms) (id: %s)"),  maxConversionTime, owi_id_string);
			}
			CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion failed (id: %s)"), owi_id_string);
		}
	}

	return result;
}