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

Миландр 1986ВЕ1Т

Всем доброго времени суток!

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

Есть Отладочный комплект для микроконтроллера 1986ВЕ1Т. Пытаюсь настроить тактирование камня на частоте 80 МГц (внешний кварц 8 МГц).

Делаю так:

/* Включаем генератор на внешнем кварце (8 МГц) */
RST_CLK_HSEconfig(RST_CLK_HSE_ON);
while (RST_CLK_HSEstatus() != SUCCESS); /* Ждем стабилизации частоты */

/* Настраиваем источник и коэффициент умножения PLL
 * (CPU_C1_SEL = HSE / 1 * 10 = 8 МГц / 1 * 10 = 80 МГц)
 */
RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul10);

/* Включаем PLL, но еще не подключаем к кристаллу (Блок умножения частоты) */
RST_CLK_CPU_PLLcmd(ENABLE); 
while (RST_CLK_CPU_PLLstatus() != SUCCESS); /* Ждем стабилизации */

/* Делитель С3 (CPU_C3_SEL = CPU_C2_SEL) */
RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);

/* На С2 идет с PLL, а не напрямую с С1 (CPU_C2_SEL = PLL) */
RST_CLK_CPU_PLLuse(ENABLE);

/* CPU берет тактирование с выхода С3
 * (HCLK_SEL = CPU_C3_SEL = 80 МГц) 
 */
RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);

Проверить пытаюсь так:

void delay_ms(volatile uint64_t milisec)
{
    milisec *= 80000; /* CLK_CPU = 80 MHz -> 80000 - 1ms */
    while (milisec)
        milisec--;
}

....
  
int main(void)
{
    freq_init(); /* 80 МГц */
    tmr_init();
    
    while(1)
    {
        delay_ms(1000);
    }
}

Еще настраиваю таймер на прерывание каждую миллисекунду (на вход модуля должно быть 80 МГц после настройки частот):

/* Модуль tmr.c */

#define CLOCK_PCLK  RST_CLK_PCLK_TIMER1
#define TIMERn      MDR_TIMER1
#define TIMER_IRQ   TIMER1_IRQn

/* 1 ms */
void tmr_init(void)
{
    TIMER_CntInitTypeDef tmr;
    
    RST_CLK_PCLKcmd(CLOCK_PCLK, ENABLE); /* Тактирование таймера */
    
    /* 80 MHz на вход. Настройка на 1ms */
    tmr.TIMER_ETR_Prescaler     = TIMER_ETR_Prescaler_None; /* Не делить входную частоту */
    tmr.TIMER_Prescaler         = 8000;
    tmr.TIMER_Period            = 10; /* Дойдя до этого значения - перезагружаем таймер */
    tmr.TIMER_CounterMode       = TIMER_CntMode_ClkFixedDir; /* Фиксированное направление счета */
    tmr.TIMER_CounterDirection  = TIMER_CntDir_Up; /* счет вверх */
    tmr.TIMER_ARR_UpdateMode    = TIMER_ARR_Update_On_CNT_Overflow; /* Обновление по переполнению */ 
    tmr.TIMER_IniCounter        = 0;
    
    TIMER_CntInit(TIMERn, &tmr);
    TIMER_ITConfig(TIMERn, TIMER_STATUS_CNT_ZERO | TIMER_STATUS_CNT_ARR, ENABLE);
    NVIC_EnableIRQ(TIMER_IRQ);
    TIMER_Cmd(TIMERn, ENABLE);
}

void TIMER1_IRQHandler(void)
{
    TIMER_ClearFlag(TIMERn, TIMER_STATUS_CNT_ZERO | TIMER_STATUS_CNT_ARR);
    
    led_set(LED_1, led_get(LED_1) ^ 1); /* Блинк светодиодом */
}

Но не получаю частоты 80 МГц даже близко...

Подскажите, возможно, я жестко косячу...

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


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

таймер на прерывание каждую миллисекунду


Светодиод, мерцающий 500 раз в с, на взгляд не отличим от просто светящего. Детский сад, чесслово...

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


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

27 минут назад, Obam сказал:

