Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2368 Прерывание по совпадению таймера, помогите
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
sasha968m
Всем здравствуйте!
Помогите, пожалуйста, разобраться с прерыванием от таймера0 по совпадению.
Только начал осваивать 32 разрядные микроконтроллеры. Есть отладочная плата SK-MLPC1768/2387/2368, с установленным LPC2368.
Для обучения пользуюсь IAR 7.50.2.10505
Нажмите для просмотра прикрепленного файла
Вставлял ловушку в бесконечном цикле и проверял 0 бит регистра T0IR. Видно что таймер входит в прерывание (бит устанавливается), но дальше действий программа никаких не выполняет, а должна быть бегущая единица.
Как должна работать эта программа ясно, но почему не работает не понятно.
Исходник взят из интернета, кроме настройки PLL. PLL настраивается. Проверялось.
Подскажите, направьте пожалуйста!
jcxz
1.Устанавливаете запрос синхронного сброса
Код
T0TCR = 0x00000002;
но не дожидаетесь его окончания. Значит сброс у Вас реально может происходить после последующих записей конфигурации.
2.Не чистите регистр флагов запросов прерываний.
3.Неправильно рассчитываете период:
Код
//Регистр совпадения = 1000 (1 Гц)
T0MR0 = 100;

Как можно было сделать столько ошибок в такой простейшей периферии???
Читайте внимательнее юзермануал!
Да и в CTCR неплохо бы соотв. значение записать.
После этого смотрите появляется ли флаг активного запроса прерывания в IR?
И если появляется, а входа в ISR нет - читайте про контроллер прерываний и всё что с ним связано.

По контроллеру прерываний:
1.А где у Вас глобальное разрешение прерываний IRQ? (Вы ведь вроде этому прерыванию от таймера назначаете линию IRQ?)
2.А где обработчик прерывания IRQ?
zltigo
Цитата(jcxz @ Jan 18 2017, 10:03) *
Читайте внимательнее юзермануал!

Ну Вы и не ленивый читать галиматью написанную в силе "= 0x00000002;" sm.gif Я лично не стал.
Ну в Автору большой совет - если хотите что бы кто-то читал написанное Вами и разбирался - НЕ ПИШИТЕ в том "стиле", как написали. Все биты и константы должны иметь ИМЕНА.
jcxz
Цитата(zltigo @ Jan 18 2017, 11:09) *
Ну Вы и не ленивый читать галиматью написанную в силе "= 0x00000002;" sm.gif Я лично не стал.

Я прочитал просто потому, что много работал с LPC-шной периферией и помню почти наизусть её, тем более таймера - почти самое простое там.
Тем более они не изменились при переходе на Cortex LPC17xx/LPC43xx.
Так бы да - и читать бы не стал.

Цитата(zltigo @ Jan 18 2017, 11:09) *
Все биты и константы должны иметь ИМЕНА.

Насчёт первого (битов в конфигурационных регистрах периферии) не совсем с Вами согласен.
Как правило, когда прописываешь их значения в какой-то регистр, всегда перед глазами открытая страничка с описанием этого регистра.
И мне например удобнее соотносить описания полей в мануале с исходником по номерам битов, а не их именам (которых может и не быть или быть неудобными).
Так что именно для битовых полей в регистрах конфигурации периферии я отступаю от этого правила, и чаще всего прописываю так:
T0MCR = B0 | B1;
А точнее даже так:
concat(T, nTIM_nrf, MCR) = B0 | B1;
ну или через указатель.
Так как все назначения номеров таймеров, портов UART/SPI/... и пр. периферии у меня собраны в одном месте и нигде нет прямых ссылок на регистры периферии:
Код
//Распределение UART-ов
#define nUART_service 3   //номер UART сервисного порта
//Распределение GP-таймеров
#define nTIM_cpu      0   //таймер коротких интервалов
#define nTIM_intmon   1   //таймер контролЯ длительности запретов прерываний (длЯ отладки)
#define nTIM_nrf      2   //таймер драйвера nRF24L01+
//Распределение SSP-портов
#define nSSP_nrf      0   //nRF24L01+

