MPetrovich 6 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба 2 hours ago, MPetrovich said: При попытке записи, микроконтроллер стопорится на этой строчке исполняемого кода. скорее всего, не стопорится, а постоянно выполняет обработчик прерывания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба А под отладчиком посмотреть, что в это время МК делает не судьба? Может он по каким-нибудь причинам в hard fault вылетает, а там у вас мертвый цикл. И watchdog не включен. Не? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MPetrovich 6 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба 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 мутота одна. Потом можно подключить, если потребуется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба 18 минут назад, MPetrovich сказал: У меня нет программатора STLink, я прошиваю по UART через Demonstrator GUI. Что есть hard fault? watchdog я не включаю, чтобы не путал меня. По месту остановки проги я смогу найти где затыка, а с watchdog мутота одна. Потом можно подключить, если потребуется. hard fault - исключение (аварийное прерывание). Компиляторы обычно для него мертвый цикл генерируют. Посмотрите, что вам CooCox там создал. "Прога" не может остановиться Это вам только так кажется, процесс крутится в каком-нибудь цикле. Без отладчика можно долго гадать, а с отладчиком - дело одной минуты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба Вангую опечатку в названии обработчика прерывания TIM4! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MPetrovich 6 18 апреля, 2020 Опубликовано 18 апреля, 2020 (изменено) · Жалоба 1 hour ago, Baser said: "Прога" не может остановиться Это вам только так кажется, процесс крутится в каком-нибудь цикле. Я это понимаю. Вопрос в том, чтобы найти этот цикл. 1 hour ago, Baser said: Без отладчика можно долго гадать, а с отладчиком - дело одной минуты. Ну нет у меня STLinc!!! Приходится исходить из тех технических возможностей, которые имеются на настоящее время. Если Вам не лень, подскажите каким образом можно произвести отладку без STLinc? 1 hour ago, AHTOXA said: Вангую опечатку в названии обработчика прерывания TIM4! :) Нет. Проверял. На TIM2 точно такой же обработчик, они в тексте кода друг за другом идут, а по TIM2 проблем нет никаких. Изменено 18 апреля, 2020 пользователем MPetrovich дополнение Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 18 апреля, 2020 Опубликовано 18 апреля, 2020 · Жалоба 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 может сформировать прерывание, а уж в нем совсем нетрудно вычислить "где стоим". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 7 hours ago, MPetrovich said: Ну нет у меня STLinc!!! Приходится исходить из тех технических возможностей, которые имеются на настоящее время. Если Вам не лень, подскажите каким образом можно произвести отладку без STLinc? Да, можно и без аппаратного отладчика. Для этого разбиваете одну вашу (супер-)функцию инициализации на максимальное число мелких, выполняющих законченные операции инициализации каждого блока. В каждую такую ф-ю включаете код само-проверки с выдачей результата на отладочный UART. Эти блоки кода (c UART) можно включать по #ifdef, только для режима отладки. С более-менее сложным и объемным кодом таким образом никто не работает. Необходимое условие для такого метода - доскональное знание "устройства" процессора и периферии (не знаю, бывает ли такое сейчас, с даташитами-мануалами 500-1500 страниц). Знание языка программирования и настроек компилятора. Так, Вы можете сделать правильно инициализацию для одного периф.узла. Затем все сделать правильно для другого узла. Но при этом "прохлопать" данные из мануала, где указаны возможные коллизии (элементарно не учесть какой-либо "общий" входной-выходной пин итп). А так, без отладчика за 10$, получается "поклейка обоев через замочную скважину". Можно симулятор для отладки использовать. Но это без периферии, скорее всего. 13 hours ago, MPetrovich said: STM32F103T8C6 Проблема в следующем . . . Я конечно сильно извиняюсь, именно "T8C6" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 19 минут назад, k155la3 сказал: Да, можно и без аппаратного отладчика. Для этого разбиваете одну вашу (супер-)функцию инициализации на максимальное число мелких, выполняющих законченные операции инициализации каждого блока. В каждую такую ф-ю включаете код само-проверки с выдачей результата на отладочный UART. Эти блоки кода (c UART) можно включать по #ifdef, только для режима отладки. Это примерно то же самое, что в наше время добывать огонь при помощи трения двух палочек и трута, экономя на спичках. Хотя.... может ТС так и делает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 4 minutes ago, jcxz said: . . . экономя на спичках. Спички ... ? Кууууу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 13 hours ago, MPetrovich said: Ну нет у меня STLinc!!! На али стоит копейки. Закажите, хотя бы на будущее. Очень нужная штука в некоторых щекотливых моментах. Конечно, лучше взять серьёзный агрегат. Например, J-Link, Jet-Link. Ну это сразу в райне 8 т.р. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 1 час назад, haker_fox сказал: Конечно, лучше взять серьёзный агрегат. Например, J-Link, Jet-Link. Ну это сразу в райне 8 т.р. Чем лучше? Лежит у меня пара клонов (10-летних, один лично коллега DASM из рук в руки передал), именно лежит, для работы со старыми проектами на ARM7TDMI, которые не умеют swd. С Кортексами st-linkа или его клона с али "для дома, для семьи" - выше головы хватает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 1 hour ago, Сергей Борщ said: Чем лучше? Я имел в виду лучше китайского. Хоть ST-Link. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 апреля, 2020 Опубликовано 19 апреля, 2020 · Жалоба 3 hours ago, Сергей Борщ said: Чем лучше Во-первых, скорость работы у сеггеровских отладчиков повыше. Секунда-другая разницы, но всё равно приятно. А во-вторых, RTT - прямо таки гениальная штука. К сожалению, в OpenOCD поддерживается только с бубном (есть pull request, не влитый в основную ветку. Как его собрать под винду, я разобраться не смог). Соответственно, ST-Link тут проигрывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться