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

STM32F103 не пишет в TIM4->DIER

STM32F103T8C6  Проблема в следующем:
После исполнения фукнкции PWM_Config(); невозможно записать ничего кроме "0" или "1" в регистр TIM4->DIER(TIM4 DMA/Interrupt enable register). При попытке записи, 
микроконтроллер стопорится на этой строчке исполняемого кода.
Проверка производилась посредством вызова функции Usart1_Send_String("ххх"), что отображалось в терминале появлением соответствующей строки текста. После PWM_Config(); программа стопорится и больше никаких строк в терминале не отображается.

void PWM_Config(void)
 {
  // TIM Configuration
  //Включаем тактирование порта В и альтернативных функций
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //тактирование порта А
  //Разрешаем такрирование TIM2, TIM4.
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM4, ENABLE);

  GPIO_InitTypeDef  GPIO_InitStruct;

  //готовим ноги порта B(РВ6, РВ7, РВ8, РВ9)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Режим альтернативной функции
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
  //готовим ноги порта A(РA0, РA1)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Режим альтернативной функции
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStruct);

  TIM_InternalClockConfig(TIM2); //Disable slave mode. Prescaler directly from internal clock
  TIM_InternalClockConfig(TIM4);

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
  //Устанавливаем прескалер
  TIM_TimeBaseStruct.TIM_Prescaler = 71; //PSC-Регистр: на сколько делится TIM_CLK
  //устанавливаем период ШИМ 100 usec(10kHz)
  TIM_TimeBaseStruct.TIM_Period = 99;  //ARR регистр: кол-во тактов в периоде(после прескалера)
  //Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))
  //72000000/((71+1)*(99+1)*(0+1))=10000Гц
  //TIM_CLK = timer clock input
  //PSC = 16-bit prescaler register
  //ARR = 16/32-bit Autoreload register
  //RCR = 16-bit repetition counter по дефолту RCR=0

  //CR1: TIM_ClockDivision - аппартный делитель TIM_CLK=SystemCoreClock/CR1
  //по дефолту: TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
  //#define TIM_CKD_DIV1  (uint16_t)0x0000
  TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;  //CR1 регистр TIM_CKD_DIV2=100
  //bit repetition counter по дефолту RCR=0
  TIM_TimeBaseStruct.TIM_RepetitionCounter = 0x0000;  //RCR регистр
  //считаемм вверх от 0 до 999
  TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
  //собственно инициализация таймера 1
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);

  TIM_OCInitTypeDef TIM_OCInitStruct;
  //настриваем режим ШИМ1 TIM Output Compare mode
  TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  //Заперещаем вывод ШИМ
  TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  //Полярность ШИМ: пассивный уровень низкий, активный высокий TIM Output Compare Polarity High
  //TIM_OCInitStruct.TIM_OCPolarity =  TIM_OCPolarity_High;//TIM_OCPolarity_Low; //
  //начальная длительность импульса для каналов = 10 мкс, скважность 10/100=0,1(10%)
  TIM_OCInitStruct.TIM_Pulse = 10;//CCRx

  TIM_OC1Init(TIM2, &TIM_OCInitStruct); //инициализация OC1 канала TIM2 = РA0
  TIM_OC2Init(TIM2, &TIM_OCInitStruct); //инициализация OC2 канала TIM2 = РА1

  TIM_OC1Init(TIM4, &TIM_OCInitStruct); //инициализация OC1 канала TIM4
  TIM_OC2Init(TIM4, &TIM_OCInitStruct); //инициализация OC2 канала TIM4
  TIM_OC3Init(TIM4, &TIM_OCInitStruct); //инициализация OC3 канала TIM4
  TIM_OC4Init(TIM4, &TIM_OCInitStruct); //инициализация OC4 канала TIM4

  //Полярность ШИМ
  TIM4->CCER |= 0x0202; //Активный уровень каналов 1, 3 - низкий; 2, 4 - высокий
  TIM2->CCER |= 0x0002; //Активный уровень канала 1 - низкий; 2 - высокий

  //Разрешаем прелоад (запись через временный регистр)
  //For PWM mode is mandatory: TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE);
  TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //1-й канал TIM4 = UL
  TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //2-й канал TIM4 = UH
  TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //3-й канал TIM4 = VL
  TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //4-й канал TIM4 = VH
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //2-й канал TIM2 = WL
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //1-й канал TIM2 = WH

  TIM_ARRPreloadConfig(TIM2, ENABLE);  //Это разрешение прелода для всего TIM2
  TIM_ARRPreloadConfig(TIM4, ENABLE);  //Это разрешение прелода для всего TIM4

   TIM4->DIER = 0; //Все прерывания от TIM4 запрещены.
   TIM2->DIER = 0; //Все прерывания от TIM2 запрещены.
   TIM4->DIER = TIM_DIER_UIE;//Update interrupt enable
   TIM2->DIER = TIM_DIER_UIE;

	 NVIC_EnableIRQ (TIM2_IRQn);
	 NVIC_EnableIRQ (TIM4_IRQn);

  /* TIM4->CCMR1 &= (uint16_t)~0x7070; //000 Ноги каналов 1 и 2 заморожены
   TIM4->CCMR1 |= (uint16_t)0x4040; //100 Ноги каналов 1 и 2 имеют НЕАКТИВНЫЙ уровень
   TIM4->CCMR2 &= (uint16_t)~0x7070; //000 Ноги каналов 3 и 4 заморожены
   TIM4->CCMR2 |= (uint16_t)0x4040; //100 Ноги каналов 3 и 4 имеют НЕАКТИВНЫЙ уровень
*/
  //Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
  TIM_Cmd(TIM2, ENABLE);
  TIM_Cmd(TIM4, ENABLE);
 }

