STM32F1, STM32F2, LPC1768 + 18B20 + ow_search от MAXIM.

Ну, раз пошла такая пьянка (на многих форумах оживился интерес к ds1820), выкладываю свое, типа творчество.
Для умного дома понадобилось измерение температуры. А так как дом большой, датчиков получается до 2-х десятков. Датчики простые, но очень капризные. Поэтому решил под работу с ними выделить отдельный МК. Он будет их опрашивать, формировать строку с данными и слать ее по уарту в головной модуль, который уже займется отображением и управлением.

Датчики будут подключаться по самому простому способу, одна нога МК — один датчик. Длина кабеля от 15 метров. Подтяжка 4.3 — 4.7 кОм. Датчики засовываются в металлические трубки, приклеиваются к стенке теплопроводящим клеем и заливаются эбоксидкой.
Для начала мысль была использовать под это дело stm32vldiscovery. Дешевая, готовая платка, да и запас у меня их приличный. Но, что то не пошло. И таймер считает и ножки дергаются, а датчики молчат. Готовые проги из инета не помогают. После недели проб, плюнул, всял толстый lpc1768 и на удивление все сразу заработало. А через пару дней с помощью доброго человека, таки получилось запустить датчики и на stm32. Правда, на stm-е задержки все таки не правильные, софтовые. Функции только базовые.
Короче, у меня теперь 2 рабочих кода, для двух различных МК. Выложу сюда, может кому пригодиться. Да и самому легче если что найти.

Первый код для LPC1768. Датчики разбиты на 2 группы по пинам c P1.18 (8 датчиков) и с P0.23 (4 датчика):


#include "LPC17xx.h"
#include "rtl.h"
#include "stdio.h"
#include "string.h"

#define DS_1(num) (LPC_GPIO1->FIOPIN & (1UL<<(18+num)))
#define DS_2(num) (LPC_GPIO0->FIOPIN & (1UL<<(23+num)))

int count = 0;
char out[50];
char rom[3];
float fTemp1[8];
float fTemp2[4];


void delay_us (unsigned int us)
{
	LPC_TIM2->MCR = 0;                   		// disable timer
  	LPC_TIM2->MR0 = us;              			// interrupt event on overrun
  	LPC_TIM2->TC = 0;                    		// reset counter
  	LPC_TIM2->MCR |= (1 << 1); 					//reset counter on match 
	LPC_TIM2->TCR |= (1 << 0);          		// start Timer2
	while (LPC_TIM2->TC);
	return;
}

void delay_ms(unsigned int ms)
{
 	int i;
 	for (i=0; i < ms; i++)
	{
 		delay_us (1000);
 	}
 }

void InitTIM2 (void)
{
	LPC_SC->PCONP |= (1<<22);						// Timer2 power on
	LPC_SC->PCLKSEL1 |= (1 << 12);					// Divide CCLK by 1 for Timer2
	LPC_TIM2->TC = 0;                   			// clear timer counter
    LPC_TIM2->PC = 0;                   			// clear prescale counter
    LPC_TIM2->PR = 0;                   			// clear prescale register
    LPC_TIM2->TCR |= (1 << 1);          			// reset timer
    LPC_TIM2->TCR &= ~(1 << 1);         			// release reset
	LPC_TIM2->CTCR = 0x00;               			// timer mode
	LPC_TIM2->PR = 99;								// <resolution> uS accuracy @ CCLK/4 Peripheral Clock
	LPC_TIM2->MCR |= (1 << 1); 						//reset counter on match             	
   
}

void InitUart0_115200 (void)
{
	uint32_t Fdiv = 0;     

	LPC_SC->PCONP &= ~(1<<3);
	LPC_PINCON->PINSEL0 &= ~(3 << 4);
    LPC_PINCON->PINSEL0 &= ~(3 << 6); 

	LPC_SC->PCONP |= (1<<3);

	LPC_PINCON->PINSEL0 |= (1 << 4);             	/* Pin P0.2 used as TXD0 (Com0) */
    LPC_PINCON->PINSEL0 |= (1 << 6);             	/* Pin P0.3 used as RXD0 (Com0) */

	Fdiv = (25000000/16)/9600; 

	LPC_UART0->LCR    = 0x83;                         
	LPC_UART0->DLL    = Fdiv % 256; 
	LPC_UART0->DLM    = Fdiv / 256; 
	LPC_UART0->LCR    = 0x03;      
}

int UART_putChar0 (char c) 
{
	while (!(LPC_UART0->LSR & 0x20));
	return (LPC_UART0->THR = c);
}

void UART_putString0 (char *s) 
{
	while (*s != 0) 
	{
		UART_putChar0 (*s++);
	}
}