Светодиод, мерцающий 500 раз в с, на взгляд не отличим от просто светящего.

Может он снимает на камеру 1000 кадров в сек...:wink3:

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


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

Хиханьки да хаханьки это хорошо, а об настройке флэша под немалую тактовую частоту ядра ТС, похоже, даже не задумывался, точнее, не подозревал...

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


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

33 минуты назад, Obam сказал:

Хиханьки да хаханьки это хорошо, а об настройке флэша под немалую тактовую частоту ядра ТС, похоже, даже не задумывался, точнее, не подозревал...

Я обычно начинаю изучение нового МК (и создание проекта для него) с компоновки кода в ОЗУ. Может ТС тоже так делает? Тогда никакая тактовая частота ему не страшна.  :sun_bespectacled:

3 часа назад, Obam сказал:

Светодиод, мерцающий 500 раз в с, на взгляд не отличим от просто светящего. Детский сад, чесслово...

Видимо автор - счастливый обладатель осциллографа. Что в принципе неудивительно, так как никакой нищий радиолюбитель не променяет дешманский народный STM32 на золотой унитаз 1986ВЕ1Т.

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


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

Три (треьим будешь?) телепата... ;-)

Да там и ПиЭльЭля может вне диапазона своего быть (стр. 460 - частота PLL не менее 144 МГц).

Грешно над подневольными издеваться - "военпред" это со стороны забавно, а на самом деле страшно.

А вообще, тема для начинающих-раздела.

Изменено пользователем Obam

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


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

On 7/25/2019 at 11:55 AM, MaksR said:

но там активация аккаунта что-то затягивается... жду ответа от админов форума.

Напишите письмо в техподдержку [email protected] - они в курсе проблемы (не приходит письмо со ссылкой для активации учётной записи), решат её быстро, придёт письмо.

До перехода на тактирование от PLL необходимо  установить требуемую по описанию на МК задержку доступа к флеш-памяти (регистр MDR_EEPROM->CMD). А после - откорректировать режим работы встроенного регулятора напряжения питания ядра и требуемую нагрузку на него (регистр MDR_BKP->REG_0E).

TIMER_ITConfig(TIMERn, TIMER_STATUS_CNT_ZERO | TIMER_STATUS_CNT_ARR, ENABLE);

Зачем разрешили прерывание по обоим событиям? Они всегда следуют друг за другом: сначала СNT==ARR, затем таймер перезагружается нулем и возникает событие CNT==0. Разрешите прерывание только по одному из событий.

Ну и моргать светодиодом в прерывании - это не заметно для глаза ввиду большой частоты. Настройте таймер на прерывание раз в секунду - тогда увидите.

 

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


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

В 26.07.2019 в 19:18, Darth Vader сказал:

Напишите письмо в техподдержку [email protected] - они в курсе проблемы (не приходит письмо со ссылкой для активации учётной записи), решат её быстро, придёт письмо.

До перехода на тактирование от PLL необходимо  установить требуемую по описанию на МК задержку доступа к флеш-памяти (регистр MDR_EEPROM->CMD). А после - откорректировать режим работы встроенного регулятора напряжения питания ядра и требуемую нагрузку на него (регистр MDR_BKP->REG_0E).


TIMER_ITConfig(TIMERn, TIMER_STATUS_CNT_ZERO | TIMER_STATUS_CNT_ARR, ENABLE);

Зачем разрешили прерывание по обоим событиям? Они всегда следуют друг за другом: сначала СNT==ARR, затем таймер перезагружается нулем и возникает событие CNT==0. Разрешите прерывание только по одному из событий.

Ну и моргать светодиодом в прерывании - это не заметно для глаза ввиду большой частоты. Настройте таймер на прерывание раз в секунду - тогда увидите.

 

Darth Vader, огромное спасибо за адекватную помощь и подсказки!

Насчет моргания светодиодом это да, при частоте 1 КГц незаметно ничего, но на данном этапе при моей текущей настройке тактовых частот мерцание происходит где-то с частотой 0,5 Гц, что достаточно заметно глазу, что говорит о том, что настройка тактирования совсем неверна. 