И кусочек main():

int main(void)
{
  // Initialize all sub-systems.
  UART_Init();
  TIM4->DIER = TIM_DIER_UIE;
  Usart1_Send_String("TIM_DIER_UIE\r\n");
  TIM4->DIER |= 0x0002;
  Usart1_Send_String("TIM4->DIER |= 0x0002\r\n");
  PWM_Config();
  TIM4->DIER |= 0x0012;
  Usart1_Send_String("TIM4->DIER |= 0x0002\r\n");
  TIM3_Config();
  ADC_Config();

Среда разработки CooCox 1.7.7

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


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

2 hours ago, MPetrovich said:

При попытке записи, 
микроконтроллер стопорится на этой строчке исполняемого кода.

скорее всего, не стопорится, а постоянно выполняет обработчик прерывания

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


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

А под отладчиком посмотреть, что в это время МК делает не судьба? Может он по каким-нибудь причинам в hard fault вылетает, а там у вас мертвый цикл. И watchdog не включен. Не?

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


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

59 minutes ago, esaulenka said:

скорее всего, не стопорится, а постоянно выполняет обработчик прерывания

Те же самые операции я проделываю с TIM2, однако, только если я отключаю прерывания TIM4 в PWM_Config(),

	 NVIC_EnableIRQ (TIM2_IRQn);
	 //NVIC_EnableIRQ (TIM4_IRQn);

то программа выполняется дальше.

Обработчик прерываний вызывает функцию 

void PWM_OFF_Period(void)
{
  LED_OFF;
//Clear all flags of TIM2 and TIM4
   TIM2->SR = 0;    TIM4->SR = 0;
 //--------------------------------------------------------------------------
 //    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
 //    TIM_ClearFlag(TIM4, TIM_FLAG_Update);
 //--------------------------------------------------------------------------

  uint16_t V_BEMF; //current V_BEMF value
  uint8_t i=0;
  while(i<200)i++; //wait 200 ticks of Core clock ~ 2,8uSec
  ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Start ADC conversion manually
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //Wait while ADC sample complete.
  V_BEMF = ADC_GetConversionValue(ADC1)>>2;//write in  V_BEMF from ADCH;
  Prev_V_BEMF = V_BEMF;
      //Сброс всех битов CCxIE TIM4 и TIM2. Все прерывания запрешены.
    TIM4->DIER = 0;
    TIM2->DIER = 0;
}

 

32 minutes ago, Baser said:

А под отладчиком посмотреть, что в это время МК делает не судьба? Может он по каким-нибудь причинам в hard fault вылетает, а там у вас мертвый цикл. И watchdog не включен. Не?

У меня нет программатора STLink, я прошиваю по UART через Demonstrator GUI. Что есть hard fault?

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

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


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

18 минут назад, MPetrovich сказал:

У меня нет программатора STLink, я прошиваю по UART через Demonstrator GUI. Что есть hard fault?

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

hard fault - исключение (аварийное прерывание). Компиляторы обычно для него мертвый цикл генерируют. Посмотрите, что вам CooCox там создал.

"Прога" не может остановиться :acute: Это вам только так кажется, процесс крутится в каком-нибудь цикле. Без отладчика можно долго гадать, а с отладчиком - дело одной минуты.

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


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

1 hour ago, Baser said:

"Прога" не может остановиться :acute: Это вам только так кажется, процесс крутится в каком-нибудь цикле.

Я это понимаю. Вопрос в том, чтобы найти этот цикл.

 

1 hour ago, Baser said:

Без отладчика можно долго гадать, а с отладчиком - дело одной минуты.

Ну нет у меня STLinc!!! Приходится исходить из тех технических возможностей, которые имеются на настоящее время.

Если Вам не лень, подскажите каким образом можно произвести отладку без  STLinc? 

 

1 hour ago, AHTOXA said:

Вангую опечатку в названии обработчика прерывания TIM4! :)