void DSOut_1 (unsigned int num)
{
	LPC_GPIO1->FIODIR |= (1<<(18+num));
}

void DSIn_1 (unsigned int num)
{
	LPC_GPIO1->FIODIR &= ~(1<<(18+num));
}

void DSUp_1 (unsigned int num)
{
	LPC_GPIO1->FIOSET |= (1<<(18+num));
}

void DSDown_1 (unsigned int num)
{
	LPC_GPIO1->FIOCLR |= (1<<(18+num));
}

char ow_reset_1 (unsigned int num)
{
	char ret = 10;

	DSOut_1 (num);
	DSUp_1 (num);
	delay_us (1);
	DSDown_1 (num);
	delay_us (500);
	DSIn_1 (num);
	delay_us (80);
	if (DS_1(num))
	{
		ret = 0;
	}
	else
	{
		ret = 1;
	}
	delay_us (400);
	return ret;
}

void ow_write_bit_1 (char bit, unsigned int num)
{
	if (bit)
	{
		DSOut_1 (num);
		DSUp_1 (num);
		delay_us (1);
		DSDown_1 (num);
		delay_us (10);
		DSUp_1 (num);
		delay_us (49);
	}
	else
	{
		DSOut_1 (num);
		DSUp_1 (num);
		delay_us (1);
		DSDown_1 (num);
		delay_us (59);
		DSUp_1 (num);
	} 
}

char ow_read_bit_1 (unsigned int num)
{
	char ret = 10;

	DSOut_1 (num);
	DSUp_1 (num);
	delay_us (1);
	DSDown_1 (num);
	delay_us (10);
	DSIn_1 (num);
	delay_us (10);
	if (DS_1(num))
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	delay_us (40);
	return ret;	
}

char ow_read_byte_1(unsigned int num)
{
	char i;
	char byte=0;
	for (i=0;i<8;i++)
	{
		if(ow_read_bit_1(num)) byte |= (0x01<<i);
		delay_us (1);
	}
	return(byte);
}

void ow_write_byte_1(char byte, unsigned int num)
{
	char a;
	char temp;

	for(a=0;a<8;a++)
	{
		temp = byte >> a;
		temp &=0x01;
		ow_write_bit_1(temp, num);
		delay_us (1);
	}
}

void DSOut_2 (unsigned int num)
{
	LPC_GPIO0->FIODIR |= (1<<(23+num));
}

void DSIn_2 (unsigned int num)
{
	LPC_GPIO0->FIODIR &= ~(1<<(23+num));
}

void DSUp_2 (unsigned int num)
{
	LPC_GPIO0->FIOSET |= (1<<(23+num));
}

void DSDown_2 (unsigned int num)
{
	LPC_GPIO0->FIOCLR |= (1<<(23+num));
}

char ow_reset_2 (unsigned int num)
{
	char ret = 10;

	DSOut_2 (num);
	DSUp_2 (num);
	delay_us (1);
	DSDown_2 (num);
	delay_us (500);
	DSIn_2 (num);
	delay_us (80);
	if (DS_2(num))
	{
		ret = 0;
	}
	else
	{
		ret = 1;
	}
	delay_us (400);
	return ret;
}

void ow_write_bit_2 (char bit, unsigned int num)
{
	if (bit)
	{
		DSOut_2 (num);
		DSUp_2 (num);
		delay_us (1);
		DSDown_2 (num);
		delay_us (10);
		DSUp_2 (num);
		delay_us (49);
	}
	else
	{
		DSOut_2 (num);
		DSUp_2 (num);
		delay_us (1);
		DSDown_2 (num);
		delay_us (59);
		DSUp_2 (num);
	} 
}

char ow_read_bit_2 (unsigned int num)
{
	char ret = 10;

	DSOut_2 (num);
	DSUp_2 (num);
	delay_us (1);
	DSDown_2 (num);
	delay_us (10);
	DSIn_2 (num);
	delay_us (10);
	if (DS_2(num))
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	delay_us (40);
	return ret;	
}

char ow_read_byte_2(unsigned int num)
{
	char i;
	char byte=0;
	for (i=0;i<8;i++)
	{
		if(ow_read_bit_2(num)) byte |= (0x01<<i);
		delay_us (1);
	}
	return(byte);
}

void ow_write_byte_2(char byte, unsigned int num)
{
	char a;
	char temp;

	for(a=0;a<8;a++)
	{
		temp = byte >> a;
		temp &=0x01;
		ow_write_bit_2(temp, num);
		delay_us (1);
	}
}

