Кто любит RISC в жизни, заходим, не стесняемся.
Ср сен 30, 2020 17:45:43
Почему-то после инициализации системного таймера, и включения его прерываний, у меня улетает в ХардФаулт... (((
Добавлено after 2 minutes 25 seconds:
Отладка показывает, что все Ок, пока не включит прерывания от Систик. И с него уходит на ассемблерную вставку в файле ...md.s
Добавлено after 22 minutes 15 seconds:
ААААааа! все разобрался. Его не надо отдельно включать... Он настроен в функции Систик сам. Без включения отдельного прерывания все заработало.
Добавлено after 36 seconds:
Но вопрос все равно остался. Почему при этой инструкции:
NVIC_EnableIRQ(SysTick_IRQn);
Происходит лажа?
Ср сен 30, 2020 17:51:17
А обработчик прерывания SysTick в наличии?
Ср сен 30, 2020 18:40:57
Да. ) Все работает. ) Светодиоды мигают. ) Как и в первый раз, только теперь не от прерываний RTC, а от прерываний Систик
Вот полный мой код. На всякий случай. (и ДА, я понимаю, что не надо так циклы писать по ожиданиям готовности, и что в обработчике прерывания не надо такую работу делать, но я просто учусь. )
Спойлер
- Код:
# include "stm32f10x.h"
# include <stdint.h>
//# include "KeyBoard.h"
void InitAll (void)
{
//======== Init RTC ===============
/* RCC->APB1ENR |= (RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN); // ON clock для бэкап и повер
PWR->CR |= PWR_CR_DBP; // разрешаем доступ к записи в регистры бэкапдомена
RCC->BDCR |= RCC_BDCR_BDRST; //Сбросить всю Backup область
RCC->BDCR &= ~(RCC_BDCR_BDRST);
RCC->BDCR |= (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_LSE); //Выбрать LSE источник (кварц 32768) и подать тактирование
RCC->BDCR |= RCC_BDCR_LSEON; //Включить LSE
while ((RCC->BDCR & RCC_BDCR_LSERDY) != RCC_BDCR_LSERDY) //Дождаться включения
{
}
while (!(RTC->CRL & RTC_CRL_RTOFF)) //проверить закончены ли изменения регистров RTC перед тем, как писать в регистры RTC
{
}
RTC->CRL |= RTC_CRL_CNF; //Разрешить Запись в регистры RTC (вход в режим конфигурации часов реального времени)
RTC->CRL &= ~(RTC_CRL_SECF); // Сбросить флаг секундного переполнения
RTC->PRLL = 0x7FFF; //Настроить делитель на 32768 (32767+1), чтобы получить 1 секунду.
RTC->CRL &= ~(RTC_CRL_CNF); //Запретить запись в регистры RTC. Обновление всех регистров
while (!(RTC->CRL & RTC_CRL_RTOFF)) //Дождаться окончания записи
{
}
RTC->CRL &= ((uint16_t)~RTC_CRL_RSF); //Синхронизировать RTC (записываем туда ноль)
while((RTC->CRL & RTC_CRL_RSF) != RTC_CRL_RSF) //Дождаться синхронизации
{
}
PWR->CR &= ~(PWR_CR_DBP); //запретить доступ к Backup области
RTC->CRH |= RTC_CRH_SECIE; // Включить прерывания каждую секунду
*/
//======== END Init RTC ===========
//======== Init HSE, PLL, CSS =====
FLASH->ACR |= (FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1); // Сразу включаем задержку для Флеша, т.к. на больших частотах ему плохо работать
RCC->CR |= RCC_CR_HSEON; // Включаем внешний резонатор 8 МГц
while ((RCC->CR & RCC_CR_HSERDY ) != RCC_CR_HSERDY) // Ждем запуска резонатора
{
}
RCC->CFGR |= (RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | RCC_CFGR_ADCPRE_DIV6); // Настраиваем PLL (умножить на 9), включаем тактирование PLL от HSE,делить АЦП на 6
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // Включаем делитель PLL на 2 для шины АВР1, т.к. она не более 32 МГц
RCC->CR |= RCC_CR_PLLON; // Включаем сам PLL
while ((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY) // Ждем готовности PLL
{
}
RCC->CFGR |= RCC_CFGR_SW_PLL; // Включаем тактирование всего в системе!
// RCC->CR |= RCC_CR_CSSON; // Разрешить работу системы защиты HSE.
//======== END Init HSE, PLL, CSS ===================
//======== Init SysTick ===========
#define F_CPU 72000000UL // Тактовая у нас 72МГЦ
SysTick_Config(F_CPU/1000); //1ms
//======== END Init SysTick =======
//======== Init GPIO ==============
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // GPIOA clock enable
GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1 | GPIO_CRL_CNF2 | GPIO_CRL_CNF3 |
GPIO_CRL_CNF4 | GPIO_CRL_CNF5 | GPIO_CRL_CNF6 | GPIO_CRL_CNF7); // 8 pins GPIO Out PP
GPIOA->CRL |= (GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_1 | GPIO_CRL_MODE2_1 | GPIO_CRL_MODE3_1 |
GPIO_CRL_MODE4_1 | GPIO_CRL_MODE5_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_1); // 8 pins out 2 MHz max
//======== END Init GPIO ==========
return;
} // END InitAll
int main (void)
{
InitAll(); // Настраиваем МК
//NVIC_EnableIRQ(RTC_IRQn); // Включаем прерывания по часам реального времени
//NVIC_EnableIRQ(SysTick_IRQn);
GPIOA->BSRR = (GPIO_BSRR_BS0); // Начальное значение в порту (включить первый светодиод)
while (!0)
{
}
}
//===================== IRQ ========
void NMI_Handler(void) // Обработчик NMI вызывается при сбое HSE.
{
/* Сбросить флаг системы контроля CSS */
if (RCC->CIR & RCC_CIR_CSSF) RCC->CIR|=RCC_CIR_CSSC;
}
void RTC_IRQHandler (void)
{
RTC->CRL &= ~(RTC_CRL_SECF); // Clear Flag IRQ
if ((GPIOA->ODR & 0xFF) == 0xFF) // Проверка не стали ли все первые 8 бит порта единицами?
{
GPIOA->ODR &= ~(0xFE); // reset 7 bit
return;
}
else
{
//GPIOA->ODR ^= 0xFF; //revers mask
//GPIOA->ODR += 1;
GPIOA->ODR++;
}
return;
}
volatile unsigned int i=0;
void SysTick_Handler (void)
{
if (i<100)
{
i++;
return;
}
else
{
if ((GPIOA->ODR & 0xFF) == 0xFF) // Проверка не стали ли все первые 8 бит порта единицами?
{
GPIOA->ODR &= ~(0xFE); // reset 7 bit
return;
}
else
{
//GPIOA->ODR ^= 0xFF; //revers mask
//GPIOA->ODR += 1;
GPIOA->ODR++;
}
i=0;
return;
}
}
Добавлено after 42 minutes 50 seconds:Вот нашел ответ... Не знаю, на сколько я его понял. Но типа до черты не надо вызвать прерывания. А после черты надо. )))
https://coderoad.ru/32504654/Cortex-M3- ... ткого-сбояДобавлено after 2 minutes 57 seconds:Перевидите, пожалуйста, еще что такое ZI? И что за Рид Онли дата?
Понятно, что кода во Флеш 1084, переменных - 8
Program Size: Code=1084 RO-data=268 RW-data=8 ZI-data=1632
Ср сен 30, 2020 18:46:20
ZI - zero initialised - память инициализированная нулями. если вы объявляете int i = 0 - вот эти 4 байта будут инициализированы нулями.
RO - read only - память откуда только читают, но не пишут. Может располагаться не в ОЗУ, а во флеш.
Ср сен 30, 2020 18:57:25
Про рид Онли я понимаю, но мне интересно, почему и что туда записано, аж 268 байт? ))))
И сколько в итоге у меня зашивается в МК?
Ср сен 30, 2020 19:39:55
Слегка выпал в осадок увидев вот это __IO uint32_t AFR[2]; Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx? Тем более, что они описаны в хедере CMSIS еще и нормальным способом в дополнение к этому __IO uint32_t AFR[2]. Только вот, IAR при попытке установить и сбросить группы битов в этих регистрах сообщает мне следующее Error[Pe136]: struct "<unnamed>#39" (declared at line 415 of "C:\STM32\I2C\CMSIS\stm32f303xc.h") has no field "AFRL" C:\STM32\I2C\main.c 15
Ср сен 30, 2020 19:46:53
Про рид Онли я понимаю, но мне интересно, почему и что туда записано, аж 268 байт? ))))
И сколько в итоге у меня зашивается в МК?
Есть map-файл. Там вся информация откуда что взялось. Прошивается всё что во флэшь расположено. Это тоже в map видно. Скорее всего 1084 + 268.
БОльшую часть из 268 RO у вас занимает таблица векторов прерываний.
Добавлено after 3 minutes 17 seconds:Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?
"C:\STM32\I2C\CMSIS\stm32f303xc.h"
Можно поправить заголовочный файл, но это не очень хорошо. Проще переступить через себя, написать один раз как обращение к массиву и забыть.
Последний раз редактировалось
VladislavS Ср сен 30, 2020 19:57:00, всего редактировалось 2 раз(а).
Ср сен 30, 2020 19:48:01
А где этот файл лежит? Что-то я перерыл в папках проекта, не увидел... (((
Ср сен 30, 2020 19:54:07
Его генерация выключена по умрлчанию. Ищите галку в настройках проекта (линкера).
Ср сен 30, 2020 19:55:48
Благодарю!
Ср сен 30, 2020 20:16:09
Добавлено after 3 minutes 17 seconds:Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?
"C:\STM32\I2C\CMSIS\stm32f303xc.h"
Можно поправить заголовочный файл, но это не очень хорошо. Проще переступить через себя, написать один раз как обращение к массиву и забыть.
Понятно. Думал, что можно как-то по другому, но раз по другому никак, тогда придется через массив. Походу, для куба и кокоса так сделали. Индусы рулят, чё...
P.S. подумалось, что можно макрос какой-то сотворить. Но, это не с моим никудышным опытом. Буду через массивы.
Чт окт 01, 2020 20:10:55
Прошу подсказать по регистру I2C_CR1 микроконтроллера STM32F3xx. Конкретно по биту SMBUS, который присутствует в регистрах STM32F1xx, STM32F4xx и которого нету в одноименном регистре STM32F303. Найденные в интернетах примеры (и даташит на F103) показывают, что посредством этого бита шина переключается в режим I2C или SMBUS.
Надо так понимать, что в F303 шина по умолчанию работает в режиме I2C и не требует каких либо манипуляций для переключения в этот режим? А режим SMBUS нужно включать отдельно, установкой или сбросом каких то битов? И, после установки бита PE в регистре I2C_CR1 модуль сразу же будет работать как I2C интерфейс?
Чт окт 01, 2020 21:30:55
Слегка выпал в осадок увидев вот это __IO uint32_t AFR[2]; Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?
Как вариант, можно, например, так:
- Код:
#define PIN_AF(PIN, AF) ((uint64_t) (AF) << (4 * (PIN))
*(__IO uint64_t *)&GPIOA->AFR = (
PIN_AF(0, 12) | /* PA0: AF12 -- COMP1_OUT */
PIN_AF(2, 14) | /* PA2: AF14 -- TIM15_CH1 */
PIN_AF(3, 14) | /* PA3: AF14 -- TIM15_CH2 */
PIN_AF(7, 12) | /* PA7: AF12 -- COMP2_OUT */
PIN_AF(9, 4) | /* PA9: AF4 -- I2C1_SCL */
PIN_AF(10, 4) | /* PA10: AF4 -- I2C1_SDA */
#if 0
PIN_AF(13, 0) | /* PA13: AF0 -- SWDIO */
PIN_AF(14, 0) | /* PA14: AF0 -- SWCLK */
#endif
0
);
Чт окт 01, 2020 21:58:17
Прошу подсказать по регистру I2C_CR1 микроконтроллера STM32F3xx. Конкретно по биту SMBUS, который присутствует в регистрах STM32F1xx, STM32F4xx и которого нету в одноименном регистре STM32F303. Найденные в интернетах примеры (и даташит на F103) показывают, что посредством этого бита шина переключается в режим I2C или SMBUS.
Надо так понимать, что в F303 шина по умолчанию работает в режиме I2C и не требует каких либо манипуляций для переключения в этот режим? А режим SMBUS нужно включать отдельно, установкой или сбросом каких то битов? И, после установки бита PE в регистре I2C_CR1 модуль сразу же будет работать как I2C интерфейс?
Да, там только настройки специфические настраиваешь для SMBUS, адрес, девайс или хост режим и прочее
Чт окт 01, 2020 22:22:14
a5021, Oxford, спасибо.
Пт окт 02, 2020 15:53:38
Почему я не могу сделать так? Ругается и выдает две ошибки...
что переменная не объявлена и что ожидается выражение...
for (unsigned int j=1; j<0x0FFF; j++) // Ждем запуска резонатора
{
if((RCC->CR & RCC_CR_HSERDY ) != RCC_CR_HSERDY)
{
//j=0x1FFF;
break;
}
}
Пт окт 02, 2020 16:05:10
Стандарт языка С поставьте повыше.
Пт окт 02, 2020 16:30:39
Еще бы знать , как это сделать... )))
Добавлено after 2 minutes 3 seconds:
Все. Разобрался. В настройках проекта С99
Добавлено after 19 seconds:
Спасибо большое! Век живи, век учись.
Добавлено after 15 minutes 41 second:
Кстати, только что проверил работу CSS. Замкнул кварц послюнявленым пальцем. МК перешел на тактирование от HSI, даже после того, как при инициализации я его выключил. Светодиоды стали моргать медленнее. Но обратно не вернулся на HSE.
Таким образом у БлюПилл нет такого, чтобы опять возобновлялось тактирование, как на других МК, кто-то указывал выше. )))
Пт окт 02, 2020 18:53:57
СКАЗОЧНИК не переключайся на С99. Обьяви как положено в рамках ANSI C
Пт окт 02, 2020 18:59:22
Ну вот... (( Теперь другое советуют...
А как положено? Я читал, что в цикле ФОР можно задавать переменную сразу. Ну, вынесу я ее из цикла, как объявление переменной. А дальше? Я не совсем понимаю, как и что надо там сделать. Мне казалось, что все правильно. Я даже много раз перепроверил.
Добавлено after 41 second:
И в чем будет приемущество?
Добавлено after 1 minute 8 seconds:
Кстати, у меня галочка сейчас стоит на С99. А на ANSI C снята. Но она и была снята.
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.