STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 725
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

Сообщение amv2000 »

Здравствуйте! Всех с Крещением!
Пробую запустить RTC на плате STM32 VL Discovery, нашел пример в сети инициализирую, обработчик прерывания есть, в котором светодиод должен загораться и гаснуть раз в секунду. На самом же деле реакции никакой, кто знает, что за напасть?

Код: Выделить всё

/*======================*\
 |                    Подключаем в код содержимое файлов                      |
\*======================*/
#include "stm32f10x.h"                                                    //*!< Файл описания периферии (главный модуль CMSIS)

void initRTC(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
    PWR->CR |= PWR_CR_DBP;
 
    RCC->BDCR |= RCC_BDCR_LSEON;
    while( (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ) ; // Wait for LSERDY = 1 (LSE is ready)
 
    RCC->BDCR |= RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0;
 
    while( (RTC->CRL & RTC_CRL_RTOFF) == 0 ) ; // Poll RTOFF, wait until its value goes to ‘1’
 
    RTC->CRL |= RTC_CRL_CNF;
    RTC->PRLH = 0;
    RTC->PRLL = 0x7FFF;
    /* Use this if you want reinit RTC */
    /* 
     *RTC->CNTH = 0;
     *RTC->CNTL = 1;
     *RTC->ALRH = 0;
     *RTC->ALRL = 0;
     */
 
 
    RTC->CRH = RTC_CRH_SECIE;
    RTC->CRL &= ~RTC_CRL_CNF;
    while(  (RTC->CRL & RTC_CRL_RTOFF) == 0 ) ; // Poll RTOFF, wait until its value goes to ‘1’ to check the end of the write operation.
 
    PWR->CR &= ~PWR_CR_DBP;
 
    /* NVIC_SetPriority & NVIC_EnableIRQ defined in core_cm3.h */
    NVIC_SetPriority (RTC_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
    NVIC_EnableIRQ (RTC_IRQn);
}

void RTC_IRQHandler(void)
{
    if(RTC->CNTL & 1)
        GPIOC->BSRR = GPIO_BSRR_BS8;
    else
        GPIOC->BSRR = GPIO_BSRR_BR8;
    RTC->CRL &= ~0x0F;
}


int main(void) /*------------ Основная программа -----------------------------*/
{
   GPIOC->CRH &= ~(GPIO_CRH_MODE8|GPIO_CRH_CNF8);
   GPIOC->CRH |= GPIO_CRH_MODE8_0; 

   initRTC();

  while (1) /*----------------- Основной цикл --------------------------------*/
  {}; 
}
//======================== 
//                                 Конец файла 
//========================
Всё вопрос снимается, сам недоглядел. Неправильно записал функцию инициализации RTC.
На всякий случай свой код исправил, он рабочий.
Реклама
Родился
Сообщения: 4
Зарегистрирован: Сб янв 18, 2014 15:01:06

Сообщение KVItalik »

Всем привет!
На днях поставил на новую систему Keil. І вот незадача, вилетает непонятная мне ошибка.
....
compiling system_stm32f4xx.c...
system_stm32f4xx.c: error: A1023E: File "C:\Users\???ppData\Local\Temp\pe38-2" could not be opened: No such file or directory
.....
притом ето премер кайла. Я думал, проблема в русских названиях папок, переместил в корень, та же проблема.
В чем может быть проблема и как ее устранить?
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Сообщение Myp3ik »

Вы архив распаковали перед открытием проекта ?

amv2000, а программа случайно не в обработчике прерывания зависает ?
Иван Сусанин - первый полупроводник :solder:
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

KVItalik писал(а): compiling system_stm32f4xx.c...
system_stm32f4xx.c: error: A1023E: File "C:\Users\???ppData\Local\Temp\pe38-2" could not be opened: No such file or directory
Русские буквы в именах каталогов?
Все будет только лучше, в крайнем случае - хуже.
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Аватара пользователя
Сообщения: 725
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

Сообщение amv2000 »

Myp3ik писал(а):а программа случайно не в обработчике прерывания зависает ?
Нет до обработчика даже не доходила, проскакивала инициализация, я вместо initRTC(); записал void initRTC();, исправил все работает.
Реклама
Родился
Сообщения: 4
Зарегистрирован: Сб янв 18, 2014 15:01:06

Сообщение KVItalik »

coredumped писал(а):
KVItalik писал(а): compiling system_stm32f4xx.c...
system_stm32f4xx.c: error: A1023E: File "C:\Users\???ppData\Local\Temp\pe38-2" could not be opened: No such file or directory
Русские буквы в именах каталогов?
Ну тут я запускаю с корня. Но оно ничего не меняет. Ошибка та же. На прошлой системе ошибок не было с ихними проктами. Ни хочу систему переустанавливать :(
Реклама
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

KVItalik писал(а): Ошибка та же.
Ага - в ДНК.
Исправь переменные окружения (Environment variables) TEMP и TMP так, чтоб они не указывали в твой домашний каталог с русскими буквами в имени пользователя.
Например так
TEMP = C:\Temp
TMP = C:\Temp
Каталог Temp не забудь создать в корне диска C
И еще - забывай русские буквы в именах файлов, каталогов, а также имен пользователей.
Все будет только лучше, в крайнем случае - хуже.
Родился
Сообщения: 4
Зарегистрирован: Сб янв 18, 2014 15:01:06

Сообщение KVItalik »

Объясните новичку как?
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

Винда какая?
Вот, например http://answers.microsoft.com/ru-ru/wind ... 95e0bd01d1
Все будет только лучше, в крайнем случае - хуже.
Родился
Сообщения: 4
Зарегистрирован: Сб янв 18, 2014 15:01:06

Сообщение KVItalik »

БОЛЬШОЕ спасибо! помогло!
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

KVItalik писал(а):БОЛЬШОЕ спасибо! помогло!
Не за что. Насчет русских букв запомните - в именах фйлов итп - это зло.
Все будет только лучше, в крайнем случае - хуже.
Опытный кот
Аватара пользователя
Сообщения: 725
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

Сообщение amv2000 »

Добрый вечер!
Кто знает подскажите IAR при компиляции ругается на функцию

Код: Выделить всё

uint32_t RTC_GetCounter_(void)                                                //Получить значение счетчика
{
  return (uint32_t)((RTC->CNTH << 16) | RTC->CNTL);
}
Пишет
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
Не пойму, что не определено, пример рабочий.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Ну парни, ну как же так? Ведь все написано там. Гугл же первой ссылкой выдает страничку IAR с подробным объяснением что это и как с ним поступать.

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
EW targets: All
EW component: C/C++ compiler
Keywords: C code, keywords, SFR, UART
Last update: June 28, 2013

Background
The warning [Pa082] is issued if 2 (or more) of the variables in a C-statment are volatile. The message text "...order of volatile accesses is undefined..." is the central information, i.e. the compiler (following the ANSII standard) can access the variables in an order that is not defined.

Is this a problem , or not...
...well that depends on your application.
Volatile is (typically) used for variables that are accessed from several threads in the application, and for Special Function Register that are the connection in/out of the chip. So you must study the volatile variables that are present in this C-statement and from the usage of these volatile variables decide if you must make a change or not.

How to change
The change is to break up the C-statement, so that each new C-statement holds only one access to a volatile variable.
In this small example the variables internalChannelSelect and ADC are volatile. If so the following C-source will issue the "Warning[Pa082]".

intAnalogSample[internalChannelSelect] = ADC[internalChannelSelect] ;

Then the following change will make the C-source predictable. Note that the temporary variables are NOT volatile.

int i;
int k;
i = internalChannelSelect;
k = ADC;
intAnalogSample = k;
Опытный кот
Аватара пользователя
Сообщения: 725
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

Сообщение amv2000 »

Да что то не сообразил сразу, чего от меня хотят. Спасибо за подсказку победил так.

Код: Выделить всё

uint32_t RTC_GetCounter_(void)                                                //Получить значение счетчика
{
  int RTC_CNTH = RTC->CNTH ;
  int RTC_CNTL =  RTC->CNTL ;             
  return (uint32_t)((RTC_CNTH << 16) | RTC_CNTL);                             /*(uint32_t)((RTC->CNTH << 16) | RTC->CNTL);*/
}
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

amv2000 писал(а):

Код: Выделить всё

uint32_t RTC_GetCounter_(void)                                                //Получить значение счетчика
{
  int RTC_CNTH = RTC->CNTH ;
  int RTC_CNTL =  RTC->CNTL ;             
  return (uint32_t)((RTC_CNTH << 16) | RTC_CNTL);                             /*(uint32_t)((RTC->CNTH << 16) | RTC->CNTL);*/
}
Можете нарваться на ошибку, тк операция не атомарная. В тот момент, когда происходит чтение RTC->CNTL возможна ситуация переполнения (обнуления) этого счетчика и Вы получите значение меньше, чем нужно, что (возможно) не совсем приемлемо. Я бы посоветовал перечитать RTC->CNTH после чтения RTC->CNTL и если он изменился, снова перечитать RTC->CNTL.
Или, хотя бы поменяйте чтение регистров местами - сперва RTC->CNTL, затем RTC->CNTH.
UPD: Можно также перед чтением регистров сбросить флаг SECF в регистре RTC_CRL, а после чтения регистров проверить его. Если флаг учтановился, значит за время чтения произошло изменение счетчика RTC, и его следует еще раз перечитать.

Код: Выделить всё

  uint32_t tmp;
               
  RTC->CRL &= ~RTC_CRL_SECF; // clear SECF;
  do
  {
    tmp = RTC->CNTH;
    tmp <<=16;
    tmp |= RTC->CNTL;
  } while(RTC->CRL & RTC_CRL_SECF);
  return tmp;
Последний раз редактировалось coredumped Пн янв 20, 2014 13:27:15, всего редактировалось 1 раз.
Все будет только лучше, в крайнем случае - хуже.
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

Мрак. В AVR и то атомарность доступа к двухбайтным регистрам была обеспечена аппаратно.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

Леонид Иванович писал(а):Мрак. В AVR и то атомарность доступа к двухбайтным регистрам была обеспечена аппаратно.
И как это? Без запрета прерываний, остановки таймеров?
Все будет только лучше, в крайнем случае - хуже.
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

Да, без запрета прерываний и без остановки таймера. Чтение одной половинки регистра таймера вызывает копирование другой в промежуточный регистр. А затем вторая половинка читается из промежуточного регистра. Для программиста это прозрачно, нужно лишь соблюдать последовательность чтения H/L.
Контактная информация:
akl
Друг Кота
Сообщения: 4458
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Леонид Иванович писал(а):соблюдать последовательность чтения H/L
Уточню, L/H при чтении и H/L при записи.
Ответить

Вернуться в «ARM»