void DS1 (void) 
{
	int count = 0;
	char out[50];
	char rom[3];
	float fTemp[8];

		count = 0;
		while (count < 8)
		{	
			if (ow_reset_1 (count))
			{
				ow_write_byte_1(0xCC, count);
				ow_write_byte_1(0x44, count);
				delay_ms (2000);
				ow_reset_1(count);
				ow_write_byte_1(0xCC, count);
				ow_write_byte_1(0xBE, count);
			
				rom[0] = ow_read_byte_1(count);
				rom[1] = ow_read_byte_1(count);
	
				fTemp[count] = (float)(rom[0] + (rom[1]<<8))/16;
				sprintf(out,"%02.4f - 1.%d\n\n",fTemp[count],count);		
				UART_putString0 (out);
			}
			else
			{
			 	UART_putString0 ("Not present\n\n");
			}
			count++;   
		}

}

void DS2 (void) 
{
	int count = 0;
	char out[50];
	char rom[3];
	float fTemp[4];

		count = 0;
		while (count < 4)
		{	
			if (ow_reset_2 (count))
			{
				ow_write_byte_2(0xCC, count);
				ow_write_byte_2(0x44, count);
				delay_ms (2000);
				ow_reset_2(count);
				ow_write_byte_2(0xCC, count);
				ow_write_byte_2(0xBE, count);
			
				rom[0] = ow_read_byte_2(count);
				rom[1] = ow_read_byte_2(count);
	
				fTemp[count] = (float)(rom[0] + (rom[1]<<8))/16;
				sprintf(out,"%02.4f - 2.%d\n\n",fTemp[count],count);		
				UART_putString0 (out);
			}
			else
			{
			 	UART_putString0 ("Not present\n\n");
			}
			count++;
	}

}

int main (void)
{
	SystemInit ();
	InitUart0_115200 ();
	UART_putString0 ("\n\nStarting ... \n\n");
	InitTIM2 ();

	while (1)
	{
		count = 0;
		while (count < 8)
		{	
			if (ow_reset_1(count) == 1)
			{
				ow_write_byte_1(0xCC, count);
				ow_write_byte_1(0x44, count);
				delay_ms (2000);
				ow_reset_1(count);
				ow_write_byte_1(0xCC, count);
				ow_write_byte_1(0xBE, count);
			
				rom[0] = ow_read_byte_1(count);
				rom[1] = ow_read_byte_1(count);
	
				fTemp1[count] = (float)(rom[0] + (rom[1]<<8))/16;
				sprintf(out,"%02.4f - 1.%d\n\n",fTemp1[count],count);		
				UART_putString0 (out);
			}

			count++;   
		}
		UART_putString0 ("\n\n");
		delay_ms (1000);
		count = 0;
		while (count < 4)
		{	
			if (ow_reset_2(count) == 1)
			{
				ow_write_byte_2(0xCC, count);
				ow_write_byte_2(0x44, count);
				delay_ms (2000);
				ow_reset_2(count);
				ow_write_byte_2(0xCC, count);
				ow_write_byte_2(0xBE, count);
			
				rom[0] = ow_read_byte_2(count);
				rom[1] = ow_read_byte_2(count);
	
				fTemp2[count] = (float)(rom[0] + (rom[1]<<8))/16;
				sprintf(out,"%02.4f - 2.%d\n\n",fTemp2[count],count);		
				UART_putString0 (out);
			}

			count++;
		}
		UART_putString0 ("\n\n");
	}
}



Второй код для stm32f100. 3 группы датчиков, PORTA1-PORTA7, PORTC4-PORTC5,PORTB1-PORTB2.


#include "stm32f10x.h"
#include "string.h"
#include "stdio.h" 	
#include "stdlib.h"   

#define Set_PortC_Pin_8_output ((GPIOC->CRH |= 0x3)|(GPIOC->CRH &= ~0xC))	
#define Set_PortC_Pin_9_output ((GPIOC->CRH |= 0x30)|(GPIOC->CRH &= ~0xC0))

#define Set_Port_input_1(num) ((GPIOA->CRL &= ~(0x0f<<((1+num)*4)))|(GPIOA->CRL |= (0x04<<((1+num)*4))))
#define Set_Port_output_1(num) ((GPIOA->CRL &= ~(0x0f<<((1+num)*4)))|(GPIOA->CRL |= (0x03<<((1+num)*4))))

#define Set_Port_Up_1(num) (GPIOA->BSRR=(1<<(1+num)))
#define Set_Port_Down_1(num) (GPIOA->BSRR=(1<<(17+num)))

#define DS_IN_1(num) (GPIOA->IDR & (1<<(1+num)))

#define Set_Port_input_2(num) ((GPIOC->CRL &= ~(0x0f<<((4+num)*4)))|(GPIOC->CRL |= (0x04<<((4+num)*4))))
#define Set_Port_output_2(num) ((GPIOC->CRL &= ~(0x0f<<((4+num)*4)))|(GPIOC->CRL |= (0x03<<((4+num)*4))))