В настройке таймера ошибся, этот момент уже поправил.

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


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

В 25.07.2019 в 23:49, jcxz сказал:

Я обычно начинаю изучение нового МК (и создание проекта для него) с компоновки кода в ОЗУ...

А я при изучении периферии, описывая сразу драйвера регистрового уровня (.c + .h), ввожу описанные в User Manual-е ограничения, например

.h-файл:

Спойлер

#define USE_USB_BLOCK
#define USE_CAN_BLOCK


//#define CLKSRC_SYS_IRCOSC
//#define CLKSRC_SYS_RTCOSC
//#define CLKSRC_SYS_EXTOSC
#define CLKSRC_SYS_PLL0
#ifdef CLKSRC_SYS_PLL0
  //#define CLKSRC_PLL0_IRCOSC
  //#define CLKSRC_PLL0_RTCOSC
  #define CLKSRC_PLL0_EXTOSC
	
  #define PLL0_N 1UL
  #define PLL0_M 12UL
#endif


#ifdef USE_USB_BLOCK
  //#define CLKSRC_USB_PLL0
  #define CLKSRC_USB_PLL1
  #ifdef CLKSRC_USB_PLL0
    #define CLKDIV_USB 6UL
  #elif defined CLKSRC_USB_PLL1
    #define PLL1_M 4UL
  #endif
#endif


#ifdef USE_CAN_BLOCK
  #define CAN_BAUDRATE 125000UL
#endif


#define CLKDIV_CPU   3UL

#define CLKDIV_SC    4UL
#define CLKDIV_PCB   4UL
#define CLKDIV_QEI   4UL
#define CLKDIV_WDT   4UL
#define CLKDIV_RIT   4UL
#define CLKDIV_PWM   4UL
#define CLKDIV_ADC   4UL
#define CLKDIV_DAC   4UL
#define CLKDIV_CAN   4UL
#define CLKDIV_SPI   4UL
#define CLKDIV_I2S   4UL
#define CLKDIV_I2C0  4UL
#define CLKDIV_I2C1  4UL
#define CLKDIV_I2C2  4UL
#define CLKDIV_SSP0  4UL
#define CLKDIV_SSP1  4UL
#define CLKDIV_TIM0  4UL
#define CLKDIV_TIM1  4UL
#define CLKDIV_TIM2  4UL
#define CLKDIV_TIM3  4UL
#define CLKDIV_EXTI  4UL
#define CLKDIV_UART0 4UL
#define CLKDIV_UART1 4UL
#define CLKDIV_UART2 4UL
#define CLKDIV_UART3 4UL
#define CLKDIV_MCPWM 4UL

 

 

.c-файл:

Спойлер

...

#if (defined CLKSRC_SYS_EXTOSC || defined CLKSRC_PLL0_EXTOSC &&\
     outrange(EXTOSC_FREQUENCY, 1000000UL, 25000000UL))
  #error EXTOSC_FREQUENCY must be between 1 and 25MHz
#endif

#ifdef CLKSRC_SYS_IRCOSC
  #define SYSCLK_FREQ IRCOSC_FREQUENCY
#elif defined CLKSRC_SYS_RTCOSC
  #define SYSCLK_FREQ RTCOSC_FREQUENCY
#elif defined CLKSRC_SYS_EXTOSC
  #define SYSCLK_FREQ EXTOSC_FREQUENCY
#elif defined CLKSRC_SYS_PLL0
  #ifdef CLKSRC_PLL0_IRCOSC
    #define PLL0_FIN IRCOSC_FREQUENCY
  #elif defined CLKSRC_PLL0_RTCOSC
    #define PLL0_FIN RTCOSC_FREQUENCY
  #elif defined CLKSRC_PLL0_EXTOSC
    #define PLL0_FIN EXTOSC_FREQUENCY
  #endif
  
  #if (outrange(PLL0_N, 1UL, 256UL))
    #error PLL0_N must be between 1 and 256
  #endif
  #if (PLL0_M < 6UL)
    #error PLL0_M must be greater than or equal to 6
  #endif
  
  #define SYSCLK_FREQ (2UL*PLL0_M*PLL0_FIN/PLL0_N)
  #if (outrange(SYSCLK_FREQ, 275000000UL, 550000000UL))
    #error Output frequency PLL0 is out of range
  #endif