где concat - это текстовая склейка :
Код
#define concatVOID
#define concat_SUBST2(a, b, c, d, e, f, g, h, i, j, k, l, ...) \
        a##b##c##d##e##f##g##h##i##j##k##l
#define concat_SUBST(...) concat_SUBST2(__VA_ARGS__)
#define concat(...) concat_SUBST(__VA_ARGS__, concatVOID, concatVOID, \
        concatVOID, concatVOID, concatVOID, concatVOID, concatVOID, concatVOID, \
        concatVOID, concatVOID)
zltigo
Цитата(jcxz @ Jan 18 2017, 10:24) *
Я прочитал просто потому, что много работал с LPC-шной периферией и помню почти наизусть её, тем более таймера - почти самое простое там.
Тем более они не изменились при переходе на Cortex LPC17xx/LPC43xx.
Так бы да - и читать бы не стал.

Я тоже работал и работаю и 34xx и 17хх тоже помню многое, но помню ИМЕНА а не "второй бит справа". Более того, что значит "второй бит справа" если и знал, то в тот краткий миг, когда его описывал.
Никаких особых дополнительных наворотов в описании не использую.
Внешне получается где-то так:
CODE

//---------------------------------------------------------------------------
void init_mrt_timers(void)
{
// Enable MRT clock
SYSAHBCLKCTRL1 |= CTRL1_MRT;
// Peripheral reset control to MRT, a "1" bring it out of reset.
PRESETCTRL1 |= ( CTRL1_MRT );
PRESETCTRL1 &= ~( CTRL1_MRT );

.......

MRT_INTVAL0 = 0;
MRT_INTVAL0 = MRT_INTVAL_LOAD;
MRT_CTRL0 = MRT_CTRL_ONE_SHOT|MRT_CTRL_INTEN;

VIC_EnableIRQ( MRT_IRQn );
}
.....
//---------------------------------------------------------------------------
void vlfx_tx_timeout_start( bint slots )
{
MRT_INTVAL0 = ((((CPU_CLOCK_HZ/CC1000_BAUD)*10) + 1)*slots);
MRT_INTVAL0 |= MRT_INTVAL_LOAD;

}


В случае, когда более-менее универсальный исходник планируется, тогда еще, да, можно алиасы назначить:
CODE

#define TsPR_SYS T1PR
#define TsIR_SYS T1IR
#define TsMR0_SYS T1MR0
#define TsMCR_SYS T1MCR
#define TsTCR_SYS T1TCR
#define TsTC_SYS T1TC
#define VIC_TIMERs_SYS VIC_TIMER1

//---------------------------------------------------------------------------
static void init_systimer( bint ext_source )
{
ulong compare_match;

// Tick does not require the use of the timer prescale. This is
// defaulted to zero but can be used if necessary
TsPR_SYS = 0;
// Calculate the match value required for our wanted tick rate
compare_match = CPU_CLOCK_HZ / BUS_DIVIDER / SYS_TICK_RATE_HZ;
TsMR0_SYS = compare_match - 1;
// Generate tick with timer compare match
TsMCR_SYS = (MCR_MR0INT | MCR_MR0RES);
TsTCR_SYS = 0;

if( ext_source )
{ // External source
}
else
{ // Start the timer
#if( configUSE_PREEMPTION == 1 )
extern void ( vPortPreemptiveTickEntry )( void );
install_irq( VIC_TIMERs_SYS, (void *)vPortPreemptiveTickEntry, VIC_SYSTEM_PRIOR, TRUE );
#else
extern void ( vNonPreemptiveTick )( void );
install_irq( VIC_TIMERs_SYS, (void *)vNonPreemptiveTick, VIC_SYSTEM_PRIOR, TRUE );

#endif
TsTCR_SYS = TCR_ENABLE;
}
}
jcxz
Цитата(zltigo @ Jan 18 2017, 11:43) *
#define TsPR_SYS T1PR
#define TsIR_SYS T1IR