Нет. Проверял. На TIM2 точно такой же обработчик, они в тексте кода друг за другом идут, а по TIM2 проблем нет никаких.

Изменено пользователем MPetrovich
дополнение

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


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

2 hours ago, MPetrovich said:

while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //Wait while ADC sample complete.

Первый кандидат на комментирование. И в любом случае незачем такими делами заниматься в прерывании.

 

2 hours ago, MPetrovich said:

По месту остановки проги я смогу найти где затыка, а с watchdog мутота одна.

WWDG может сформировать прерывание, а уж в нем совсем нетрудно вычислить "где стоим".

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


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

7 hours ago, MPetrovich said:

Ну нет у меня STLinc!!! Приходится исходить из тех технических возможностей, которые имеются на настоящее время.

Если Вам не лень, подскажите каким образом можно произвести отладку без  STLinc? 

 

Да, можно и без аппаратного отладчика. Для этого разбиваете одну вашу (супер-)функцию инициализации на максимальное число мелких, выполняющих законченные операции инициализации каждого блока. В каждую такую ф-ю включаете код само-проверки с выдачей результата на отладочный UART. Эти блоки кода (c UART) можно включать по #ifdef,  только для режима отладки.  С более-менее сложным и объемным кодом таким образом никто не работает. Необходимое условие для такого метода - доскональное знание "устройства" процессора и периферии (не знаю, бывает ли такое сейчас, с даташитами-мануалами 500-1500 страниц). Знание языка программирования и настроек компилятора. Так, Вы можете сделать правильно инициализацию для одного периф.узла. Затем все сделать правильно для другого узла. Но при этом "прохлопать" данные из мануала, где указаны возможные коллизии (элементарно не учесть какой-либо "общий" входной-выходной пин итп).

А так, без отладчика за 10$, получается "поклейка обоев через замочную скважину"

Можно симулятор для отладки использовать. Но это без периферии, скорее всего.

 

 

13 hours ago, MPetrovich said:

STM32F103T8C6  Проблема в следующем . . . 

Я конечно сильно извиняюсь, именно "T8C6" ?

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


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

19 минут назад, k155la3 сказал:

Да, можно и без аппаратного отладчика. Для этого разбиваете одну вашу (супер-)функцию инициализации на максимальное число мелких, выполняющих законченные операции инициализации каждого блока. В каждую такую ф-ю включаете код само-проверки с выдачей результата на отладочный UART. Эти блоки кода (c UART) можно включать по #ifdef,  только для режима отладки.

Это примерно то же самое, что в наше время добывать огонь при помощи трения двух палочек и трута, экономя на спичках.

Хотя.... может ТС так и делает?  :biggrin:

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


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

4 minutes ago, jcxz said:

. . .  экономя на спичках.

Спички ... ?  Кууууу :beach:

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


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

13 hours ago, MPetrovich said:

Ну нет у меня STLinc!!!

На али стоит копейки. Закажите, хотя бы на будущее. Очень нужная штука в некоторых щекотливых моментах. Конечно, лучше взять серьёзный агрегат. Например, J-Link, Jet-Link. Ну это сразу в райне 8 т.р.

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


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

1 час назад, haker_fox сказал:

Конечно, лучше взять серьёзный агрегат. Например, J-Link, Jet-Link. Ну это сразу в райне 8 т.р.

Чем лучше? Лежит у меня пара клонов (10-летних, один лично коллега DASM из рук в руки передал), именно лежит, для работы со старыми проектами на ARM7TDMI, которые не умеют swd. С Кортексами st-linkа или его клона с али "для дома, для семьи" - выше головы хватает.

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


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

1 hour ago, Сергей Борщ said:

Чем лучше?

Я имел в виду лучше китайского. Хоть ST-Link.

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


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

3 hours ago, Сергей Борщ said:

Чем лучше

Во-первых, скорость работы у сеггеровских отладчиков повыше. Секунда-другая разницы, но всё равно приятно.

А во-вторых, RTT - прямо таки гениальная штука. К сожалению, в OpenOCD поддерживается только с бубном (есть pull request, не влитый в основную ветку. Как его собрать под винду, я разобраться не смог). Соответственно, ST-Link тут проигрывает.

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


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

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

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

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

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

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

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

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

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

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