#endif


#ifdef CLKSRC_USB_PLL0
  #ifndef CLKSRC_PLL0_EXTOSC
    #error To use a USB block, the PLL0 input frequency must be taken from an external oscillator
  #endif
  
  #if (CLKDIV_USB != 6UL && CLKDIV_USB != 8UL && CLKDIV_USB != 10UL)
    #error CLKDIV_USB must be equal to 6, 8 or 10
  #elif (SYSCLK_FREQ/CLKDIV_USB != 48000000UL)
    #error The frequency of the USB block is not equal to 48MHz
  #endif
#elif defined CLKSRC_USB_PLL1
  #if (EXTOSC_FREQUENCY != 12000000UL && EXTOSC_FREQUENCY != 16000000UL && EXTOSC_FREQUENCY != 24000000UL)
    #error To use a USB block, EXTOSC_FREQUENCY must be 12, 16 or 24MHz
  #endif
  
  #if (outrange(PLL1_M, 2UL, 4UL))
    #error PLL1_M must be between 2 and 4
  #endif
  
  #define PLL1_P    2UL
  #define PLL1_FREQ (2UL*PLL1_P*PLL1_M*EXTOSC_FREQUENCY)
  #if (outrange(PLL1_FREQ, 156000000UL, 320000000UL))
    #error Output frequency PLL1 is out of range
  #elif (PLL1_FREQ/(2UL*PLL1_P) != 48000000UL)
    #error The frequency of the USB block is not equal to 48MHz
  #endif
#endif


#if (defined CAN_BAUDRATE && CAN_BAUDRATE > 100000UL && (defined CLKSRC_SYS_IRCOSC || defined CLKSRC_PLL0_IRCOSC))
  #error To use a CAN block with BR > 100kb/s, system frequency should not be taken from internal RC-oscillator
#endif


#if (outrange(CLKDIV_CPU, 1UL, 256UL))
  #error CLKDIV_CPU must be between 1 and 256
#elif (SYSCLK_FREQ/CLKDIV_CPU > 100000000UL)
  #error CPU frequency is out of range
#endif

#if (CLKDIV_SC != 1UL && CLKDIV_SC != 2UL && CLKDIV_SC != 4UL && CLKDIV_SC != 8UL)
  #error CLKDIV_SC must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_PCB != 1UL && CLKDIV_PCB != 2UL && CLKDIV_PCB != 4UL && CLKDIV_PCB != 8UL)
  #error CLKDIV_PCB must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_QEI != 1UL && CLKDIV_QEI != 2UL && CLKDIV_QEI != 4UL && CLKDIV_QEI != 8UL)
  #error CLKDIV_QEI must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_WDT != 1UL && CLKDIV_WDT != 2UL && CLKDIV_WDT != 4UL && CLKDIV_WDT != 8UL)
  #error CLKDIV_WDT must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_RIT != 1UL && CLKDIV_RIT != 2UL && CLKDIV_RIT != 4UL && CLKDIV_RIT != 8UL)
  #error CLKDIV_RIT must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_PWM != 1UL && CLKDIV_PWM != 2UL && CLKDIV_PWM != 4UL && CLKDIV_PWM != 8UL)
  #error CLKDIV_PWM must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_ADC != 1UL && CLKDIV_ADC != 2UL && CLKDIV_ADC != 4UL && CLKDIV_ADC != 8UL)
  #error CLKDIV_ADC must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_DAC != 1UL && CLKDIV_DAC != 2UL && CLKDIV_DAC != 4UL && CLKDIV_DAC != 8UL)
  #error CLKDIV_DAC must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_CAN != 1UL && CLKDIV_CAN != 2UL && CLKDIV_CAN != 4UL && CLKDIV_CAN != 6UL)
  #error CLKDIV_CAN must be equal to 1, 2, 4 or 6
