Перейти к содержанию
    

Запрограммировать группу битов в регистре

Для инициализации отдельных битов в регистрах STM32F207 использую следующее макро. Копирую описание битов из stm32f20x.h, и редактирую в соответсвии с потребностями:

  ADC2->CR2 =
    ADC_CR2_ADON        * 1 |    // A/D Converter ON / OFF
    ADC_CR2_CONT        * 0 |    // Continuous Conversion
    ADC_CR2_DMA        * 0 |    // Direct Memory access mode
    ADC_CR2_DDS        * 0 |    // DMA disable selection (Single ADC)
    ADC_CR2_EOCS        * 0 |    // End of conversion selection
    ADC_CR2_ALIGN        * 0 |    // Data Alignment = Right
    ADC_CR2_JEXTSEL_0    * 1 |    // External event select for injected group - Bit 0 = EXTI_15 PG15
    ADC_CR2_JEXTSEL_1    * 1 |    //    Bit 1
    ADC_CR2_JEXTSEL_2    * 1 |    //    Bit 2
    ADC_CR2_JEXTSEL_3    * 1 |    //    Bit 3
    ADC_CR2_JEXTEN_0    * 0 |    // External Trigger Conversion mode for injected channels - Bit 0 = Fall
    ADC_CR2_JEXTEN_1    * 1 |    //    Bit 1
   ...

Очень наглядно, и удобно манипулировать настройками.

Но не нравится, что группу битов, определяющую некое число (как в JEXTSEL, JEXTEN в данном случае), приходится кодировать побитно. Нет ли простого и красивого способа задать сразу группу одним числом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет ли простого и красивого способа задать сразу группу одним числом?

 

#define    ADC_CR2_JEXTSEL0    (ADC_CR2_JEXTSEL_0 * 0)
#define    ADC_CR2_JEXTSEL1    (ADC_CR2_JEXTSEL_0 * 1)
#define    ADC_CR2_JEXTSEL2    (ADC_CR2_JEXTSEL_0 * 2)
#define    ADC_CR2_JEXTSEL3    (ADC_CR2_JEXTSEL_0 * 3)
...
#define    ADC_CR2_JEXTSEL15  (ADC_CR2_JEXTSEL_0 * 15)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define    ADC_CR2_JEXTSEL0    (ADC_CR2_JEXTSEL_0 * 0)
#define    ADC_CR2_JEXTSEL3    (ADC_CR2_JEXTSEL_0 * 3)
...

Не пойдет. ADC_CR2_JEXTSEL_0 - это ((uint32_t)0x00010000) . Что будет, если его умножить на 3?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не пойдет. ADC_CR2_JEXTSEL_0 - это ((uint32_t)0x00010000) . Что будет, если его умножить на 3?

??

0x00030000 = ADC_CR2_JEXTSEL_0 | ADC_CR2_JEXTSEL_1

 

Разве не это нужно было?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

??

0x00030000 = ADC_CR2_JEXTSEL_0 | ADC_CR2_JEXTSEL_1

 

Разве не это нужно было?

Ой! Что-то я ступил. :) Мне казалось, получается громадное число... :a14:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...
#define COMP(v,offset) ((v)<<offset)) //упрощенная версия
//используемые макросы (МК другой):
//#define ERROR_VALUE (_nop_())
//#define COMP(v,min,max,offset,len)  ((((v)<min)||((v)>max)||((v)>=1<<len)||((len+offset)>16)) ? ERROR_VALUE : ((v)<<offset))
...
#define ADON(v)    (v, 0)
#define CONT(v)    COMP(v, 1)
#define DMA(v)    COMP(v, 8)
#define DDS(v)    COMP(v, 9)
#define EOCS(v)    COMP(v,10)
#define _RIGHT    (0)
#define _LEFT    (1)
#define ALIGN(v)    COMP(v,11)
#define _TMR1_CC4 (0)
#define _EXTI_15    (15)
#define JEXTSEL(v)    COMP(v,16)
#define _RISING    (1)
#define _FALLING    (2)
#define JEXTEN(v)    COMP(v,20)
...
ADC_CR2=ADON(1) | CONT(1) | DMA(0) | DDS(0) | EOCS(0) | ALIGN (_RIGHT) | JEXTSEL (_EXTI_15) | JEXTEN(_FALLING);

Изменено пользователем Risport

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все бы хорошо, но не стоит далеко отходить от стандартных определений, предоставленных производителем.

Одно дело, немного приукрасить, и совсем другое - полностью переписать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задал так. Проверку на допустимый диапазон не делаю (в скобках записал).

  ADC2->JSQR =
    ADC_JSQR_JSQ4_0        * 15 |    // 4th conversion in injected sequence (0..18) - IN15
    ADC_JSQR_JL_0        * 00;    // Injected Sequence length (0..3) - 1 Conversion

или иначе (потому что не все комбинации битов допустимы)

  ADC2->CCR =
    ADC_CCR_MULTI_0        * 00 |    // MULTI[4:0] (Multi-ADC mode selection)
    ADC_CCR_DELAY_0        * 00 |    // DELAY[3:0] bits (Delay between 2 sampling phases)
    ADC_CCR_DDS        *  0 |    // DMA disable selection (Multi-ADC mode)
    ADC_CCR_DMA_0        * 00 |    // DMA[1:0] bits (Direct Memory Access mode for multimode)
    ADC_CCR_ADCPRE_0    * 00 |    // ADCPRE[1:0] bits (ADC prescaler) - PCLK2/2 = 30 MHz
    ADC_CCR_VBATE        *  1 |    // VBAT Enable
    ADC_CCR_TSVREFE        *  1;    // Temperature Sensor and VREFINT Enable

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...