#define Set_Port_Up_2(num) (GPIOC->BSRR=(1<<(4+num)))
#define Set_Port_Down_2(num) (GPIOC->BSRR=(1<<(20+num)))

#define DS_IN_2(num) (GPIOC->IDR & (1<<(4+num)))

#define Set_Port_input_3(num) ((GPIOB->CRL &= ~(0x0f<<((0+num)*4)))|(GPIOB->CRL |= (0x04<<((0+num)*4))))
#define Set_Port_output_3(num) ((GPIOB->CRL &= ~(0x0f<<((0+num)*4)))|(GPIOB->CRL |= (0x03<<((0+num)*4))))

#define Set_Port_Up_3(num) (GPIOB->BSRR=(1<<(0+num)))
#define Set_Port_Down_3(num) (GPIOB->BSRR=(1<<(16+num)))

#define DS_IN_3(num) (GPIOB->IDR & (1<<(0+num)))

#define GreenLedOn (GPIOC->BSRR=GPIO_BSRR_BS9) 
#define GreenLedOff (GPIOC->BSRR=GPIO_BSRR_BR9) 
#define BlueLedOn (GPIOC->BSRR=GPIO_BSRR_BS8) 
#define BlueLedOff (GPIOC->BSRR=GPIO_BSRR_BR8)

#define F_CPU		24000000 

char uartout[300];
char count = 0;
char out[31];
char rom[3];
float fTemp;

__asm void _delay_loop(uint32_t __count)
{
loop	SUBS     r0,r0,#1
		BNE      loop
		BX    lr
}

void _delay_us(double __us)
{
	uint32_t __ticks;
	double __tmp = ((F_CPU) / 3e6) * __us;
	__ticks = (uint32_t)__tmp;

	_delay_loop(__ticks);	 
}


void _delay_ms(double __ms)
{
	uint32_t __ticks;
	double __tmp = ((F_CPU) / 3e3) * __ms;
	__ticks = (uint32_t)__tmp;

	_delay_loop(__ticks);
}

void Delay (long cnt) 
{  
	while (cnt--);
}

void USART1_Init(void)
{
	  RCC->APB2ENR |=   RCC_APB2ENR_IOPAEN;                //Òàêòèðîâàíèå GPIO
	  RCC->APB2ENR |=   RCC_APB2ENR_AFIOEN;                //Òàêòèðîâàíèå àëüòåðíàòèâíûõ ôóíêöèé GPIO
	  RCC->APB2ENR |=   RCC_APB2ENR_USART1EN;              //Òàêòèðîâàíèå USART1
	  //Êîíôèãóðèðîâàíèå PORTA.9 äëÿ TX; PORTA.10 äëÿ RX 
	  GPIOA->CRH   &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9);   //Ïðåäî÷èñòêà MODE è CNF
	  GPIOA->CRH   |=   GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1;  //Äâóõòàêòíûé âûõîä ñ àëüòåðíàòèâíîé ô-åé, 50MHz
	  GPIOA->CRH   &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10); //Ïðåäî÷èñòêà MODE è CNF
	  GPIOA->CRH   |=   GPIO_CRH_CNF10_0;                  //Âõîä, òðåòüå ñîñòîÿíèå
	  //Çàäàíèå ðåæèìà ðàáîòû
	  USART1->BRR   =   0x09C4;                            //Cêîðîñòü îáìåíà 9600 áîä
	  USART1->CR1  &=  ~USART_CR1_M;                       //8 áèò äàííûõ
	  USART1->CR2  &=  ~USART_CR2_STOP;                    //Êîëè÷åñòâî ñòîï-áèòîâ: 1
	  //Óïðàâëåíèå ðàáîòîé
	  USART1->CR1  |=   USART_CR1_UE;                      //Âêëþ÷åíèå ìîäóëÿ USART1
	  USART1->CR1  |=   USART_CR1_TE;                      //Âêëþ÷åíèå ïåðåäàò÷èêà
	  USART1->CR1  |=   USART_CR1_RE;                      //Âêëþ÷åíèå ïðèåìíèêà
}
 
void USART1_SendData(unsigned char data)
{
	  USART1->DR  =  data;                                //çàïóñòèòü ïðîöåññ ïåðåäà÷è
	  while((USART1->SR & USART_SR_TC)==0) {}             //îæèäàíèå ïåðåäà÷è áàéòà
	  USART1->SR &=  ~USART_SR_TC;                        //î÷èñòèòü ôëàã
}


void USART1_SendString (char *s) 
{
	while (*s != 0) 
	{
		USART1_SendData (*s++);
	}
} 