#endif
#if (CLKDIV_SPI != 1UL && CLKDIV_SPI != 2UL && CLKDIV_SPI != 4UL && CLKDIV_SPI != 8UL)
  #error CLKDIV_SPI must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_I2S != 1UL && CLKDIV_I2S != 2UL && CLKDIV_I2S != 4UL && CLKDIV_I2S != 8UL)
  #error CLKDIV_I2S must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_I2C0 != 1UL && CLKDIV_I2C0 != 2UL && CLKDIV_I2C0 != 4UL && CLKDIV_I2C0 != 8UL)
  #error CLKDIV_I2C0 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_I2C1 != 1UL && CLKDIV_I2C1 != 2UL && CLKDIV_I2C1 != 4UL && CLKDIV_I2C1 != 8UL)
  #error CLKDIV_I2C1 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_I2C2 != 1UL && CLKDIV_I2C2 != 2UL && CLKDIV_I2C2 != 4UL && CLKDIV_I2C2 != 8UL)
  #error CLKDIV_I2C2 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_SSP0 != 1UL && CLKDIV_SSP0 != 2UL && CLKDIV_SSP0 != 4UL && CLKDIV_SSP0 != 8UL)
  #error CLKDIV_SSP0 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_SSP1 != 1UL && CLKDIV_SSP1 != 2UL && CLKDIV_SSP1 != 4UL && CLKDIV_SSP1 != 8UL)
  #error CLKDIV_SSP1 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_TIM0 != 1UL && CLKDIV_TIM0 != 2UL && CLKDIV_TIM0 != 4UL && CLKDIV_TIM0 != 8UL)
  #error CLKDIV_TIM0 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_TIM1 != 1UL && CLKDIV_TIM1 != 2UL && CLKDIV_TIM1 != 4UL && CLKDIV_TIM1 != 8UL)
  #error CLKDIV_TIM1 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_TIM2 != 1UL && CLKDIV_TIM2 != 2UL && CLKDIV_TIM2 != 4UL && CLKDIV_TIM2 != 8UL)
  #error CLKDIV_TIM2 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_TIM3 != 1UL && CLKDIV_TIM3 != 2UL && CLKDIV_TIM3 != 4UL && CLKDIV_TIM3 != 8UL)
  #error CLKDIV_TIM3 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_EXTI != 1UL && CLKDIV_EXTI != 2UL && CLKDIV_EXTI != 4UL && CLKDIV_EXTI != 8UL)
  #error CLKDIV_EXTI must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_UART0 != 1UL && CLKDIV_UART0 != 2UL && CLKDIV_UART0 != 4UL && CLKDIV_UART0 != 8UL)
  #error CLKDIV_UART0 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_UART1 != 1UL && CLKDIV_UART1 != 2UL && CLKDIV_UART1 != 4UL && CLKDIV_UART1 != 8UL)
  #error CLKDIV_UART1 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_UART2 != 1UL && CLKDIV_UART2 != 2UL && CLKDIV_UART2 != 4UL && CLKDIV_UART2 != 8UL)
  #error CLKDIV_UART2 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_UART3 != 1UL && CLKDIV_UART3 != 2UL && CLKDIV_UART3 != 4UL && CLKDIV_UART3 != 8UL)
  #error CLKDIV_UART3 must be equal to 1, 2, 4 or 8
#endif
#if (CLKDIV_MCPWM != 1UL && CLKDIV_MCPWM != 2UL && CLKDIV_MCPWM != 4UL && CLKDIV_MCPWM != 8UL)
  #error CLKDIV_MCPWM must be equal to 1, 2, 4 or 8
#endif

...

 

 

В .h-файле у меня некий конструктор параметров (для драйвера настройки синхронизации это, например, что от чего тактируется и т.д.).

В .c-файле эти параметры проверяются в соответствии с выбранными режимами и т.д.

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

Такие "области допустимых значений", при изучении периферии, пишутся налету и особых проблем не доставляют, зато потом, ИМХО, избавляют от детских косяков (всех тонкостей-то не упомнить):wink2:

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


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

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

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

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

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

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

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

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

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

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