реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как правильно записать бит в регистр NVIC_ISER1?
r44083
сообщение Oct 19 2015, 09:04
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 13-09-15
Пользователь №: 88 376



Здравствуйте, ситуация такая: использую STM32F10x и хочу без использования функций CMSIS и StdPeriphLib разрешить прерывание от SPI1.
У SPI1_IRQn номер равный 35, следовательно я должен записать 1 во второй по счету регистр NVIC_ISER[1] в 4-ый бит (если считать с нуля). А так как SPI1_IRQn равен 35 (мы не можем сдвинуть 1 на 35 бит), то нам надо вычесть 32 из SPI1_IRQn (итого получается сдвигаем 1 на 3 бита и записываем это в регистр NVIC_ISER[1]).
Итак у меня получается запись такого вида:

Код
NVIC->ISER[1] |= (1 << (SPI1_IRQn - 32 ));


Но это выглядит плохо читаемым и не универсальным. Может кто-нибудь посоветует как лучше такие вещи делать, что бы код стал более понятным?

В CMSIS например есть вот такая функция:

Код
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}


Сообщение отредактировал r44083 - Oct 19 2015, 09:08
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 19 2015, 09:10
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Думаю, это неправильное желание.

Аккуратнее, чем NVIC_EnableIRQ() можно сделать только битбангом. И то, не факт, что оно лучше будет (наверное, даже хуже - ядро будет делать read-modify-write, вместо записи одного бита).
И смысл тогда этого велосипеда, если он будет такой же, только нестандартный?


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
r44083
сообщение Oct 19 2015, 09:14
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 13-09-15
Пользователь №: 88 376



Цитата(esaulenka @ Oct 19 2015, 12:10) *
Думаю, это неправильное желание.

Аккуратнее, чем NVIC_EnableIRQ() можно сделать только битбангом. И то, не факт, что оно лучше будет (наверное, даже хуже - ядро будет делать read-modify-write, вместо записи одного бита).
И смысл тогда этого велосипеда, если он будет такой же, только нестандартный?

Я понимаю что вы хотите мне сказать, но мною движет желание сделать код более прозрачным.
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Oct 19 2015, 09:35
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



а разве с функцией NVIC_EnableIRQ(SPI1_IRQn) он стал менее прозрачным?
Даже если вы доведете до вида NVIC->ISER[1] |= (1 << (SPI1_IRQn & 0x1F)); запись понятней не станет

Сообщение отредактировал ЯadiatoR - Oct 19 2015, 09:45
Go to the top of the page
 
+Quote Post
Obam
сообщение Oct 19 2015, 14:19
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Прозрачнее дальше некуда:
LDR R0, =NVIC_BASE_ADDRSS
LDR R1, =(ID25_IRQ | ID21_IRQ | ID15_IRQ)
STR R1, [R0, #REG_NVIC_ISER0]// в ядре разрешены прерывания от TC0_Ch2, SPI и USART1_SPImode


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 19 2015, 16:03
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(ЯadiatoR @ Oct 19 2015, 12:35) *
а разве с функцией NVIC_EnableIRQ(SPI1_IRQn) он стал менее прозрачным?
Даже если вы доведете до вида NVIC->ISER[1] |= (1 << (SPI1_IRQn & 0x1F)); запись понятней не станет

Вот-вот, не надо NVIC_EnableIRQ() переписывать.
Потому что в
NVIC->ISER[1] |= (1 << (SPI1_IRQn & 0x1F));
уже есть ошибка. При дальнейшем увеличении прозрачности количество ошибок будет только расти...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2015, 17:24
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Посмотрите в core_cm3.h, и увидите, что проще сделать невозможно.
Код
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}

Поэтому надо использовать. В отличие от StdPeriph_lib.
О, я и не заметил, что уже в вопросе есть ответ.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 19 2015, 17:34
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ViKo @ Oct 19 2015, 20:24) *
Посмотрите в core_cm3.h, и увидите, что проще сделать невозможно.

Можно сдвиг заменить на деление, а побитовое И - на остаток от деления. Кому-то, может быть, и станет нагляднее, но если имеешь дело с Си и впадаешь в ступор от битовых операций, то лучше или сменить род занятий, или подучить Си.
Go to the top of the page
 
+Quote Post
r44083
сообщение Oct 19 2015, 22:10
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 13-09-15
Пользователь №: 88 376



Ок, я понял. Всем спасибо. Буду использовать функцию из CMSIS.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 10:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01442 секунд с 7
ELECTRONIX ©2004-2016