Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-окт-15 21:46

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: 2018-мар-06 11:45 
Не в сети

Зарегистрирован: 2018-мар-02 14:22
Сообщения: 3
Для работы пробовали вычислить частоту прерываний таймера. Сделали стандартную инициализацию, настроили таймер на счет вверх, по прерывания таймера выдаем на выход порта "0" или "1" (по сути формируем меандр).
Код:
volatile uint16_t dd =0;

int main(void)
{          
   CLKCTRL_HSEconfig(CLKCTRL_HSE0_CLK_ON);
   while(CLKCTRL_HSEstatus(CLKCTRL_HSEn_STAT_HSE0_RDY) != SUCCESS){}
      
   //Select PLL0 clk src, PLL0_N, PLL0_Q to get FINT = FIN*(PLLn_N)/(PLLn_Q+1)
   CLKCTRL_CPU_PLLconfig(PLL0, CLKCTRL_PLLn_CLK_SELECT_HSE0div1, 0, 10);//PLLn, SRC, Q, N
   while(CLKCTRL_CPU_PLLstatus(0) != SUCCESS){}         
   CLKCTRL_MAX_CLKSelection(CLKCTRL_MAX_CLK_PLL0);

   //PORT_B      
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_19);
   PORT_InitStructure.PORT_SOE   = PORT_SOE_OUT;
   PORT_InitStructure.PORT_SANALOG  = PORT_SANALOG_DIGITAL;
   PORT_InitStructure.PORT_SPD = PORT_SPD_OFF;   
   PORT_InitStructure.PORT_SPWR = PORT_SPWR_10;
   PORT_Init(PORTB, &PORT_InitStructure);
       
   TIM_CLK_en(TIM1, TIM_CLKdiv1);   
   MDR_TMR1->CNTRL = 0x0;
   MDR_TMR1->PSG = 0x0;
   MDR_TMR1->CNT=0;
   MDR_TMR1->ARR = 100000000;
   MDR_TMR1->IE = (1<<1);
   NVIC_EnableIRQ(TMR1_IRQn);   
   MDR_TMR1->CNTRL = (1<<0)|(1<<1)|(0<<3);
   while (1)
   {

   }
}

void INT_TMR1_Handler()
{   
   if(MDR_TMR1->STATUS==3)
   {
   if(dd==0)
   {
      //PORT_ResetBits(PORTB,PORT_Pin_18);   
      PORTB->RXTX=(1<<19);
      dd=1;
      //for (i=0;i<10000;i++);
      MDR_TMR1->STATUS &= ~(1 << 1);
   }
   else
   {
      //PORT_SetBits(PORTB,PORT_Pin_19);
      PORTB->RXTX=(0<<19);
      dd=0;
      //for (i=0;i<10000;i++);
      MDR_TMR1->STATUS &= ~(1 << 1);
   }
}
   
}

В процессе возникло несколько вопросов.
1. При срабатывании прерывания (MDR_TMR1->STATUS=3), его обработки и сброса статуса, прерывание немедленно срабатывает снова, при этом в новом прерывании поле статуса значение 0х1 (те. на которое сбросили в конце обработки). Однако если в обработке прерывания искусственно ввести задержку или использовать функции для записи в регистр вместо прямой записи, то этого не происходит. С чем это может быть связано.
2. Таким методом измерения получили соотношение частоты тактирования к частоте меандра 1/200, те при 10 МГц опоры максимальная частота меандра 25 КГц (50 КГц частота половины периода, нужно 2 для формирования "0" и "1"), при 100 МГц - 250 КГц. Это верные соотношения, или мы чего-то не учли?
3. Для использования RTOS необходимы дополнительные файлы. "MDR1986VE8T.H" выслали, а вот с файлами "system_MDR1986VE8T.c", "system_MDR1986VE8T.h", "MDR32F9Qx_config.h" сложнее. Возможно ли их получить или же насколько сильно они отличаются от файлов 1986VE1T, возможно ли их переделать или разница в контроллерах слишком большая?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-07 11:13 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 159
Откуда: ПКК "Миландр"
1. Подобный эффект обнаружился недавно на 1986ВЕ92У - сброс таймера занимает некоторое время. Лечится переносом сброса статуса в начало обработчика прерывания таймера, после которого выполнение прочих инструкций дает некоторую задержку. Проверим такое ли поведение на 1986ВЕ8Т.

2. Математику не смотрел.

3. Файл MDR32F9Qx_config.h не нужен для 1986ВЕ8Т, он используется для прочих процессоров. Вместо него используется mdr32f8_config.h который в
C:\Keil_v5\ARM\PACK\Keil\MDR32F8\0.1\Libraries\MDR32F8_StdPeriph_Driver\inc

В файлах system_MDR1986VE8T.c должно быть всего две функции
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);

и переменная extern uint32_t SystemCoreClock

У нас пока нет их реализации, можете сделать реализацию-заглушку под свою используемую частоту по аналогии с 1986VE1T или 1986VE9х.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-07 14:35 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 479
Цитата:
Подобный эффект обнаружился недавно на 1986ВЕ92У - сброс таймера занимает некоторое время.

А поподробнее можно, в errata будет?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-07 17:35 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 159
Откуда: ПКК "Миландр"
Обнаружилось на учебных курсах. Команду сброса статуса выставили последней при выходе из прерывания таймера. Реально сброс статуса еще не произошел в таймере, поэтому возникало вторичное прерывание. Добавление задержки после сброса статуса, либо перенос сброса в начало обработчика решал проблему.

После проверки на различных ревизиях и при разных скоростях работы ядра поведение либо будет подтверждено и сделана запись в errata, либо поведение будет опровергнуто. Наблюдение совсем свежее, валидация пока не проводилась. Возможно в учебном коде были другие проблемы.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-13 11:04 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 159
Откуда: ПКК "Миландр"
Поведение подтвердилось у меня на 1986ВЕ92 и 1986ВЕ8Т. В 1986ВЕ1Т сбоя не обнаружил.

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

Двойное прерывание есть:
Код:
void TimerX_IRQHandler (void) 
{
  IRQCount++;
  MDR_TIMER1->STATUS &= ~TIMER_STATUS_CNT_ARR; 
}


НЕТ двойного прерывания:
Код:
void TimerX_IRQHandler (void) 
{
  MDR_TIMER1->STATUS &= ~TIMER_STATUS_CNT_ARR;
  IRQCount++; 
}

или

void TimerX_IRQHandler (void) 
{
  IRQCount++;
  TIMER_ClearITPendingBit (MDR_TIMER1, TIMER_STATUS_CNT_ARR);
}


Сброс функцией дает необходимую задержку даже при максимальной частоте ядра.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-13 12:56 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1154
Откуда: Тула
EEPROM::Delay может иметь значение в 1986ВЕ1 и прочих

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-13 13:26 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 479
Цитата:
Таймер это периферийный блок и видимо требуется некоторая задержка чтобы реально снять сигнал запроса к NVIC (чтобы этот сигнал не генерировал повторное прерывание). Иными словами, мы успеваем выйти из прерывания раньше, чем таймер успевает снять сигнал запроса на прерывание.

Хм, а могут быть другие периферийные блоки с аналогичным поведением?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-13 13:33 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1154
Откуда: Тула
ЧумА писал(а):
Хм, а могут быть другие периферийные блоки с аналогичным поведением?

- Видишь суслика?
- Нет
- И я не вижу. А он есть.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-13 13:59 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 159
Откуда: ПКК "Миландр"
Цитата:
EEPROM::Delay может иметь значение в 1986ВЕ1 и прочих


В 1986ВЕ9х Delay по умолчанию установлен под частоту 125МГц, я запускался на 80МГц. Про суслика верно, он может и есть, но нужно суметь поймать. Мне не удалось, но вплотную этим не занимался.

Цитата:
Хм, а могут быть другие периферийные блоки с аналогичным поведением?


Кто знает, почему бы нет. На такое поведение не закладывались, это то, что получилось по факту и обнаружилось только сейчас. Реальную причину будут устанавливать разработчики, выше лишь мое предположение, основанное на наблюдаемом поведении.

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-май-15 14:26 
Не в сети

Зарегистрирован: 2018-мар-02 14:22
Сообщения: 3
Пытаемся запустить RTOS2 на данной плате. Создали файлы для настройки частоты (функции SystemCoreClockUpdate и SystemInit).
Выполняем настройку периферии, убеждаемся что все работает. Однако при запуске инициализации RTOS2 (функция osKernelInitialize ) контролер не возвращается из нее. Может кто-то сталкивался с подобным?

Код:
/* Includes ------------------------------------------------------------------*/
#include "MDR1986VE8T.h"
#include "spec.h"

#include "mdr32f8_config.h"
#include "mdr32f8_port.h"
#include "mdr32f8_clkctrl.h"
#include <rtx_os.h>

/* Private typedef -----------------------------------------------------------*/
PORT_InitTypeDef PORT_InitStructure;

/* Private define ------------------------------------------------------------*/
#define VD7 PORT_Pin_16
#define VD8 PORT_Pin_17
#define VD9 PORT_Pin_18
#define VD10 PORT_Pin_19
#define VD11 PORT_Pin_20
#define VD12 PORT_Pin_21
#define VD13 PORT_Pin_22
#define VD14 PORT_Pin_23

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/         
/* Private function prototypes -----------------------------------------------*/
void RTOS_Init(void);
void Thread_Blink(void *argument);
void Blinky(uint32_t VD);
/* rivate functions ---------------------------------------------------------*/
void Delay(__IO uint32_t nCount)
{
  for (; nCount != 0; nCount--);
}

