Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 22.08.2016, 15:00  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию STM32F103C8T6 Таймер и прерывание по окончании счета

Добрый день!
Хочу запустить таймер с автоматическим перезапуском и выдачей прерывания по окончании счета. Никак не могу получить прерывание. Только начинаю разбираться опыта пока еще ноль. Курение даташита (с моим уровнем английского) не привело ни к какому выводу. Методом тыка попробовал менять параметры, не помогло. Попробовал на основании кода по ШИМ из русскоязычной статьи, но подозреваю что между моментом окончания счета и началом нового цикла должно пройти какое то время, у меня оно равно нулю.

Код:
RCC-›APB1ENR |= RCC_APB1ENR_TIM4EN;//разрешить тактирование таймера от внутренней шины
	TIM2-›PSC = 8-1; //коффициент предделителя 8000000/8=1000000 Гц (1МГц)
	TIM2-›ARR = 1000-1;  //счетчик до 1000 тактов
        TIM2-›CCMR1 =0x00000068; //устанавливаем режим ШИМ
	TIM2-›CCR1 = 0x00000001; //задаем стартовое значение ШИМ
	TIM2-›CCER = 0x00000101; //разрешаем выход канала 1
	TIM2-›DIER = 0x00000011;	//разрешаем обновление прерывания
	TIM2-›EGR = 0x00000001;	//разрешаем обновление
	TIM2-›CNT = 0x00000000;	//какой то регистр без которого возмжно не сработает прерывание
	TIM2-›CR1 = 0x00000086;  
        NVIC_SetPriority (TIM2_IRQn,15);	//назначаем прерывание
	NVIC_EnableIRQ (TIM2_IRQn);	//включаем прерывание
	
	TIM2-›CR1 |= 0x00000001;		//включаем работу таймера


void TIM2_IRQHandler(void)
{
	//TIM2-›CR1 = 0x00000000;
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	//TIM2-›CR1 = 0x00000001;
}
Реклама:
zeon13 вне форума  
Непрочитано 22.08.2016, 15:28  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

Каламбур какой-то. Включаете тактирование четвертого таймера, конфигурируете второй, а флаг прерывания не сбрасываете. Зачем вам шим? Вам только базовый функционал нужен - чтобы CNT инкременировался.
Easyrider83 вне форума  
Непрочитано 22.08.2016, 15:34  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

Спасибо!
Поправил на тактирование 2-го
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;

а каким регистром сбрасывать флаг прерывания?... а так понимаю его надо сбрасывать в теле функции TIM2_IRQHandler()?

В мануале прочитал что режим с автоперезапуском возможен в режиме ШИМ. Поэтому так и перекопипастил
zeon13 вне форума  
Непрочитано 22.08.2016, 15:46  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

У вас дебаг работает? Посмотрите в дебаге, значение CNT увеличивается? В прерывание вы попадаете?
Для кучи спрошу, а тактирование порта включено? Пин на выход настроен?

Последний раз редактировалось Easyrider83; 22.08.2016 в 15:49.
Easyrider83 вне форума  
Сказали "Спасибо" Easyrider83
zeon13 (22.08.2016)
Непрочитано 22.08.2016, 15:54  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

Как то странно получается... Нашел несколько ошибок, исправил,
TIM2-›PSC = 80-1; //коффициент предделителя увеличил в 10 раз.

и дебагом начал смотреть и наблюдать следующее...
1. при переходе на строчку

NVIC_SetPriority (TIM2_IRQn,15);

программа сразу сваливается в функцию TIM2_IRQHandler() при этом CNT=0, отрабатывает её код и возвращается обратно,
2. доходит до строки TIM2-›CR1 |= 0x00000001; CNT становится больше нуля и программа снова уходит в прерывание TIM2_IRQHandler().


Для наглядности ниже весь код программы:


Код:
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "core_cm3.h"
#include "stdint.h"

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
GPIO_InitTypeDef GPIO_InitStructure;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint16_t ADC_Res[6];

void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);

void TIM2_IRQHandler(void);