Мой вариант лучше, так как:
1. Короче - всего по одной строчке на каждый экземпляр периферии.
2. Позволяет связывать данным именем не только регистры периферии, но и биты в регистрах NVIC, регистрах разрешения тактирования периферии, адрес вектора прерывания.
Т.е. - я могу просто всего в одном месте изменить номера
Код
#define nTIM_cpu      0   //таймер коротких интервалов
#define nTIM_intmon   1   //таймер контролЯ длительности запретов прерываний (длЯ отладки)
#define nTIM_nrf      2   //таймер драйвера nRF24L01+
скажем на:
Код
#define nTIM_cpu      2   //таймер коротких интервалов
#define nTIM_intmon   0   //таймер контролЯ длительности запретов прерываний (длЯ отладки)
#define nTIM_nrf      1   //таймер драйвера nRF24L01+

и всё! Больше ничего в исходнике ни в одном месте трогать не надо - все конфигурирования битов в регистрах NVIC, регистрах SYSCFG.PCONP и вектора прерывания переедут на новые места соответствующие новому распределению периферии.
Типичный инит таймера у меня выглядит примерно так:
CODE
PeripheralPowerOn(concat(PERIPH_PCTIM, nTIM_nrf)); //устанавливает нужный бит SYSCFG.PCONP
volatile HwRegsTIMER *p = &concat(TIMER, nTIM_nrf);
p->TCR = B1;
p->TC = p->PC = p->PR = p->CCR = p->CTCR = 0;
p->MCR = B0 | B1 | B2;
p->IR = p->IR;
IntClrEna(concat(NVIC_TIMER, nTIM_nrf)); //чистит нужный бит регистре активных запросов прерываний и устанавливает такой же бит в маске разрешения прерываний

Таблица назначения приоритетов INT-ов:
Код
  static u8 const priority[] = { //список INT-ов по убыванию приоритетов
    concat(NVIC_TIMER, nTIM_intmon), 0,
    NVIC_ETHERNET, NVIC_GPDMA, concat(NVIC_SSP, nSSP_nrf),
    concat(NVIC_TIMER, nTIM_nrf), 0,
    concat(NVIC_UART, nUART_service), 0, 0
  };

Фрагмент asm-файла описания таблицы векторов прерываний:
CODE
...
#define mapUART (1 << nUART_service)
#define mapSSP (1 << nSSP_nrf)
#define mapTIMER (1 << nTIM_intmon | 1 << nTIM_nrf)
isrPort MACRO port, portClass
IF map\2 & 1 << \1
EXTERN isr\2\1
DCD isr\2\1
ELSE
DCD DefaultISR
ENDIF
ENDM
...
SECTION .intvecTail:CONST:NOROOT(2)
DATA ;Продолжение таблицы прерываний
__vector_table_tail
DCD isrSVC ;SVCall Handler
DCD DefaultISR ;Debug Monitor Handler
DCD 0 ;Reserved
DCD OS_CPU_PendSVHandler ;PendSV Handler
DCD isrSysTick ;SysTick Handler
DCD isrWDT ;Watchdog timer
isrPort 0, TIMER ;Match 0 - 1 (MR0, MR1), Capture 0 - 1 (CR0, CR1)
isrPort 1, TIMER ;Match 0 - 2 (MR0, MR1, MR2), Capture 0 - 1 (CR0, CR1)
isrPort 2, TIMER ;Match 0-3, Capture 0-1
isrPort 3, TIMER ;Match 0-3, Capture 0-1
isrPort 0, UART ;UART0
isrPort 1, UART ;UART1
isrPort 2, UART ;UART2
isrPort 3, UART ;UART3
...
zltigo
Цитата(jcxz @ Jan 18 2017, 11:18) *
Мой вариант лучше, так как:

