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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

-Og -- это все равно оптимизация и в таких ситуациях лучше запретить вовсе. Следующий шаг -- максимальные варнинги. Я любопытства ради загнал в кейл и там полезли разные вырвиглазные, по мнению компиля, шедевры, типа такого:

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

void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode)
{  							  
    ...	
	uint16_t write[size][size==12?6:8];

    ...
        ST7735_FillRGBRect(&st7735_pObj,x0,y0,(uint8_t *)&write,size==12?6:8,size);
    ...

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

Сообщение WiseLord »

Меня сильно смущает ещё одна вещь. Берём практически любую функцию в LCD.c, например, lcd_senddata
https://github.com/WeActTC/MiniSTM32H7x ... lcd.c#L312

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

result =HAL_SPI_Transmit(SPI_Drv,pdata,length,100);
LCD_CS_SET;
result /= -result;
Это что же, деление нуля на нуль получается? В случае, если HAL-овская функция ОК вернёт?
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Где вы такой индусокод находите?
Зачем вообще, будучи в трезвом уме, пользоваться калом?
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Правильно ли я понимаю вот это выражение:

#define RTC ((RTC_TypeDef *) RTC_BASE)

Здесь создается указатель RTC_BASE типа структуры RTC_TypeDef и сразу же объявляется для него новое имя попроще RTC?

А здесь:

#define RTC_BASE (APB1PERIPH_BASE + 0x2800)

Указывается, что есть некоторый адрес, который принадлежит шине АРВ1 плюс смещение к нему, получается адрес начала регистров RTC в памяти. И объявляется это все для простоты под одним именем RTC_BASE?

После все этого, т.к. структура была объявлена через ТейпДеф, я могу использовать оператор (->), так и оператор (.)?
Станислав
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

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

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

Точно! Это же директивы препроцессора... А не объявления переменных

Добавлено after 7 minutes 10 seconds:
Мне потихоньку начинает казаться, что я уже на грани просветления фундамента по работе с этими микроконтроллерами... Все мои проблемы только с языком Си.

Добавлено after 1 minute 56 seconds:
По сути, если разобраться с тем, что написано в этом заголовочном файле и как это работает, больше вопросов и не останется, кроме некоторых нюансов в Рефренс Мануале.
Станислав
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Понимаю, что можно все и проверить в железе... Но спросить все равно гложит...
Правильно ли я настроил тактирование от внешнего кварца 8 МГц, чтобы с ФАПЧ получилось 72 МГц? Или я где-то чего-то не учел и накосячил?

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

	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_PLLMULL_2 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLSRC); // Настраиваем PLL (умножить на 9) и включаем тактирование PLL от HSE
	RCC->CR |= RCC_CR_PLLON; // Включаем сам PLL
	while ((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY) // Ждем готовности PLL
	{
	}
	RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // Включаем делитель PLL на 2 для шины АВР1, т.к. она не более 32 МГц
	RCC->CFGR |= RCC_CFGR_SW_PLL; // Включаем тактирование всего в системе! 

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

Сообщение VladislavS »

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

// Настройка FLASH
FLASH->ACR = FLASH_ACR_PRFTBE | _VAL2FLD(FLASH_ACR_LATENCY, 2);

RCC->CR = _VAL2FLD(RCC_CR_HSITRIM, 16) 
        | RCC_CR_HSION 
        | RCC_CR_HSEON;   //Включаем HSE
while(!(RCC->CR & RCC_CR_HSERDY));  //Ждём пока запустится HSE
//Задаём источники тактирования и прескалеры 
// SYSCLK = 72 МГц, USB = 48 МГц, 
// PCLK1 = 36 МГц, PCLK2 = 72 МГц,  
// ADC = 12 МГц  
RCC->CFGR = RCC_CFGR_MCO_NOCLOCK 
          | RCC_CFGR_USBPRE_1d5 
          | RCC_CFGR_PLLMULL9 
          | RCC_CFGR_PLLSRC_HSE 
          | RCC_CFGR_ADCPRE_DIV6   
          //|  RCC_CFGR_PLLXTPRE  // Раскомментировать для кварца 16 МГц
          | RCC_CFGR_PPRE2_DIV1 
          | RCC_CFGR_PPRE1_DIV2 
          | RCC_CFGR_HPRE_DIV1 
          | RCC_CFGR_SW_HSE;
RCC->CR = _VAL2FLD(RCC_CR_HSITRIM, 16) 
        | RCC_CR_HSEON 
        | RCC_CR_PLLON;   // Включаем PLL, выключаем HSI
while(!(RCC->CR & RCC_CR_PLLRDY));  // Ждём пока запустится PLL
//Переключаемся на PLL с установленнными ранее прескалерами
RCC->CFGR = RCC_CFGR_MCO_NOCLOCK 
          | RCC_CFGR_USBPRE_1d5 
          | RCC_CFGR_PLLMULL9 
          | RCC_CFGR_PLLSRC_HSE 
          | RCC_CFGR_ADCPRE_DIV6 
          //| RCC_CFGR_PLLXTPRE // Раскомментировать для кварца 16 МГц
          |  RCC_CFGR_PPRE2_DIV1 
          | RCC_CFGR_PPRE1_DIV2 
          | RCC_CFGR_HPRE_DIV1 
          | RCC_CFGR_SW_PLL;
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

А откуда вы взяли вот такие конструкции?

_VAL2FLD(FLASH_ACR_LATENCY, 2

И если я пока не использую ЮСБ и АЦП, мне их все равно надо настраивать? :dont_know:

Добавлено after 1 minute 15 seconds:
И похоже, я зря везде понаписал |=

Добавлено after 8 minutes 48 seconds:
дА, и HSI я не выключил... Или это не обязательно?
Станислав
Друг Кота
Аватара пользователя
Сообщения: 6616
Зарегистрирован: Сб янв 28, 2006 22:47:24

Сообщение Asmodey »

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

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

Понял. Лучше отключить.
А верхние конструкции? и почему у меня работает также запущенный RTC, где я тоже писал |=, а не просто =?

Добавлено after 14 minutes 52 seconds:
Кстати, я не включил CSS... Тоже надо доделать.
А если я выключу HSI и в случае сбоя HSE сам CSS включит его или нет?
Станислав
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

|= это чтение-модификация-присвоение
= прямое присвоение

Использование каждого из вариантов зависит от ситуации.

Есть еще такая разновидность 1-го варианта:

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

REGISTER = (REGISTER & ~(MASK_1 | MASK_2)) | (MASK_3 | MASK_4);
Это если нужно обнулить биты масок 1 и 2, а биты масок 3 и 4 выставить.

Добавлено after 9 minutes 35 seconds:
Кстати, хорошо бы "ожидание запуска резонатора" снабдить тайм-аут таймером, чтобы программа не зависла на while в случае проблем с кварцем.

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

unsigned short tot = 5000;  // при необходимости увеличить

while (((RCC->CR & RCC_CR_HSERDY) == 0) && (--tot));  // Ждем запуска резонатора
После этого проверить tot на 0. Если 0, значит HSE не запустился, переходим к плану Б.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Zhuk72",url="/forum/viewtopic.php?p=3898341#p3898341"]

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

unsigned short tot = 5000;  // при необходимости увеличить
[/uquote]Только не unsigned short, а uint32_t. Вы же на 32-битном проце работаете, 16-битная переменная даст лишний код.
Последний раз редактировалось VladislavS Вс сен 27, 2020 15:44:20, всего редактировалось 1 раз.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Так биты, которые обозначены в хидере, они уже сами нужные единички? Их можно просто присваивать? Или все же лучше как маску накладывать? Просто везде вроде их через |= используют...
И по поводу АЦП и ЮСБ, тоже надо сразу частоты на них выставлять?
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Нет никакого лучше/хуже. Есть как правильно в каждом конкретном случае.
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3898534#p3898534"]И по поводу АЦП и ЮСБ, тоже надо сразу частоты на них выставлять?[/uquote]Можно по сто раз дрюкать идин и тот же регистр, а можно сразу записать правильные параметры.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

:dont_know: А как тогда правильно?

Добавлено after 52 seconds:
В случае инициализации внешнего тактитрования от кварца? Как пример выше?
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3898546#p3898546"]Как пример выше?[/uquote]Есть сомнения, что я правильный пример выложил?
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

я не совсем понимаю, откуда там вот такие штучки:

_VAL2FLD(RCC_CR_HSITRIM, 16), что они обозначают, т.к. я их не нашел в хидере....
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3898558#p3898558"]_VAL2FLD(RCC_CR_HSITRIM, 16), что они обозначают,[/uquote]Это макрос из CMSIS. Не знаю ни одной IDE, где по ПКМ не было бы "показать/перейти к определению".
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Блин. Точно. он в коре.Х сидит.... Спасибо. )
Станислав
Ответить

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