void DevInit (void)
{
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;	 		
	RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;	 					
	RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

	Set_PortC_Pin_8_output;
	Set_PortC_Pin_9_output;
}

char ow_reset_1 (char num)
{
	char ret = 10;

	Set_Port_output_1(num);
	Set_Port_Down_1(num);
	_delay_us(600);
	Set_Port_input_1(num);
	_delay_us(80);
	if(DS_IN_1(num))
	{
		ret = 0;
	}
	else
	{
		ret = 1;
	}
	_delay_us (400);
	return ret;
}

void ow_write_bit_1 (char bit, char num)
{
	if (bit)
	{
		Set_Port_output_1(num);
		Set_Port_Down_1(num);
		_delay_us (10);
		Set_Port_Up_1(num);
		_delay_us (49);
	}
	else
	{
		Set_Port_output_1(num);
		Set_Port_Down_1(num);
		_delay_us (59);
		Set_Port_Up_1(num);
	} 
}

char ow_read_bit_1 (char num)
{
	char ret = 10;

	Set_Port_output_1(num);
	Set_Port_Down_1(num);
	_delay_us (5);
	Set_Port_input_1(num);
	_delay_us (10);
	if (DS_IN_1(num))
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	_delay_us (44);
	return ret;	
}

char ow_read_byte_1 (char num)
{
	char i;
	char byte=0;
	for (i=0;i<8;i++)
	{
		if(ow_read_bit_1 (num)) byte |= (0x01<<i);
		_delay_us (1);
	}
	return(byte);
}

void ow_write_byte_1 (char byte, char num)
{
	char a;
	char temp;

	for(a=0;a<8;a++)
	{
		temp = byte >> a;
		temp &=0x01;
		ow_write_bit_1 (temp, num);
		_delay_us (1);
	}
}

char ow_reset_2 (char num)
{
	char ret = 10;

	Set_Port_output_2(num);
	Set_Port_Down_2(num);
	_delay_us(600);
	Set_Port_input_2(num);
	_delay_us(80);
	if(DS_IN_2(num))
	{
		ret = 0;
	}
	else
	{
		ret = 1;
	}
	_delay_us (400);
	return ret;
}

void ow_write_bit_2 (char bit, char num)
{
	if (bit)
	{
		Set_Port_output_2(num);
		Set_Port_Down_2(num);
		_delay_us (10);
		Set_Port_Up_2(num);
		_delay_us (49);
	}
	else
	{
		Set_Port_output_2(num);
		Set_Port_Down_2(num);
		_delay_us (59);
		Set_Port_Up_2(num);
	} 
}

char ow_read_bit_2 (char num)
{
	char ret = 10;

	Set_Port_output_2(num);
	Set_Port_Down_2(num);
	_delay_us (5);
	Set_Port_input_2(num);
	_delay_us (10);
	if (DS_IN_2(num))
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	_delay_us (44);
	return ret;	
}

char ow_read_byte_2 (char num)
{
	char i;
	char byte=0;
	for (i=0;i<8;i++)
	{
		if(ow_read_bit_2 (num)) byte |= (0x01<<i);
		_delay_us (1);
	}
	return(byte);
}

void ow_write_byte_2 (char byte, char num)
{
	char a;
	char temp;

	for(a=0;a<8;a++)
	{
		temp = byte >> a;
		temp &=0x01;
		ow_write_bit_2 (temp, num);
		_delay_us (1);
	}
}

char ow_reset_3 (char num)
{
	char ret = 10;

	Set_Port_output_3(num);
	Set_Port_Down_3(num);
	_delay_us(600);
	Set_Port_input_3(num);
	_delay_us(80);
	if(DS_IN_3(num))
	{
		ret = 0;
	}
	else
	{
		ret = 1;
	}
	_delay_us (400);
	return ret;
}

void ow_write_bit_3 (char bit, char num)
{
	if (bit)
	{
		Set_Port_output_3(num);
		Set_Port_Down_3(num);
		_delay_us (10);
		Set_Port_Up_3(num);
		_delay_us (49);
	}
	else
	{
		Set_Port_output_3(num);
		Set_Port_Down_3(num);
		_delay_us (59);
		Set_Port_Up_3(num);
	} 
}

char ow_read_bit_3 (char num)
{
	char ret = 10;

	Set_Port_output_3(num);
	Set_Port_Down_3(num);
	_delay_us (5);
	Set_Port_input_3(num);
	_delay_us (10);
	if (DS_IN_3(num))
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	_delay_us (44);
	return ret;	
}

char ow_read_byte_3 (char num)
{
	char i;
	char byte=0;
	for (i=0;i<8;i++)
	{
		if(ow_read_bit_3 (num)) byte |= (0x01<<i);
		_delay_us (1);
	}
	return(byte);
}