Верю. Способов знаю, если не все, то много sm.gif. Просто описал, как сам делаю, поскольку, как написал "универсальные" использую редко. При малейшем желании можно и такую форму в одну строчку изменений обернуть - конкатенация всегда хорошо применима. Не проблема.
Ну и к форме "p->TCR" испытываю какую-то личную (будем считать ничем не обоснованную - просто глаз цепляется и понимаю, что можно тоже спрятать) неприязнь.

Цитата(jcxz @ Jan 18 2017, 10:24) *
Как правило, когда прописываешь их значения в какой-то регистр, всегда перед глазами открытая страничка с описанием этого регистра.
И мне например удобнее соотносить описания полей в мануале с исходником по номерам битов, а не их именам (которых может и не быть или быть неудобными).
Так что именно для битовых полей в регистрах конфигурации периферии я отступаю от этого правила, и чаще всего прописываю так:
T0MCR = B0 | B1;

А для прочитать через день, или год опять мануал открывать? Нет, спасибо. Если я опишу пусть и пусть даже забуду аббревиатуру бита, то по этому имени я нажатием Alt+T в моем редакторе попаду в хидер, где оно определено и где У МЕНЯ есть комментарии, что это есть такое. И никаких лазаний по мануалам. Хотя все нужные мануалы у меня тоже подключены в проект и по Alt+H можно открыть сразу поиск. Для некоторых битов даю и дополнительные имена, КАК ПРИВЫК за многие годы с РАЗНЫМ оборудованием, например те-же регистры и биты 8250/82550 - у меня названы по первоисточнику sm.gif так привычнее и уже намертво в голову вбиты.
sasha968m
Цитата(jcxz @ Jan 18 2017, 11:03) *
1.Устанавливаете запрос синхронного сброса
Код
T0TCR = 0x00000002;
но не дожидаетесь его окончания. Значит сброс у Вас реально может происходить после последующих записей конфигурации.

jcxz, это значит что после операции T0TCR = 0x00000002; нужно проверить сбросился ли ТС и только потом продолжать конфигурацию?

Цитата(jcxz @ Jan 18 2017, 11:03) *
2.Не чистите регистр флагов запросов прерываний.

Его обязательно чистить в конфигурации таймера? Читал в юзер мануал что по сбросу он очищен.


Цитата(jcxz @ Jan 18 2017, 11:03) *
3.Неправильно рассчитываете период:
Код
//Регистр совпадения = 1000 (1 Гц)
T0MR0 = 100;


jcxz, так правильно будет?
Код
PCLKSEL0 |= 0x0000000E; //Timer0Clk=72Mhz/8= 9 MHz      
}

