Jump to content
    

stm32f1 ds18b20 на таймере.

Решил я усложнить задачу на базе stm32f1 на таймере настроить программу для ds18b20. Как правильно это сделать.Я имею ввиду что когда  когда мастер передаёт байт то включается ШИМ.А когда принимает то включается захват по таймеру.Так я понимаю или нет ?

Edited by haker_fox
Автор! Выбирайте внимательнее раздел для темы.

Share this post


Link to post
Share on other sites

хм, мне кажется удобнее на USART и DMA

 

1-Wire USART baudrate USART data
Reset 9600 Кбит/с 0xF0
Bit 1 115200 Кбит/с 0xFF
Bit 0 115200 Кбит/с 0x00

 

Если отправили Reset F0 и приняли F0 значит никого на шине нет

Ну и с чтением бит также, отправили FF, если приняли FF значит 1, иначе 0.

Share this post


Link to post
Share on other sites

В 14.02.2023 в 20:09, dimir сказал:

Решил я усложнить задачу на базе stm32f1 на таймере настроить программу для ds18b20. Как правильно это сделать.Я имею ввиду что когда  когда мастер передаёт байт то включается ШИМ.А когда принимает то включается захват по таймеру.Так я понимаю или нет ?

И прием, и передачу бита инициирует только мастер. Причем/чтение - это по сути запись бита 1, но в ответ может быть получена длительность как для бита 1, так и бита 0.

Т.е. вы одним каналом таймера всегда формируете передачу какой-то длительности нуля на шине, а вторым каналом всегда считываете момент фронта (перехода из нуля в единицу шины) - т.е. длительность нуля на шине, по которой принимаете решение о считанном бите.

 

Share this post


Link to post
Share on other sites

UART, хоть и "народный" метод, но весьма не стабильный. Я бы не советовал никогда делать 1-Wire на UART.

У 1-Wire очень сильно выражены "неопределенности" по временным диаграммам, и на UART могут быть глюки.

Проще ногодрыгом + таймерные захваты/сравнения, ИМХО.

Share this post


Link to post
Share on other sites

Что за неопределенности? При отправке приеме байта махом, используя ДМА, как-то не замечал проблем.

 

Share this post


Link to post
Share on other sites

Тайм-слоты 1-Wire имеют просто громадные разбросы таймингов. И эти тайминги могут не попадать на весьма точные тайминги UART-кадров.

И здесь либо датчик может "не услышать" команд мастера, либо мастер может не увидеть правильные слоты слейва (первое - реже, но также возможно, думаю).

Цитата

как-то не замечал проблем

лишь везение:smile:

Share this post


Link to post
Share on other sites

В 14.02.2023 в 20:37, mitya1698 сказал:

Что за неопределенности? При отправке приеме байта махом, используя ДМА, как-то не замечал проблем.

 

В широком диапазоне температур вместо привычных кодов для 0 и 1 начинают приходить "соседние" значения. Если ПО это сможет учесть, то норм.

Share this post


Link to post
Share on other sites

В 14.02.2023 в 19:35, Arlleex сказал:

UART, хоть и "народный" метод, но весьма не стабильный. Я бы не советовал никогда делать 1-Wire на UART.

У 1-Wire очень сильно выражены "неопределенности" по временным диаграммам, и на UART могут быть глюки.

Проще ногодрыгом + таймерные захваты/сравнения, ИМХО.

это как это ногодрыг+таймер захвата можно помедленей и по подробнее.

Share this post


Link to post
Share on other sites

В 14.02.2023 в 21:27, dimir сказал:

это как это ногодрыг+таймер захвата можно помедленей и по подробнее.

//-----------------------------------------------------------------------------
//	void OW_start(void)
//-----------------------------------------------------------------------------
void OW_start(void)
{
	ow_timeout = 0;

	OW_TIM->CCR1 = OW_START_PULSE - 1;
	OW_TIM->ARR = 1000 - 1;
	OW_TIM->CCMR1 = 0
		|	(OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);
	OW_TIM->CCMR1 = 0
		|	(OC_MODE_SET_INACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);
	OW_TIM->CR1 = (1 << TIM_CR1_OPM) | (1 << TIM_CR1_CEN);

	#ifdef OW_DEBUG
	con_str("[START]");
	con_start();
	#endif
}

//-----------------------------------------------------------------------------
//	void OW_write(const int b)
//-----------------------------------------------------------------------------
void OW_write(const int b)
{
	switch(b)
	{
		case 0:		OW_TIM->CCR1 = OW_BIT_0 - 1;	break;
		case 1:		OW_TIM->CCR1 = OW_BIT_1 - 1;	break;
		default:	return;
	}
	OW_TIM->ARR		= 100;
	OW_TIM->CCR2	= 0;
	OW_TIM->CCMR1 = 0
		|	(OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);
	OW_TIM->CCMR1 = 0
		|	(OC_MODE_SET_INACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);
	OW_TIM->CR1 = (1 << TIM_CR1_OPM) | (1 << TIM_CR1_CEN);
}

//-----------------------------------------------------------------------------
//	void OW_read(void)
//-----------------------------------------------------------------------------
void OW_read(void)
{
	OW_write(1);
}

//-----------------------------------------------------------------------------
//	void OW_IRQ(BYTE x)
//-----------------------------------------------------------------------------
void OW_on_data(int x)
{
	#ifdef OW_DEBUG
	con_push('[');
	con_dec(x);
	con_push(']');
	con_start();
	#endif

	switch(ow_state)
	{
		//*********************************************************
		//	ПОИСК НОВЫХ УСТРОЙСТВ
		//*********************************************************

		//---------------------------------------------------------
		//	OW_STATE_SEARCH
		//---------------------------------------------------------
		case OW_STATE_SEARCH:
			if(OW_COND_START)
			{
				ow_cmd		= OW_CMD_SEARCH_ROM;
				ow_count	= 0;
				ow_state	= OW_STATE_CMD_SEARCH_ROM;
				OW_send();

				// инициализация поиска
			...
}
      
//-----------------------------------------------------------------------------
//	void TIM8_BRK_TIM12_IRQHandler(void)
//-----------------------------------------------------------------------------
void TIM8_BRK_TIM12_IRQHandler(void)
{
	if(TIM12->SR & (1 << TIM_SR_UIF))
	{
		TIM12->SR = ~(1 << TIM_SR_UIF);
		OW_on_data(TIM12->CCR2);
	}
}

      //-----------------------------------------------------------------------------
//	void init_TIMER12(void)
//-----------------------------------------------------------------------------
void init_TIMER12(void)
{
	TIM12->CR1 = 0;
	TIM12->CCER = 0;

	if(rcc_state == RCC_STATE_PLL)
		TIM12->PSC = ((FPLL >> 1) / 1000000) - 1;
	else
		TIM12->PSC = (FHSI / 1000000) - 1;

	TIM12->ARR = 1000;

	TIM12->CCR1 = 2 - 1;
	TIM12->CCMR1 = 0
		|	(OC_MODE_FORCE_INACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);

	TIM12->CCER = (1 << TIM_CCER_CC1E) | (1 << TIM_CCER_CC2E) | (0 << TIM_CCER_CC2P);
	TIM12->DIER = (1 << TIM_DIER_UIE);
	TIM12->CR1 = (0 << TIM_CR1_CEN);
}

/******************************************************************************
 * DEFINE
 *****************************************************************************/
#define OW_BIT_0				(70)
#define OW_BIT_1				(10)

#define OW_START_PULSE			(480)
#define OW_START_MIN			(OW_START_PULSE + 15 + 60)
#define OW_START_MAX			(OW_START_PULSE + 60 + 240)
#define OW_BIT_MIN				(1)
#define OW_BIT_MAX				(20)

#define OW_COND					((OW_BIT_MIN <= x) && (x <= OW_BIT_MAX))
#define OW_COND_START			((OW_START_MIN <= x) && (x <= OW_START_MAX))

Правда, без ногодрыга

Share this post


Link to post
Share on other sites

28 минут назад, adnega сказал:

Правда, без ногодрыга

OW_TIM->CCMR1 = 0
		|	(OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);

Ну конечно)

Share this post


Link to post
Share on other sites

В 14.02.2023 в 20:36, adnega сказал:

Правда, без ногодрыга

Это как это в ШИМе и с прерываниями по таймеру?И при инициализации таймер не включён и не все дефайны показаны

Share this post


Link to post
Share on other sites

В 14.02.2023 в 22:32, dimir сказал:

Это как это в ШИМе и с прерываниями по таймеру?И при инициализации таймер не включён и не все дефайны показаны

Это не ШИМ, а правильнее назвать "сравнение".

В 14.02.2023 в 22:05, Arlleex сказал:
OW_TIM->CCMR1 = 0
		|	(OC_MODE_FORCE_ACTIVE << TIM_CCMR1_OC1M)
		| (1 << TIM_CCMR1_CC2S);

Ну конечно)

)) Ну, как бы таймер ногу дергает, а я только длительность задаю. Хотя, согласен, случай спорный.

Можно сделать чисто TIMER+DMA, но только не для SEARCH_ROM, т.к. там по ходу нужно решения принимать.

Правда, в IRQ для SEARCH_ROM можно данные в буфере DMA успевать подменять...

Share this post


Link to post
Share on other sites

А где же режим захвата по таймеру.Я так понимаю что основные параметры таймера должны прописываться в дефайнах.Где они?

Share this post


Link to post
Share on other sites

В 15.02.2023 в 07:13, dimir сказал:

А где же режим захвата по таймеру.Я так понимаю что основные параметры таймера должны прописываться в дефайнах.Где они?

Я не пользуюсь стандартной библиотекой - у меня своя, но по исходнику все понятно - какие биты в каких регистрах взводить.

В 17.02.2023 в 08:10, dimir сказал:

В прерывание по таймеру не получается .Почему?

Дык, видно же, что прерывание по таймеру используется.

Вам прицепленный исходник понятен?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...