int main(void)
{   
   /* Disable Power-on-Reset control. Hold the RESET button down until operation complete */
   POR_disable();
   /* Allow write to PORT regs */
   KEY_reg_accs();
   
   /* Set CLKCTRL to default */
   CLKCTRL_DeInit();
   
   /* Enable HSE0 clock */
   CLKCTRL_HSEconfig(CLKCTRL_HSE0_CLK_ON);
   
   /* Check HSE success, enable PLL0, check PLL0 success, select MAX_CLK src */
   while(CLKCTRL_HSEstatus(CLKCTRL_HSEn_STAT_HSE0_RDY) != SUCCESS){}
   
   /* Select PLL0 clk src, PLL0_N, PLL0_Q to get FINT = FIN*(PLLn_N)/(PLLn_Q+1) */
   CLKCTRL_CPU_PLLconfig(PLL0, CLKCTRL_PLLn_CLK_SELECT_HSE0div1, 0, 10);//PLLn, SRC, Q, N
      while(CLKCTRL_CPU_PLLstatus(0) != SUCCESS){}
         CLKCTRL_MAX_CLKSelection(CLKCTRL_MAX_CLK_PLL0);   
         
  /* Enable PORTx clk */
   CLKCTRL_PER0_CLKcmd(CLKCTRL_PER0_CLK_MDR_PORTE_EN, ENABLE);
   CLKCTRL_PER0_CLKcmd(CLKCTRL_PER0_CLK_MDR_PORTC_EN, ENABLE);

  /* Configure PORTC pins [16:23] for output */
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_16|PORT_Pin_17|PORT_Pin_18|PORT_Pin_19|
                                                    PORT_Pin_20|PORT_Pin_21|PORT_Pin_22|PORT_Pin_23);
   
  PORT_InitStructure.PORT_SOE    = PORT_SOE_OUT;
  PORT_InitStructure.PORT_SANALOG  = PORT_SANALOG_DIGITAL;
   PORT_InitStructure.PORT_SPD = PORT_SPD_OFF;
   PORT_InitStructure.PORT_SPWR = PORT_SPWR_10;

  PORT_Init(PORTC, &PORT_InitStructure);
   
   /* Configure PORTC pins [18,21,22] for input */   
   PORT_InitStructure.PORT_Pin   = (PORT_Pin_18|PORT_Pin_21|PORT_Pin_22);
   
  PORT_InitStructure.PORT_SOE    = PORT_SOE_IN;
  PORT_InitStructure.PORT_SANALOG  = PORT_SANALOG_DIGITAL;
   PORT_InitStructure.PORT_SPD = PORT_SPD_OFF;
   PORT_InitStructure.PORT_SPWR = PORT_SPWR_10;
   /* irq enable and set active irq level */   
   PORT_InitStructure.PORT_SIE = PORT_SIE_ON;
   PORT_InitStructure.PORT_SIT = PORT_SIT_LOW;

  PORT_Init(PORTE, &PORT_InitStructure);
   
   /* PORTE IRQ enable */   
   NVIC_EnableIRQ(PORTE_IRQn);
   
   PORT_SetBits(PORTC,VD7);
   Delay(5000000);
   PORT_ResetBits(PORTC,VD7);
   
   SystemCoreClockUpdate();
   /*Main cycle*/                           
   RTOS_Init();
   while (1)
   {
      
   }
}

void Blinky(uint32_t VD)
{   
      PORT_SetBits(PORTC, VD);
      Delay(10000);
      PORT_ResetBits(PORTC, VD);
      Delay(10000);
}

void IRQ_PORTE_Handler()
{
  Blinky(VD8);
   PORTE->CIR=0xFFFFFFFF;
}

void RTOS_Init(void)
{
   //ThreadAttr_Ticker
   static const osThreadAttr_t ThreadAttr_Ticker=
      {
    .priority = osPriorityHigh,  // Приоритет потока
    .stack_size = 1000            // Размер стека потока (в байтах)
  };

  // Инициализация ядра ОСРВ
  osKernelInitialize();

  // Создание потока управления бегущей строкой
  osThreadNew(Thread_Blink, NULL, &ThreadAttr_Ticker);

  // Запуск ядра ОСРВ
  osKernelStart();
}

void Thread_Blink(void *argument)
{
  // Основной цикл
  while (1)
  {
    PORT_SetBits(PORTC, VD7);
      osDelay(250);
      //PORT_ResetBits(PORTC, VD7);
      //osDelay(250);

    // Задержка
   
  }
}


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


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

Найти:
Перейти:  
cron
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB