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

STM32 – вопросы – проблемы - решения.

А кто-нибудь в курсе, когда STM обещает начать массовое производство и выпуск серии STM32F2xx?

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


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

А кто-нибудь в курсе, когда STM обещает начать массовое производство и выпуск серии STM32F2xx?

По слухам с апреля, до нас с вами докатится не раньше мая...

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


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

Всем привет. Планируем использовать CORTEХ-M3 контроллер STM32F103C8 совместно с эмулятором J-Link ARM ( http://jtag.su/index.php?option=com_conten...7&Itemid=1) в IAR. Т.к. опыта работы с такими контроллерами нету, то вопрос таков - будет ли это все работать? :D

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


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

Всем привет. Планируем использовать CORTEХ-M3 контроллер STM32F103C8 совместно с эмулятором J-Link ARM ( http://jtag.su/index.php?option=com_conten...7&Itemid=1) в IAR. Т.к. опыта работы с такими контроллерами нету, то вопрос таков - будет ли это все работать? :D

 

Будет, только ссылка Ваша на китайский клон, стоит он около 600руб.

http://www.aliexpress.com/product-fm/37417...holesalers.html

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


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

Начали разбираться с stm32 контроллером, чтобы не создавать новую тему - так как вопросов будет много - буду спрашивать их здесь.

В модуле GPIO есть регистры AFIO, чтобы назначать REMAP и указывать ножку для внешнего прерывания. С этим вроде все ясно. Но еще там есть один магический регистр Event control register (AFIO_EVCR), который назначает ножку и порт для некого "EVENTOUT Cortex output". Поиск в даташите на ядро и в референсе ничего не дали. В гугле толком тоже нету. Что это такое?

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

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


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

Тоже есть вопросик про GPIO они что не предусмотрели регистр для атомарного XOR'а порта вывода?

BSSR и BRR - это конечно хорошо но мало...

 

Как народ делает атомарно инверсию пина?

Неужели через if !!!!

Или через ремап для побитовой адресации?

 

PS: Я тут макросами имени Аскольда под STM озадачился, всё красиво получилось кроме pin_toggle(PIN)...

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


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

PS: Я тут макросами имени Аскольда под STM озадачился, всё красиво получилось кроме pin_toggle(PIN)...

Посмотрите вот это, может пригодится.

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


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

Посмотрите вот это, может пригодится.

void Cpl()
{
      *(volatile uint32_t *)ODR_BB_ADDR = ~*(volatile uint32_t *)ODR_BB_ADDR;
}

Посмотрел. Выглядит симпатично. А во что это компилиться?

Я всё же больше на Си...

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


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

Посмотрел. Во что это компилиться?

И компилится, и атомарная операция. Через бит-бэнд регион обращается к отдельному биту регистра ODR.

Т.е. доступ к одному биту в bit-band alias области, как к целому слову в bit-band области.

Только смысла в ней немного.

Проще через BSRR и BRR, и по скорости, и по коду.

void LED_Blink(void) {
  while (1) {
    GPIOB->BSRR = 0x0002;
//    __nop(), __nop(), __nop;
    GPIOB->BRR = 0x0002;
  }
}

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


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

Проще через BSRR и BRR, и по скорости, и по коду.

И компилится, и атомарная операция. Через бит-бэнд регион обращается к отдельному биту регистра ODR.

Т.е. доступ к одному биту в bit-band alias области, как к целому слову в bit-band области.

Только смысла в ней немного.

Т.е. так вполне сносно будет?

...
#define _PIN_SET(   XPORT, XPIN, XMODE, XSPEED)  do {GPIO##XPORT->BSRR = (1UL << (XPIN)); } while (0)  // Atomic operation
#define _PIN_CLR(   XPORT, XPIN, XMODE, XSPEED)  do {GPIO##XPORT->BRR  = (1UL << (XPIN)); } while (0)  // Atomic operation

#define _PIN_TEST(  XPORT, XPIN, XMODE, XSPEED)   ( (GPIO##XPORT->IDR  & (1UL << (XPIN))) != 0UL )

#define _PIN_TOGGLE(XPORT, XPIN, XMODE, XSPEED)                                        \
do                                                                                     \
{                                                                                      \
    if (_PIN_TEST(XPORT, XPIN, XMODE, XSPEED))  _PIN_CLR(XPORT, XPIN, XMODE, XSPEED);  \
    else                                        _PIN_SET(XPORT, XPIN, XMODE, XSPEED);  \
} while (0)

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


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

Т.е. так вполне сносно будет?

На так давно ReAl провёл целое исследование на эту тему. Я позволю себе процитировать фрагмент его письма:

-------- CPL ------------------------------------------------------

---- через ODR ^=

521 0012 DA68 ldr r2, [r3, #12]

522 0014 82F00202 eor r2, r2, #2

523 0018 DA60 str r2, [r3, #12]

-- 8 байтов, 9 циклов, 125 ns -- всё как у On/Off через ODR |=, что и

должно было быть

 

---- через Latched() ? Off() : On()

Полные глупости при компиляции, компилируется в условные переходы,

нестабильный и плохой результат.

 

---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;

 

551 001a DA68 ldr r2, [r3, #12]

556 001c 12F0020F tst r2, #2

557 0020 0CBF ite eq

558 0022 0222 moveq r2, #2

559 0024 4FF40032 movne r2, #131072

561 0028 1A61 str r2, [r3, #16]

-- 14 байтов, 12 циклов (около 167 ns импульс)

Опять выходит немного больше, чем по рассчёту -- как и для ODR |= / &= / ^=

 

 

---- через bit-band

525 0010 5A68 ldr r2, [r3, #4]

526 0012 D243 mvns r2, r2

527 0014 5A60 str r2, [r3, #4]

-- 6 байтов, те же самые 12 циклов, что и выше.

По коду короче даже ODR ^=

По времени дольше, зато атомарно.

 

---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;

 

Но Latched() сделано через bit-band

619 004a 5268 ldr r2, [r2, #4]

624 004c 002A cmp r2, #0

625 004e 0CBF ite eq

626 0050 0222 moveq r2, #2

627 0052 4FF40032 movne r2, #131072

629 0056 1A61 str r2, [r3, #16]

Немного короче и бстрее, чем с Latched() через считывание ODR и маскирование.

Тут использовать особого смысла нет, так как почти не быстрее

bit-band, но длиннее.

Но сам Latched() стоит сделать через bit-band. Разница между

556 001c 12F0020F tst r2, #2

и

624 004c 002A cmp r2, #0

мелочь, а приятно. А где-то просто эта единичка/нолик сразу в bool

пойдёт для возврата из функции.

 

По результатам этих исследований победил вариант с BB :)

 

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


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

Т.е. так вполне сносно будет?

Думаю, да. А для чтения-модификации бита можете и ODR регистр использовать.

Мне не было необходимости делать именно инверсию бита. Просто задаю то состояние, что нужно.

 

На так давно ReAl провёл целое исследование на эту тему. Я позволю себе процитировать фрагмент его письма:

По результатам этих исследований победил вариант с BB :)

Трудно сравнивать объективно, потому что слова для записи и адреса еще нужно подготовить.

Вот листинг того кода, что я показал.

;;;370    void LED_Blink(void) {
000386  482e              LDR      r0,|L1.1088|
;;;371      while (1) {
;;;372        GPIOB->BSRR = 0x0002;
000388  f04f0102          MOV      r1,#2
                  |L1.908|
00038c  f8c01c10          STR      r1,[r0,#0xc10]
;;;373    //    __nop(), __nop(), __nop(); // from Flash 12 clock states
;;;374    //  __nop(), __nop();   // from RAM 14 clock states
;;;375        GPIOB->BRR = 0x0002;
000390  f8c01c14          STR      r1,[r0,#0xc14]
000394  e7fa              B        |L1.908|
;;;376      }
;;;377    }

Пара регистров BSRR, BRR тем и хороша, что одним и тем же словом можно установить или сбросить бит. Как в этом коде - оно хранится в R1. И адрес структуры один - в R0. А смещение внутри команды задается.

Я пробовал и с bit-band, у меня получилось хуже.

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


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

Трудно сравнивать объективно, потому что слова для записи и адреса еще нужно подготовить.

Что может быть объективнее тактов и байтов? :)

А адрес надо готовить в любом случае, что с BB, что с B(S)RR.

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


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

Что может быть объективнее тактов и байтов? :)

Пусть бы ReAl показал результат не для

---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;

а

if (Latched()) GPIOx->BSRR = mask;

else GPIOx->BRR = mask;

Впрочем, для инверсии бита, наверное, вывод ReAl верный.

Зато через регистр BSRR можно зараз сбросить-установить кучу битов.

 

Покажу результат своих только что проделанных экспериментов. Считайте сами, не забудьте константы в конце кода.

                  Bit_change1 PROC
;;;68     
;;;69     void Bit_change1(bool set)
000004  b118              CBZ      r0,|L1.14|
;;;70     {
;;;71       if (set) GPIOB->BSRR = 0x0002;
000006  2102              MOVS     r1,#2
000008  4a0f              LDR      r2,|L1.72|
00000a  6011              STR      r1,[r2,#0]
00000c  e002              B        |L1.20|
                  |L1.14|
;;;72       else     GPIOB->BRR  = 0x0002;
00000e  2102              MOVS     r1,#2
000010  4a0e              LDR      r2,|L1.76|
000012  6011              STR      r1,[r2,#0]
                  |L1.20|
;;;73     }
000014  4770              BX       lr
;;;74     
                          ENDP

                  Bit_change2 PROC
;;;75     void Bit_change2(bool set)
000016  b108              CBZ      r0,|L1.28|
;;;76     {
;;;77       GPIOB->BSRR = 0x0002<<(set ? 0 : 16);
000018  2200              MOVS     r2,#0
00001a  e000              B        |L1.30|
                  |L1.28|
00001c  2210              MOVS     r2,#0x10
                  |L1.30|
00001e  2102              MOVS     r1,#2
000020  4091              LSLS     r1,r1,r2
000022  4a09              LDR      r2,|L1.72|
000024  6011              STR      r1,[r2,#0]
;;;78     }
000026  4770              BX       lr
;;;79     
                          ENDP

                  Bit_change3 PROC
;;;80     void Bit_change3(bool set)
000028  b108              CBZ      r0,|L1.46|
;;;81     {
;;;82       GPIOB->BSRR = set ? 0x0002 : 0x0002<<16;
00002a  2102              MOVS     r1,#2
00002c  e001              B        |L1.50|
                  |L1.46|
00002e  f44f3100          MOV      r1,#0x20000
                  |L1.50|
000032  4a05              LDR      r2,|L1.72|
000034  6011              STR      r1,[r2,#0]
;;;83     }
000036  4770              BX       lr
;;;84     
                          ENDP

                  Bit_change4 PROC
;;;91     
;;;92     void Bit_change4()
000038  4905              LDR      r1,|L1.80|
;;;93     {
;;;94     #define ALIAS_PTR(VarPtr,BitNum) \
;;;95       *((__IO uint32_t *) (((uint32_t) &(VarPtr) & 0xf0000000) | 0x02000000 \
;;;96       + (((uint32_t) &(VarPtr) & 0xfffff) <<5) | (BitNum <<2)))
;;;97     
;;;98       uint32_t bit = ALIAS_PTR(GPIOB->ODR,1);
00003a  6808              LDR      r0,[r1,#0]
;;;99       bit = !bit;
00003c  b908              CBNZ     r0,|L1.66|
00003e  2101              MOVS     r1,#1
000040  e000              B        |L1.68|
                  |L1.66|
000042  2100              MOVS     r1,#0
                  |L1.68|
000044  4608              MOV      r0,r1
;;;100    }
000046  4770              BX       lr
;;;101    
                          ENDP

                  |L1.72|
                          DCD      0x40010c10
                  |L1.76|
                          DCD      0x40010c14
                  |L1.80|
                          DCD      0x42218184

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


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

Впрочем, для инверсии бита, наверное, вывод ReAl верный.

Дык, вопрос-то как раз и был про инверсию бита.

Покажу результат своих только что проделанных экспериментов. Считайте сами, не забудьте константы в конце кода.

Вот благодетель! Не пожалел времени и сил, накропал гениальной рукой десяток тривиальных гениальных строк, и поделился со всеми! Нате, считайте!

Спасибо, что-то не хочется. В чём заключались ваши "эксперименты", если ничего не посчитано? В выяснении возможности скопипастить кусок дизассемблерного текста в форум? :cranky:

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...