void Timer0_Init(void){
//Предделитель таймера = 8999
T0PR = 8999;
//Сбросить счетчик и делитель
T0TCR = 0x00000002;
//Режим таймера
Т0СТСR = 0;
//При совпадении сбрасываем таймер и вызываем прерывание
T0MCR = 0x00000003;
//Регистр совпадения = 1000 (1 Гц)
T0MR0 = 1000;



Цитата(jcxz @ Jan 18 2017, 11:03) *
Как можно было сделать столько ошибок в такой простейшей периферии???
Читайте внимательнее юзермануал!
Да и в CTCR неплохо бы соотв. значение записать.

До этого я программировал только AVR (mega) на Ассемблере. В С, можно сказать, я полный балбес, только учусь.

Цитата(jcxz @ Jan 18 2017, 11:03) *
После этого смотрите появляется ли флаг активного запроса прерывания в IR?
И если появляется, а входа в ISR нет - читайте про контроллер прерываний и всё что с ним связано.


В бесконечный цикл вставлял такой код
Код
//if (T0IR & (1 << 0)) {FIO2CLR = (1<<13);      //Зажгли светодиод              |    
                    // T0TCR = 0x00000000;     //Остановили таймер - счётчик   |    
                    // T0IR = 0x00000001;      //сбросили флаг прерывания      |Ловушка                
                    // T0TCR = 0x00000002;     //сбросили таймер - счётчик     |    
                     // T0TCR = 0x00000001;}    //запустили таймер - счётчик    |
// else {FIO2SET = (1<<13);}

и по светодиоду видел, что 0 бит T0IR с определённым периодом устанавливается (таймер входит в прерывание).

Цитата(jcxz @ Jan 18 2017, 11:03) *
По контроллеру прерываний:
1.А где у Вас глобальное разрешение прерываний IRQ? (Вы ведь вроде этому прерыванию от таймера назначаете линию IRQ?)

Это не оно VICIntEnable |= 0x00000010;?

Цитата(jcxz @ Jan 18 2017, 11:03) *
2.А где обработчик прерывания IRQ?

Вроде это обработчик прерывания
Код
__irq void Timer0_Int (void)
{

  
if (n!=0x2000000) {n<<=1;}
else {n = 0x04000000;}
T0IR = 0x00000001; /*Сбросить флаг прерывания в Timer0*/
//Бегущая единица
IOSET1 = 0x3C000000;
IOCLR1 = n; /* Установить состояние порта */
VICVectAddr = 0; /*Перевести VIC в исходное состояние*/
}


Пробовал я писать имена битов в регистрах, как в других примерах из интернета, но IAR выдаёт на них ошибки. Нужны, видимо какие-то библиотеки, ноя пока не пойму какие и где их брать.
Ребята выше привели много разных примеров кода, ноя их не понимаю. Буду пробовать разбираться.
zltigo
Цитата(sasha968m @ Jan 18 2017, 13:24) *
Пробовал я писать имена битов в регистрах, как в других примерах из интернета, но IAR выдаёт на них ошибки. Нужны, видимо какие-то библиотеки, ноя пока не пойму какие и где их брать.

Это называется заголовки, а не библиотеки. Есть в комплекте компилятора, или пишутся свои. У ИАР они очень специфичные под себя заточенные, посему абстракниые примеры их интернету не годятся. Либо свои пишите, либо надстройки над ИАРовскими допишите, либо на милость ИАР сдавайтесь (категорически не рекомендую).
Но САМОЕ главное начинайте не с таскания и усугубления всякого мусора из интернета, а изучения базовых понятий языка.
sasha968m
Цитата(zltigo @ Jan 18 2017, 14:31) *
Это называется заголовки, а не библиотеки. Есть в комплекте компилятора, или пишутся свои. У ИАР они очень специфичные под себя заточенные, посему абстракниые примеры их интернету не годятся. Либо свои пишите, либо надстройки над ИАРовскими допишите, либо на милость ИАР сдавайтесь (категорически не рекомендую).
Но САМОЕ главное начинайте не с таскания и усугубления всякого мусора из интернета, а изучения базовых понятий языка.

Да Вы правы, не правильно я выразился, это заголовочные файлы. Спасибо за совет!
zltigo, если Вас не затруднит, можете в двух строчках написать, какие базовые понятия С языка нужно изучить прежде всего.
zltigo
Цитата(sasha968m @ Jan 18 2017, 13:51) *
Да Вы правы, не правильно я выразился, это заголовочные файлы. Спасибо за совет!
zltigo, если Вас не затруднит, можете в двух строчках написать, какие базовые понятия С языка нужно изучить прежде всего.

K&R второе издание


sasha968m
zltigo, спасибо! Уже скачал.
Проект мой получилось собрать и запустить в Keil. Прерывания от таймера по совпадению заработали.
Но! Для этого в проект был включён файл LPC2300.s (startup).
В IAR тоже нужно, наверное, типа такого файл подключать? Подскажите?
jcxz
Цитата(sasha968m @ Jan 18 2017, 14:24) *
jcxz, это значит что после операции T0TCR = 0x00000002; нужно проверить сбросился ли ТС и только потом продолжать конфигурацию?

Нет. Нужно проверить сбросился ли этот бит синхронного сброса в TCR. Прочитайте наконец описание TCR в юзермануале. У меня сейчас нет его под рукой, но насколько помню там описано поведение этого бита.
В общем случае частота тактирования таймера может быть ниже частоты процессора, а сброс этого бита - синхронный, т.е. - будет выполнен по ближайшему клоку. К этому времени процессор может успеть выполнить несколько команд.
Всё это описано в юзермануале.

Цитата(sasha968m @ Jan 18 2017, 14:24) *
Его обязательно чистить в конфигурации таймера? Читал в юзер мануал что по сбросу он очищен.

Сбросу чего? МК? Не вижу у Вас этого сброса и не уверен что он выполняется.
Да и в любом случае - лучше очистить.

Цитата(sasha968m @ Jan 18 2017, 14:24) *
jcxz, так правильно будет?
//Регистр совпадения = 1000 (1 Гц)
T0MR0 = 1000;[/code]

Вы на что хотите поделить? На 1000? Чтобы поделить на 1000 надо записать туда 999.
Опять же - RTFM.

Цитата(sasha968m @ Jan 18 2017, 14:24) *
Вроде это обработчик прерывания
__irq void Timer0_Int (void)

У Вас ядро ARM7. У этого ядра только два вектора прерывания - IRQ и FIQ, которые может генерить периферия.
Для каждой периферии можно выбрать - какое из этих 2х прерываний генерить. Вы насколько вижу выбираете IRQ для таймера.
Вот его обработчик Вам и необходим. И его нужно разрешить. А уже в нём будете вызывать эту функцию обслуживания прерывания от таймера.
В общем - прочитайте как устроена система прерываний ARM7.
sasha968m
Нажмите для просмотра прикрепленного файла
Я, кажется, понял. Выставил в первый бит 1, дождался когда она сбросится, а только потом продолжил выполнять дальше программу. Так?
Нажмите для просмотра прикрепленного файла
В это скриншоте вижу что по сбросу микроконтроллера все прерывания сброшены. Допустим, я запишу туда 1 для сброса. Это не вызовет никакой неправильной реакции? Не установятся ли прерывания?
Вот последний код что я состряпал из разных кусков. И он работает! На данном этапе для меня это достижение.
Код
unsigned int n;
void initClocks(void);
void Timer0_Init(void);
__irq void timer0ISR(void);

/***************************************************************************/
/****************************************************************************/
int main (void) {
initClocks();
Timer0_Init(); /* Настроить таймер */    
//
IODIR1 = 0x3C000000;    /*Конфигурируем Р1.26 - Р1.29 на выход, остальное на вход*/
IOSET1 = 0x3C000000;    /* Устанавливаем ноль на выходах */
FIO2DIR = (1<<13);      //Configure Pin P2.13 as Output
FIO2SET = (1<<13);    
//
n = 0x04000000;
IOCLR1 = n;          /* Установить состояние порта */

//Запустить таймер
T0TCR = 0x00000001;

    for (;;) {} //бесконечный цикл
  
}
/***************************************************************************/
/****************************************************************************/

void Timer0_Init(void)
{
  T0CTCR = 0x0; //Set Timer Mode
  T0PR = 8999; //Increment T0TC at every 9000 clock cycles
//9000 clock cycles @9 Mhz = 1 mS

  T0MR0 = 399;   //Zero Indexed Count-hence subtracting 1 (400 msec)
  T0MCR = (1<<0) | (1<<1);//Set bit0 & bit1 to Interrupt & Reset TC on MR0  

  VICVectAddr4 = (unsigned )timer0ISR; //Pointer Interrupt Function (ISR)
  VICVectCntl4 = 0xF;            //lowest priority
  VICIntEnable = (1<<4); // Enable timer0 interrupt

  T0TCR = (1<<1); // Reset Timer
}
/***************************************************************************/
/****************************************************************************/

__irq void timer0ISR(void)
{
if (n!=0x20000000) {n<<=1;}
else{n = 0x04000000;}
T0IR = 0x00000001; /*Сбросить флаг прерывания в Timer0*/
//Бегущая единица
IOSET1 = 0x3C000000;
IOCLR1 = n; /* Установить состояние порта */
VICVectAddr = 0; /*Перевести VIC в исходное состояние*/
}

Как работает таймер я понял.
Читаю RTFM.
jcxz
Цитата(sasha968m @ Jan 18 2017, 23:38) *
Я, кажется, понял. Выставил в первый бит 1, дождался когда она сбросится, а только потом продолжил выполнять дальше программу. Так?

Да.

Цитата(sasha968m @ Jan 18 2017, 23:38) *
В это скриншоте вижу что по сбросу микроконтроллера все прерывания сброшены. Допустим, я запишу туда 1 для сброса. Это не вызовет никакой неправильной реакции? Не установятся ли прерывания?

Вы можете инициализировать таймер и не обязательно после сброса МК. Или например - подключение эмулятора без сигнала сброс. Или выполнение основного ПО после bootloader.
Вобщем - лучше вручную сбросить. Чтобы не было потом неожиданностей.
То же самое и с флагами запросов прерываний в регистрах контроллера прерываний перед их разрешением - вначале соотв. флаг лучше почистить.
Тут уже недавно были вопросы от тех, кто этого не делает о странных попаданиях в ISR когда они не ожидали...
sasha968m
Понял, благодарю.
jcxz
Цитата(zltigo @ Jan 18 2017, 12:49) *
А для прочитать через день, или год опять мануал открывать? Нет, спасибо. Если я опишу пусть и пусть даже забуду аббревиатуру бита, то по этому имени я нажатием Alt+T в моем редакторе попаду в хидер, где оно определено и где У МЕНЯ есть комментарии, что это есть такое. И никаких лазаний по мануалам. Хотя все нужные мануалы у меня тоже подключены в проект и по Alt+H можно открыть сразу поиск. Для некоторых битов даю и дополнительные имена, КАК ПРИВЫК за многие годы с РАЗНЫМ оборудованием, например те-же регистры и биты 8250/82550 - у меня названы по первоисточнику sm.gif так привычнее и уже намертво в голову вбиты.

Всё зависит от данной конкретной периферии. Для более-менее стандартных и подобных по функционалу в разных МК битов (например в UART-ах, SPI, и т.п.) я тоже даю символические имена. И иногда стараюсь чтобы они были одинаковы даже для разных МК.
Но для многой периферии названия битов не то что через год, через день уже не вспомнишь - такие они безликие и так их много. Смысла здесь выписывать их в процедурах работы с периферией не вижу - один фиг чтобы понять что там делается надо мануал держать перед глазами. А в нём ориентироваться по номерам битов легче. Имхо.
Вот к примеру: "Flexible CRC Engine" в Infineon - о чём Вам говорят имена битов: CMI, CEI, LEI, BEI, ...? И таких там сотни. Запоминать бесполезно. Если всего таких 1-3 регистра - ещё помнишь пока пишешь, а в некоторой периферии с десяток таких регистров с кучей битов - даже пока пишешь работу с периферией - и то только по мануалу можно ориентироваться.
zltigo
Цитата(jcxz @ Jan 20 2017, 13:40) *
о чём Вам говорят имена битов: CMI, CEI, LEI, BEI, ...? И таких там сотни. Запоминать бесполезно...

Вы решили проигнорировать то, что я еще написал:
Цитата
... по этому имени я нажатием Alt+T в моем редакторе попаду в хидер, где оно определено и где У МЕНЯ есть комментарии, что это есть такое. И никаких лазаний по мануалам. Хотя все нужные мануалы у меня тоже подключены в проект и по Alt+H можно открыть сразу поиск.

То есть я по этому имени СРАЗУ получу комментарий в хидере или вообще запущу поиск в мануале.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.