здрасьте здрасьте люди добрые. скажите пожалуйста как правильно включить тактирование? МК stm32f103c8. нарыл что порты ввода|вывода расположены на шине APB2. причем все порты. нельзя включить отдельно порт допустим
GPIO A
GPIO B
можно только подать тактирование на шину
APB2
нахожу
RCC_APB2ENR
в этом регистре нахожу бит
IOPC// так как светодиод висит у меня на PC13
и теперь видимо мне нужно его выставить в едниницу.
нахожу в memory map вижу адрес не APB2 а RCC
RCC 0x40021000
и правильно ли я понимаю что теперь чтобы мне включить бит нужно вычислить адрес по формуле
40021000-40000000=offset
(offset*32)+(4*4)
потому что (4*4) IOPC=4 битом
поправте пожалуйста уважаемые форумчане меня. я не совесем понимаю как правильно считать
? Лишняя переменная, ненужные обращения к памяти, ненужное чтение регистра.
Действительно, чем же стандартный общеизвестный способ лучше экзотического. В от так с ходу и не знаю что ответить. Ну, например, то, что поиск по «BB_RCC_APB2ENR_GPIOCEN» в рефмане и заголовочнике ничего не дал. По исправленному имени BB_RCC_APB2ENR_IOPCEN тоже.
Со скрипом можно было принять что-то вроде
BB_SET_BIT( RCC_APB2ENR, RCC_APB2ENR_IOPCEN_Pos )
хотя это все равно выглядит хуже битового сложения.
Ты пойми, что не каждое число магическое. В данном случае ты ставишь бит в единицу. Имя у бита говорит само за себя. Если для тебя это магия… а хотя кому я рассказываю.
Некоторые биты, кстати, сбрасываются, записью в них единицы. Ты тоже их своим магическим «сетом» обнулять будешь?
Лишняя переменная, ненужные обращения к памяти, ненужное чтение регистра
пока один бит надо сбросить или установить BB имеет какой-то смысл, с 2-мя битами преимущества уже сомнительны. Учитывая сколько он адресного пространства отжирает куда полезней специальные регистры _CLEAR и _SET - тут тебе и атомарность и возможность оперировать любыми битами за одну запись и адресное пространства отжирает на порядок меньше.
А что адресное пространство, жалко его что ли? Его там 4 гигабайта. Ну хорошо, если брать начиная с 0x2000’0000, то всего 2 гигабайта. А реальной оперативки десятки килобайт. Ну хорошо, в последних моделях допустим единицы мегабайт. Даже если предположить, что оперативка + периферия занимают 10 МБ - область битбанда будет 10 * 32 = 320 МБ. Даже если на один бит отводить 4 байта, получим чуть больше гигабайта адресного пространства.
куда полезней специальные регистры _CLEAR и _SET
Они не для всей периферии есть, не говоря уж об оперативке. Но вообще да, могли бы для каждого адреса добавить адрес на AND и адрес на OR. А то и вообще установку по маске. Скажем, старшие 16 битов задают маску, младшие - значение.
Но, может, обеспечить альтернативный доступ к памяти было достаточно просто, а то, что я сейчас нафантазировал потребовало бы усложнять топологию.
особенно если он выступает компаньёном 64 битного ядра
Они не для всей периферии есть
это смотря какой процессор, есть такие что у каждого регистра есть расширения для атомарной установки, сброса и переключения любой битовой маски основного регистра
если брать отдельный микроконтроллер то нет, а если гетерогенные SoC то там BB ограничивает адресное пространство микроконтроллерного ядра
Дальше в дебри не полезу. Но вон Эдди говорит, что в младших моделях STM битбанда нет вовсе. Он там жестко прописан в стандарт ARM или это прихоть производителя?
Дальше в дебри не полезу. Но вон Эдди говорит, что в младших моделях STM битбанда нет вовсе. Он там жестко прописан в стандарт ARM или это прихоть производителя?
Действительно, чем же стандартный общеизвестный способ лучше экзотического.
Ахаха. А теперь представь, что между temp = RCC_APB2ENR; и RCC_APB2ENR = temp; произошло прерывание, в котором меняется состояние регистра. Экзотическая тут только твоя неатомарная эквилибристика с левой переменной.
поиск по «BB_RCC_APB2ENR_GPIOCEN» в рефмане и заголовочнике ничего не дал
или вот!
да и сама эта тема, разве она не о том как расчитать адреса? вся тема посвещана этому. и они умудряются говорить что я ничего не спрашивал. ужасные люди.
Ахаха. А теперь представь, что между temp = RCC_APB2ENR; и RCC_APB2ENR = temp; произошло прерывание, в котором меняется состояние регистра.
Если погромист настолько упоролся, чтобы менять регистр тактирования в прерывании без малейшего понимания принципов асинхронного программирования - ССЗБ.
поиск по «BB_RCC_APB2ENR_GPIOCEN» в рефмане и заголовочнике ничего не дал
Я тоже не нашел, так что Ищи лучше. Ты же в этом спец.
40021000-40000000=offset
(offset*32)+(4*4)
потому что (4*4) IOPC=4 битом
поправте пожалуйста уважаемые форумчане меня. я не совесем понимаю как правильно считать
или вот! да и сама эта тема, разве она не о том как расчитать адреса?
Да вроде нет. Она про начало работы с stm32 на ассемблере. Адреса регистров тут особо считать не надо, они в документации прописаны.
А если кто-то хочет решать простую задачу через неприличное место, зачем ему мешать. Что такой способ в реальности практически не используется - предупредили.
будьте добры, скажите еще это магическое число
MAGICK 0x0200`0000
Вам же еще в той теме расписали что это Eddy его придумал для перевода адресов. На самом деле оно не нужно
Если погромист настолько упоролся, чтобы менять регистр тактирования в прерывании
Упоролся тут походу только ты, раз не можешь удержать в голове пару простых сущностей. Мы же говорим не только про регистр тактирования, а про битбанд в целом и его атомарность, в отличие от твоей эквилибристики.
Тролль опять пытается меня подловить? Бесполезно, потому что он не знает, что битбанд - лишь один из способов синхронизации многопоточного кода, далеко не единственный.
Ты на каждый бит будешь свою синхронизацию вставлять? Не спотеешь?
я вам выше привел и ссылки и цитаты где я спрашивал.
сходите пожалуйста уже в другую тему. вы сеяте ложь.
Скажите, кого вы пытаетесь обмануть? Вся переписка ведь видна.
На счет регистров: вы уже разобрались какие именно регистры вам нужны? Вы собрали минимальный работоспособный код, на котором можно экспериментировать?
А то берете адреса фиг знает откуда и фиг знает зачем, а потом крики «что я делаю не так». Вот именно это - попытка угадать ответ вместо последовательного изучения и понимания что и зачем делается.
Алгоритм отладки я вам тоже уже расписал - строим минимально рабочий код и тестируем новые фичи по одной, чтобы сразу видеть какую именно не понимаем.
Если не лень будет вечером откопаю платку с f103 и по шагам покажу как это делается. Не на асме, а на Си, разумеется.
вечером откопаю платку с f103 и по шагам покажу как это делается. Не на асме, а на Си, разумеется.
А давай, вместе посмеёмся. Только показывай так, чтобы Ассемблеру понятно было, а не только вам с Эдиком. Начни с нормальной, не васянской, ссылки на используемую библиотеку для этого контроллера. Про документацию к библиотеке не забудь — это очень важно. И про настройку окружения.
Если не лень будет вечером откопаю платку с f103 и по шагам покажу как это делается. Не на асме, а на Си, разумеется.
думаю, что уже не стоит. тем более уроков с использованием библиотек и сред разработок на youtube много. вы можете конечно создать отдельно тему и там разбираться на СИ сами. Но только не тут. эта тема закрыта.
может благодаря этому форуму вы научитесь программировать.
от вас только одни слова. идите уже и создайте тему. уважаемые форумчане вам объяснят и научат. для этого не нужно заходит в мои тему и гнобить меня, заглядывая при этом в лица форумчан в надежде увидить в них одобрения своих действий. тему что создадите прям так и называйте
я не понимаю что такое bitband пожалуйста объясните
и метки не забудьте выставить stm32
уроков с использованием библиотек и сред разработок на youtube много
И все — полнейший шлак. Когда один ни хрена не понимающий чел (вроде одного анонимуса, который у тебя в темах лужи газифицирует) с умным видом несет бред другим еще более не въезжающим.
Ну невозможно сделать «видеоурок» для работы с микроконтроллерами! Можно сделать «видеоурок» вроде: «как правильно паять LQFP», «как правильно варить электродной сваркой», «как сделать что-то на токарном станке» и т.п. — где важна именно видеодемонстрация процесса. В случае же с обучением электронике и программированию нужен лишь гольный текст. А для программирования вообще хватит хорошо прокомментированного исходника.
Допустим, есть желание протестировать bitband доступ к RCC->APB2ENR. Для начала закомментируем строчку с ним и убедимся, что мигалка перестала работать.
Начнем с того, чтобы заменить подаренный компилятором адрес на вычисленный самостоятельно. Открываем Reference Manual и ищем там RCC_APB2ENR. У меня он нашелся на 109 странице. Для него указано смещение Address: 0x18. Листаем пока не найдем относительно чего это смещение считается, находим чт оотносительно RCC (вот так неожиданность). В разделе Memory map находим, что RCC начинается с адреса 0x4002’1000. Прибавляем смещение, получаем 0x4002’1018.
Поскольку считать все вручную лень, оформим в виде макроса (надеюсь, не надо объяснять откуда в коде взялись 0x4000’0000 и 0x4200’0000). ВНИМАНИЕ! С этого момента начинается мой затуп:
Осталось только добавить круглые скобки вокруг аргументов макроса для надежности и задокументировать, хотя бы на русском. Заодно восстановим стандартные имена адресов, раз уж самодельные сработали:
#include <stm32f1xx.h>
void __attribute__((weak)) _init(void){} //костыли для стандартного стартапа
void __attribute__((weak)) SystemInit(void){}
#define GPIO_PP50 0b0011 //push-pull, 50MHz
//Доступ к биту периферии при помощи bitband.
// addr - регистр периферии
// bit - номер бита
//return value - "регистр", отвечающий за данный бит
#define BB_PERIPH( addr, bit ) (*((uint32_t*)( 0x42000000 + ((uint32_t)&(addr)-0x40000000)*32 + (bit)*4 )))
//LED on PB5
int main(void){
BB_PERIPH( RCC->APB2ENR, RCC_APB2ENR_IOPBEN_Pos ) = 1;
GPIOB->CRL = (GPIOB->CRL &~(0b1111 << (4*5))) | (GPIO_PP50 << (4*5));
while(1){
GPIOB->ODR ^= (1<<5);
for(uint32_t i=0; i<100000; i++)asm("nop");
}
}
Тут меня заинтересовал вопрос: можно ли этот бит считать? Для проверки считаем в переменную сначала бит до модификации, а потом после и если они не равны, зажжем светодиод. Без мигания на этот раз:
#include <stm32f1xx.h>
void __attribute__((weak)) _init(void){} //костыли для стандартного стартапа
void __attribute__((weak)) SystemInit(void){}
#define GPIO_PP50 0b0011 //push-pull, 50MHz
//Доступ к биту периферии при помощи bitband.
// addr - регистр периферии
// bit - номер бита
//return value - "регистр", отвечающий за данный бит
#define BB_PERIPH( addr, bit ) (*((uint32_t*)( 0x42000000 + ((uint32_t)&(addr)-0x40000000)*32 + (bit)*4 )))
//LED on PB5
int main(void){
uint8_t prev = BB_PERIPH( RCC->APB2ENR, RCC_APB2ENR_IOPBEN_Pos );
BB_PERIPH( RCC->APB2ENR, RCC_APB2ENR_IOPBEN_Pos ) = 1;
uint8_t next = BB_PERIPH( RCC->APB2ENR, RCC_APB2ENR_IOPBEN_Pos );
GPIOB->CRL = (GPIOB->CRL &~(0b1111 << (4*5))) | (GPIO_PP50 << (4*5));
if( prev != next )GPIOB->ODR |= (1<<5);
while(1){
}
}
Да, зажигается. Значит, битбанд работает в обе стороны. По крайней мере в моем контроллере.