int main(void)
{
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
 
	//int t=500000;
  while (1)
  {
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
		for(int i=0;i‹10000;i++);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
		for(int i=0;i‹10000;i++);
  }
}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }

}

static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
/*Инициализация портов А как вход АЦП PA0-PA5*/
	GPIO_InitStructure.Pin = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
/*Инициализация порта PB1 как выход для включения светодиода*/	
	GPIO_InitStructure.Pin = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10);
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
	/*  
   * настройка TIM3. Выход триггера при обновлении таймера 
   */ 
	RCC-›APB1ENR |= RCC_APB1ENR_TIM3EN;
	TIM3-›PSC = 80;																	//коффициент предделителя (был 80)
	TIM3-›ARR = 1;                                    //период обновления 1 мс (был 100-1)
  TIM3-›CR2 |= TIM_CR2_MMS_1;                         //выход триггера при обновлении таймера
	
	RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;								//разрешить тактирование таймера от внутренней шины
	TIM2-›PSC = 80-1;																	//коффициент предделителя 8000000/8=1000000 Гц (1МГц)
	TIM2-›ARR = 1000-1;                                    //счетчик до 1000 тактов
  TIM2-›CCMR1 =0x00000068;														//устанавливаем режим ШИМ
	TIM2-›CCR1 = 0x00000001;														//задаем стартовое значение ШИМ
	TIM2-›CCER = 0x00000101;														//разрешаем выход канала 1
	TIM2-›DIER = 0x00000011;														//разрешаем обновление прерывания
	TIM2-›EGR = 0x00000001;															//разрешаем обновление
	TIM2-›CNT = 0x00000000;															//если ›0 то сработало прерывание
	TIM2-›CR1 = 0x00000086;
  
	NVIC_SetPriority (TIM2_IRQn,15);										//назначаем прерывание
	NVIC_EnableIRQ (TIM2_IRQn);													//включаем прерывание
	
	TIM2-›CR1 |= 0x00000001;															//включаем работу таймера
		
	//TIM2-›CR2 |= TIM_CR2_MMS_1;                         //выход триггера при обновлении таймера
	//TIM2-›DIER |= TIM_DIER_UIE;													// разрешение генерации события по достижении значения TIM2-›ARR = 1000 
		
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
/*Инициализация порта PB1 как выход для включения светодиода*/	
	GPIO_InitStructure.Pin = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10);
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	
}
/* ADC1 init function */
static void MX_ADC1_Init(void)
{
	/* ............................ 
     * АЦП, регулярные каналы IN0 - IN5, запуск от TIM3 TRGO, 
     * режим сканирования каналов,  
     * запрос DMA по получению результата канала 
     */ 
    RCC-›APB2ENR |= RCC_APB2ENR_ADC1EN ;// APB2Periph_ADC1; 
    ADC1-›CR2 |= ADC_CR2_ADON;                            //включение модуля АЦП 
    ADC1-›CR1 |= ADC_CR1_SCAN;                            //режим сканирования каналов 
    ADC1-›CR2 |= ADC_CR2_EXTSEL_2 |    ADC_CR2_EXTTRIG |     //триггер запуска от TIM3 TRGO, 
                 ADC_CR2_DMA;                            //разрешено использование DMA 
    ADC1-›SQR1 |= ADC_SQR1_L_0 | ADC_SQR1_L_2;            //число каналов 6 
    ADC1-›SQR3 = 0 |                                    //последовательность 
                 ADC_SQR3_SQ2_0 |                        //каналов 0, 1, 2, 3, 4, 5 
                 ADC_SQR3_SQ3_1 | 
                 ADC_SQR3_SQ4_0 | ADC_SQR3_SQ4_1 | 
                 ADC_SQR3_SQ5_2 | 
                 ADC_SQR3_SQ6_0 | ADC_SQR3_SQ6_2; 
  
}

