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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Почему-то после инициализации системного таймера, и включения его прерываний, у меня улетает в ХардФаулт... (((

Добавлено after 2 minutes 25 seconds:
Отладка показывает, что все Ок, пока не включит прерывания от Систик. И с него уходит на ассемблерную вставку в файле ...md.s

Добавлено after 22 minutes 15 seconds:
ААААааа! все разобрался. Его не надо отдельно включать... Он настроен в функции Систик сам. Без включения отдельного прерывания все заработало.

Добавлено after 36 seconds:
Но вопрос все равно остался. Почему при этой инструкции:

NVIC_EnableIRQ(SysTick_IRQn);

Происходит лажа?
Станислав
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

А обработчик прерывания SysTick в наличии?
Контактная информация:
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Да. ) Все работает. ) Светодиоды мигают. ) Как и в первый раз, только теперь не от прерываний 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
Станислав
Друг Кота
Аватара пользователя
Сообщения: 7360
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

ZI - zero initialised - память инициализированная нулями. если вы объявляете int i = 0 - вот эти 4 байта будут инициализированы нулями.
RO - read only - память откуда только читают, но не пишут. Может располагаться не в ОЗУ, а во флеш.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Реклама
Эиком - электронные компоненты и радиодетали
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Про рид Онли я понимаю, но мне интересно, почему и что туда записано, аж 268 байт? ))))

И сколько в итоге у меня зашивается в МК?
Станислав
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6542
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

Слегка выпал в осадок увидев вот это __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
Астролябия-сама меряет, было бы что мерять!!!
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3899968#p3899968"]Про рид Онли я понимаю, но мне интересно, почему и что туда записано, аж 268 байт? ))))

И сколько в итоге у меня зашивается в МК?[/uquote]

Есть map-файл. Там вся информация откуда что взялось. Прошивается всё что во флэшь расположено. Это тоже в map видно. Скорее всего 1084 + 268.

БОльшую часть из 268 RO у вас занимает таблица векторов прерываний.

Добавлено after 3 minutes 17 seconds:
[uquote="Asmodey",url="/forum/viewtopic.php?p=3899989#p3899989"]Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?

"C:\STM32\I2C\CMSIS\stm32f303xc.h"[/uquote]Можно поправить заголовочный файл, но это не очень хорошо. Проще переступить через себя, написать один раз как обращение к массиву и забыть.
Последний раз редактировалось VladislavS Ср сен 30, 2020 19:57:00, всего редактировалось 2 раза.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

А где этот файл лежит? Что-то я перерыл в папках проекта, не увидел... (((
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Его генерация выключена по умрлчанию. Ищите галку в настройках проекта (линкера).
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Благодарю!
Станислав
Друг Кота
Аватара пользователя
Сообщения: 6542
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3899996#p3899996"]Добавлено after 3 minutes 17 seconds:
[uquote="Asmodey",url="/forum/viewtopic.php?p=3899989#p3899989"]Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?

"C:\STM32\I2C\CMSIS\stm32f303xc.h"[/uquote]Можно поправить заголовочный файл, но это не очень хорошо. Проще переступить через себя, написать один раз как обращение к массиву и забыть.[/uquote]
Понятно. Думал, что можно как-то по другому, но раз по другому никак, тогда придется через массив. Походу, для куба и кокоса так сделали. Индусы рулят, чё...
P.S. подумалось, что можно макрос какой-то сотворить. Но, это не с моим никудышным опытом. Буду через массивы.
Астролябия-сама меряет, было бы что мерять!!!
Друг Кота
Аватара пользователя
Сообщения: 6542
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

Прошу подсказать по регистру I2C_CR1 микроконтроллера STM32F3xx. Конкретно по биту SMBUS, который присутствует в регистрах STM32F1xx, STM32F4xx и которого нету в одноименном регистре STM32F303. Найденные в интернетах примеры (и даташит на F103) показывают, что посредством этого бита шина переключается в режим I2C или SMBUS.

Надо так понимать, что в F303 шина по умолчанию работает в режиме I2C и не требует каких либо манипуляций для переключения в этот режим? А режим SMBUS нужно включать отдельно, установкой или сбросом каких то битов? И, после установки бита PE в регистре I2C_CR1 модуль сразу же будет работать как I2C интерфейс?
Астролябия-сама меряет, было бы что мерять!!!
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="Asmodey",url="/forum/viewtopic.php?p=3899989#p3899989"]Слегка выпал в осадок увидев вот это __IO uint32_t AFR[2]; Как бы мне это обойти и обратиться к сдвоенным регистрам ARFH и ARFL как обычно GPIOB->AFRx?[/uquote]
Как вариант, можно, например, так:

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

#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
);
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

[uquote="Asmodey",url="/forum/viewtopic.php?p=3900500#p3900500"]Прошу подсказать по регистру I2C_CR1 микроконтроллера STM32F3xx. Конкретно по биту SMBUS, который присутствует в регистрах STM32F1xx, STM32F4xx и которого нету в одноименном регистре STM32F303. Найденные в интернетах примеры (и даташит на F103) показывают, что посредством этого бита шина переключается в режим I2C или SMBUS.

Надо так понимать, что в F303 шина по умолчанию работает в режиме I2C и не требует каких либо манипуляций для переключения в этот режим? А режим SMBUS нужно включать отдельно, установкой или сбросом каких то битов? И, после установки бита PE в регистре I2C_CR1 модуль сразу же будет работать как I2C интерфейс?[/uquote]

Да, там только настройки специфические настраиваешь для SMBUS, адрес, девайс или хост режим и прочее
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6542
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

a5021, Oxford, спасибо.
Астролябия-сама меряет, было бы что мерять!!!
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Почему я не могу сделать так? Ругается и выдает две ошибки...
что переменная не объявлена и что ожидается выражение...


for (unsigned int j=1; j<0x0FFF; j++) // Ждем запуска резонатора
{
if((RCC->CR & RCC_CR_HSERDY ) != RCC_CR_HSERDY)
{
//j=0x1FFF;
break;
}
}
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Стандарт языка С поставьте повыше.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Еще бы знать , как это сделать... )))

Добавлено after 2 minutes 3 seconds:
Все. Разобрался. В настройках проекта С99

Добавлено after 19 seconds:
Спасибо большое! Век живи, век учись.

Добавлено after 15 minutes 41 second:
Кстати, только что проверил работу CSS. Замкнул кварц послюнявленым пальцем. МК перешел на тактирование от HSI, даже после того, как при инициализации я его выключил. Светодиоды стали моргать медленнее. Но обратно не вернулся на HSE.

Таким образом у БлюПилл нет такого, чтобы опять возобновлялось тактирование, как на других МК, кто-то указывал выше. )))
Станислав
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

СКАЗОЧНИК не переключайся на С99. Обьяви как положено в рамках ANSI C
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Ну вот... (( Теперь другое советуют...
А как положено? Я читал, что в цикле ФОР можно задавать переменную сразу. Ну, вынесу я ее из цикла, как объявление переменной. А дальше? Я не совсем понимаю, как и что надо там сделать. Мне казалось, что все правильно. Я даже много раз перепроверил.

Добавлено after 41 second:
И в чем будет приемущество?

Добавлено after 1 minute 8 seconds:
Кстати, у меня галочка сейчас стоит на С99. А на ANSI C снята. Но она и была снята.
Станислав
Ответить

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