void ow_write_byte_3 (char byte, char num)
{
	char a;
	char temp;

	for(a=0;a<8;a++)
	{
		temp = byte >> a;
		temp &=0x01;
		ow_write_bit_3 (temp, num);
		_delay_us (1);
	}
}

int main (void)
{
	SystemInit ();
	DevInit ();
	USART1_Init();
	USART1_SendString ("\n\nStarting\n\n");
	//InitLCD ();
	//LCDputs ("Starting");
	while (1)
	{
		count = 0;
		while (count < 7)
		{
			ow_reset_1 (count);

			ow_write_byte_1 (0xCC, count);
			ow_write_byte_1 (0x44, count);
			GreenLedOn;
			_delay_ms (1000);
			GreenLedOff;
			ow_reset_1 (count);
			ow_write_byte_1 (0xCC, count);
			ow_write_byte_1 (0xBE, count);
						
			rom[0] = ow_read_byte_1 (count);
			rom[1] = ow_read_byte_1 (count);

			fTemp = (float)(rom[0] + (rom[1]<<8))/16;

			sprintf(out,"ch.1.%d,t=%+02.2f,rom=%03d:%03d; ",count,fTemp,rom[0],rom[1]);

			strncat (uartout, out, 30);

			count++;
		}
		strncat (uartout, "\n", 2);
		count = 0;
		while (count < 2)
		{
			ow_reset_1 (count);

			ow_write_byte_2 (0xCC, count);
			ow_write_byte_2 (0x44, count);
			GreenLedOn;
			_delay_ms (1000);
			GreenLedOff;
			ow_reset_2 (count);
			ow_write_byte_2 (0xCC, count);
			ow_write_byte_2 (0xBE, count);
						
			rom[0] = ow_read_byte_2 (count);
			rom[1] = ow_read_byte_2 (count);

			fTemp = (float)(rom[0] + (rom[1]<<8))/16;

			sprintf(out,"ch.2.%d,t=%+02.2f,rom=%03d:%03d; ",count,fTemp,rom[0],rom[1]);

			strncat (uartout, out, 30);
		
			count++;
		}
		strncat (uartout, "\n", 2);
		count = 0;
		while (count < 2)
		{
			ow_reset_3 (count);

			ow_write_byte_3 (0xCC, count);
			ow_write_byte_3 (0x44, count);
			GreenLedOn;
			_delay_ms (1000);
			GreenLedOff;
			ow_reset_3 (count);
			ow_write_byte_3 (0xCC, count);
			ow_write_byte_3 (0xBE, count);
						
			rom[0] = ow_read_byte_3 (count);
			rom[1] = ow_read_byte_3 (count);

			fTemp = (float)(rom[0] + (rom[1]<<8))/16;

			sprintf(out,"ch.3.%d,t=%+02.2f,rom=%03d:%03d; ",count,fTemp,rom[0],rom[1]);

			strncat (uartout, out, 30);

			count++;
		}
		BlueLedOn;
		USART1_SendString (uartout);
		USART1_SendString ("\n\n");
		strcpy (uartout , "");
		BlueLedOff;
	}

}



Коды рабочие, но чисто для проверки. Только базовые функции, никакой оптимизации или творческого подхода. Если кто подскажет, как на stm32 сделать временные задержки от таймера, буду сильно признателен. Изначально настройка таймера и функции задержек были такие:


void DevTIM2 (void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    TIM2->CR1 = 0;                                    
    TIM2->CR2 = 0;
    TIM2->CR1 |= TIM_CR1_OPM | TIM_CR1_ARPE;
}

void delay_us (uint32_t us)
{
    TIM2->PSC = 23;
    TIM2->ARR = us;
    TIM2->CR1 |= TIM_CR1_CEN;
    while (TIM2->CR1 & TIM_CR1_CEN);
    return;
}

void delay_ms( uint16_t ms )
{
    int i;
    for (i=0; i < ms; i++){
        delay_us (1000);
    }
}


Но, что то не работало.

Портировал все на камень stm32f217 и добавил поиск. Теперь все ds18b20 сидят на одном пине (PB0).


#define FALSE 0
#define TRUE  1

uint8_t ROM_NO[8];
uint16_t LastDiscrepancy;
uint16_t LastFamilyDiscrepancy;
uint16_t LastDeviceFlag;
uint8_t crc8;


void RCC_Configuration (void)
{
    RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOB, ENABLE);
	
    RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE);
}

void TIM2_Configuration (void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	
    TIM_TimeBaseStructure.TIM_Period = UINT16_MAX;
    TIM_TimeBaseStructure.TIM_Prescaler = 59;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_Cmd(TIM2, ENABLE);
}

void Delay_US (uint16_t useconds)
{
    TIM2->CNT = 0;
    while((TIM2->CNT) <= useconds);
}

void Delay_MS (uint16_t mseconds)
{
    uint16_t i;
    for(i=0; i<=(mseconds - 1); ++i)
    Delay_US (1000);  
}

void Set_Port_input (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

void Set_Port_output (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

void Set_Port_Up (void)
{
    GPIOB->BSRRL = GPIO_Pin_0;
}

void Set_Port_Down (void)
{
    GPIOB->BSRRH = GPIO_Pin_0;
}

uint8_t ow_reset (void)
{
    uint8_t ret = 10;

    Set_Port_output ();
    Set_Port_Down ();
    Delay_US(600);
    Set_Port_input ();
    Delay_US(80);
    if(GPIOB->IDR & GPIO_Pin_0)
        {
            ret = 0;
	}
    else
	{
            ret = 1;
	}
    Delay_US (400);
    return ret;
}

void ow_write_bit (uint8_t bit)
{
    if (bit)
        {
            Set_Port_output ();
            Set_Port_Down ();
            Delay_US (10);
            Set_Port_Up ();
            Delay_US (49);
	}
    else
	{
            Set_Port_output ();
            Set_Port_Down ();
            Delay_US (59);
            Set_Port_Up ();
	} 
}

uint8_t ow_read_bit (void)
{
    uint8_t ret = 10;

    Set_Port_output ();
    Set_Port_Down ();
    Delay_US (5);
    Set_Port_input ();
    Delay_US (10);
    if (GPIOB->IDR & GPIO_Pin_0)
	{
            ret = 1;
	}
    else
	{
            ret = 0;
	}
    Delay_US (44);
    return ret;	
}

uint8_t ow_read_byte (void)
{
    uint8_t i;
    uint8_t byte=0;

    for (i=0;i<8;i++)
	{
            if(ow_read_bit ()) byte |= (0x01<<i);
            Delay_US (1);
	}
    return(byte);
}

void ow_write_byte (uint8_t byte)
{
    uint8_t a;
    uint8_t temp;

    for(a=0;a<8;a++)
	{
            temp = byte >> a;
            temp &=0x01;
            ow_write_bit (temp);
            Delay_US (1);
	}
}

uint8_t docrc8(uint8_t value)
{
    static uint8_t 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};
			
   crc8 = dscrc_table[crc8 ^ value];
   return crc8;
}


uint16_t ow_search (void)
{
    uint16_t id_bit_number;
    uint16_t last_zero, rom_byte_number, search_result;
    uint16_t id_bit, cmp_id_bit;
    uint8_t rom_byte_mask, search_direction;

  id_bit_number = 1;
  last_zero = 0;
  rom_byte_number = 0;
  rom_byte_mask = 1;
  search_result = 0;
  crc8 = 0;

   if (!LastDeviceFlag)
   {
      if (!ow_reset ())
      {
         LastDiscrepancy = 0;
         LastDeviceFlag = FALSE;
         LastFamilyDiscrepancy = 0;
         return FALSE;
      }
 
      ow_write_byte(0xF0);  

      do
      {
         id_bit = ow_read_bit();
         cmp_id_bit = ow_read_bit();

         if ((id_bit == 1) && (cmp_id_bit == 1))
            break;
         else
         {
            if (id_bit != cmp_id_bit)
               search_direction = id_bit; 
            else
            {
               if (id_bit_number < LastDiscrepancy)
                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
               else
                  search_direction = (id_bit_number == LastDiscrepancy);

               if (search_direction == 0)
               {
                  last_zero = id_bit_number;

                  if (last_zero < 9)
                     LastFamilyDiscrepancy = last_zero;
               }
            }

            if (search_direction == 1)
              ROM_NO[rom_byte_number] |= rom_byte_mask;
            else
              ROM_NO[rom_byte_number] &= ~rom_byte_mask;

            ow_write_bit(search_direction);

            id_bit_number++;
            rom_byte_mask <<= 1;

            if (rom_byte_mask == 0)
            {
                docrc8(ROM_NO[rom_byte_number]); 
                rom_byte_number++;
                rom_byte_mask = 1;
            }
         }
      }
      while(rom_byte_number < 8); 

      if (!((id_bit_number < 65) || (crc8 != 0)))
      {
         LastDiscrepancy = last_zero;

         if (LastDiscrepancy == 0)
            LastDeviceFlag = TRUE;
         
         search_result = TRUE;
      }
   }

   if (!search_result || !ROM_NO[0])
   {
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      search_result = FALSE;
   }
   return search_result;
}

int OWFirst()
{
    LastDiscrepancy = 0;
    LastDeviceFlag = FALSE;
    LastFamilyDiscrepancy = 0;

    return ow_search();
}

int OWNext()
{
    return ow_search();
}



  • 0
  • 26 января 2012, 18:36
  • lexanet

Комментарии (18)

RSS свернуть / развернуть
Понравились функции задержки для STM32, сразу видно что рабочие.)
А вот с таймером скорей всего задержки формируются неправильные, в данный момент не дома, через неделю проверил бы ЛА. Я бы сделал не дрыганье ножек, а использовал UART, компактнее и читабельность лучше.
0
  • avatar
  • pkm
  • 26 января 2012, 19:08