/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
	  /* ........................... 
     * DMA1, Ch1, 16/16 bit, циклич.буфер, инкремент памяти 
     * Запрос DMA от ADC1, результаты каналов АЦП в регистрах ADC_Res[] 
     */ 
    RCC-›AHBENR |= RCC_AHBENR_DMA1EN;                    //DMA1 затактирован 
    DMA1_Channel1-›CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | //канал 1, 16/16 бит, 
                          DMA_CCR_PSIZE_0 | DMA_CCR_CIRC;     //инкремент памяти, циклич.буфер 
    DMA1_Channel1-›CPAR = (uint32_t)&ADC1-›DR;            //адрес регистра АЦП 
    DMA1_Channel1-›CMAR = (uint32_t)&ADC_Res[0];        //начальный адрес буфера результатов 
    DMA1_Channel1-›CNDTR = 6;                            //кол-во передач по DMA 
    DMA1_Channel1-›CCR |= DMA_CCR_EN;                    //DMA канал 1 включен 
     
//----- Запуск преобразований ------------------------ 
    TIM3-›CR1 |= TIM_CR1_CEN;    //таймер запущен, АЦП запущен, преобразования выполняются 
	}
void TIM2_IRQHandler(void)
{
	//TIM2-›CR1 = 0x00000000;
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	//TIM2-›CR1 = 0x00000001;
	TIM2-›CNT = 0x00000000;	
}

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
  /* User can add his own implementation to report the HAL error return state */
  while(1) 
  {
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
  }
  /* USER CODE END Error_Handler */ 
}


void assert_failed(uint8_t* file, uint32_t line)
{
  
}
Светодиод на PIN_0 срабатывает
Не понятно, почему прерывание срабатывает еще на стадии конфигурации и повторно при запуске таймера?

Последний раз редактировалось zeon13; 22.08.2016 в 16:33.
zeon13 вне форума  
Непрочитано 22.08.2016, 16:41  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

и как то странно в функции прерывания TIM2_IRQHandler(void) строка

TIM2-›CNT = 0x00000000;

не выполняется, пролетает мимо, из-за этого постоянный сброс в эту функцию.
Помогите пожалуйста. моск взрывается, что делать не знаю, вроде все правильно, и в тоже время как то странно работает

Последний раз редактировалось zeon13; 22.08.2016 в 16:43.
zeon13 вне форума  
Непрочитано 22.08.2016, 17:02  
Jeka_T
Частый гость
 
Регистрация: 15.04.2008
Адрес: Йошкар-Ола
Сообщений: 39
Сказал спасибо: 47
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
Jeka_T на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

а флаг прерывания кто сбрасывать будет?
Jeka_T вне форума  
Непрочитано 22.08.2016, 17:30  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

Сообщение от Jeka_T Посмотреть сообщение
а флаг прерывания кто сбрасывать будет?
Код:
void TIM2_IRQHandler(void)
{
	//TIM2-›CR1 = 0x00000000;
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	//TIM2-›CR1 = 0x00000001;
	TIM2-›CNT = 0x00000000;	
}
нет? не этот регистр?
zeon13 вне форума  
Непрочитано 22.08.2016, 17:33  
Jeka_T
Частый гость
 
Регистрация: 15.04.2008
Адрес: Йошкар-Ола
Сообщений: 39
Сказал спасибо: 47
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
Jeka_T на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

TIM2-›SR = (uint16_t)~TIM_IT_Update;
Jeka_T вне форума  
Непрочитано 22.08.2016, 17:55  
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103C8T6 Таймер и прерывание по окончании счета

Сообщение от Jeka_T Посмотреть сообщение
TIM2-›SR = (uint16_t)~TIM_IT_Update;
Спасибо за подсказку.
в моем случае это видимо будет строкой:

TIM2-›SR &= ~TIM_SR_UIF;

Первый раз после инициализации прерывания флаг сбросился на ноль а потом почему то не сбрасывается. Значение SR=0x1E. Валит по циклу функцию прерывания...
Таймер не надо останавливать? Хотя он должен непрерывно крутиться
zeon13 вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прерывание по совпадению таймера 1 gruffi AVR 38 21.10.2016 22:58
stm32 после старта TIM6 сразу прерывание kvark85 ARM 8 04.07.2013 11:22
Задача - таймер. и прерывание! chipic128 Микроконтроллеры, АЦП, память и т.д 11 22.02.2005 18:11


Часовой пояс GMT +4, время: 20:43.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot