Перейти к содержанию
    

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хм, мне кажется удобнее на 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Цитата

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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))

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Ну конечно)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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 успевать подменять...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...