Я не представляю как 20 датчиков подключить к уарту, даже 3-м имеющимся. Пришлось бы разбираться с поиском датчиков на одной линии.
А функции как раз и не мои. Только благодаря им и человеку, который их написал все заработало.
0
В программе для LPC используется один таймер2?
Ну коль используешь 1768 то писать уже функции такого рода: «температура=ПолучитьТемпературу(Номер датчика)» и усе. Места немерено:)
0
  • avatar
  • Zov
  • 26 января 2012, 19:16
код ужасен, вам говорили когда нибудь что существуют циклы, структуры функции?
Вы замечали что у вас многократные повторения одного и того же куска кода?

эта простынь может быть раза в 3 короче и понятно
0
«Только базовые функции, никакой оптимизации или творческого подхода.»
0
Действительно слишком много кода, читабельность не на высоте прямо скажем. Вроде бы и задача не такая уж сложная… Бывает, конечно, пишешь на скорую руку программу, но тут даже самому разбираться потом не захочется. Я вот тоже раньше думал, что неплохо знаю С, а как поглубже копнул, оказалось, что совсем совсем нет)
А можно поинтересоваться, откуда у вас «приличный запас» stm32vldiscovery? И для каких целей?
0
Откуда дровишки? ©…
все знают откуда… (ну во всяком случае это наиболее вероятный случай...)
0
Нет, не халява ;) за свои кровные, в свое время они по 370 р. за штуку в мегаэлектронике были. Взял несколько.
0
Писал с пару месяцев назад под stm32f103 программу, которая каждые 5 секунд опрашивает датчики на линии. Датчики детектируются на стадии инициализации через ручное дерганье ногами. Потом в дело вступает связка из USART, DMA и таймера. Если интересно, могу завтра скниуть рабочий код.
0
В код не вчитывался, потому может чего не понял, но ответьте мне на вопрос: зачем каждый датчик на отдельную ногу? 1-wire ведь держит до кучи датчиков на шине. (У меня на 20 метровом проводе 3 штуки висит, вполне комфортно себя чувствуют.) Может я что-то не так понял?
0
А это что бы каждый датчик опрашивать отдельной функцией было удобно :)
0
Ясно, ну во мне, видимо, режим зануды заговорил: «это ж расточительство, столько ножек тратить!» Но с другой стороны, какое нафиг расточительство, когда МК стоит каких-нибудь 50-100 рублей, удобство гораздо важнее.
Но в моем случае удобство 1 линнии было большее — так как датчики на линии последовательно находятся (топология шина, или кольцо), если бы я тянул отдельные провода к каждому — это было бы пипец как неудобно :) Но для топологии звезда — в самый раз.
0
Именно топология, типа звезда, у меня и будет. Каждый датчик равноудален от центрального модуля. Так намного удобней прокладывать провод по технологическим отверстиям дома и всю коммутацию производить в одном месте.
0
Не читайте весь код. Он абсолютно не интересен и не полезен никому. Это прост обертка к 5 основным функциям: ow_reset_, ow_write_bit_, ow_read_bit_, ow_read_byte_, ow_write_byte_. И настройка пинов. Все остальное чисто чтобы воздух заполнить.
0
Поддерживаю pkm и Egois. Имея такие жирные камни с набортным DMA на UART дрыгать ножками совсем не камильфо. Ознакомьтесь с документом maxim «1w via UART»
0
  • avatar
  • prm
  • 27 января 2012, 07:48
Ознакомлен я с этим документом. Не устраивает. Мне главное — попроще. Задача решена, модуль смонтирован в корпус, осталось проложить проводку к датчикам.
Но, я с удовольствием ознакомлюсь с готовой и рабочей программой поиска 20-и датчиков на одной линии подключенной к уарту stm32f100, если кто нить ее представит.
0
Если попроще, то есть ардуиновская библиотека OneWire, там реализованно сканирование шины.
Потребуется только заменить функции дерганья ногой на ваши макросы.
Правда, библиотека сиплюсплюсная.
Дальше упростить можно применив версию libmaple для Discovery.
Кстати, народ уже портировал libmaple и на F4.
0
Спасибо, посмотрю обязательно.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.