Мигать светодиодом. ARM или не-ARM?

Флейм в чистом виде - все что угодно...
Но - в рамках закона :)
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: ARM или не-ARM?

Сообщение dosikus »

oleg110592 писал(а): В общем ощущение с новым HAL еще все очень сыро - обкатывают на народе.


Все сырое и ляпается наспех.Главное что STM, самим фактом появления кубатуры, признало всю ущербность SPL.

oleg110592 писал(а):Ну и в принципе непонятно, почему считается настройка периферии в стм32 сложной, по сравнению с авр пик ...


Периферия в STM сложней и на порядок мощней , а вот работать с ней намного проще чем с ущербной от выше названных 8ми биток ...

ЗЫ. Чтобы тебе быстрее остыть: я ПРИМЕНЯЮ СТМ32... :wink:


КРАМ, то есть ты хочешь сказать - что я STM32 не использую, просто понтуюсь ?, жги дальше... :)))
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25205
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: ARM или не-ARM?

Сообщение КРАМ »

dosikus писал(а):КРАМ, то есть ты хочешь сказать - что я STM32 не использую

"Кто о чем, а вши о бане..." (с)
:facepalm:
:cry:
dosikus писал(а):Периферия в STM сложней и на порядок мощней , а вот работать с ней намного проще чем...

Проще тому, кто умеет.
dosikus, прочтите все сначала и уловите СМЫСЛ топика...
Не нужно ломиться в открытую дверь.
:)
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Продолжим.
Ну вот теперь видим - программы для армов можно писать и с HAL и без или сочетая и то и то. Ну мигать светодиодом точно ;). Мне кажется написание такой программы для начинающего будет приятным вдохновением перед решением более трудных задач. Наверное HAL будет нужен для написания боле сложных программ, типа работы с графикой для Chrom-ART Accelerator, TCP/IP, USB, RTOS где производитель предлагает свои библиотечные решения на основе HAL
И так теперь у нас есть таймер с прерываниями, точно так же как и у стареньких микроконтроллеров, теперь можно попробовать применить старые разработки, отлично работающие на пиках и аврах. Для отображения часов на индикаторе нам понадобится динамическая индикация - тут и пригодится таймер с прерываниями. Забегая вперед, скажу - у стм32 есть другая замечательная возможность организовать динамическую индикацию. Но вначале проверим работают ли устаревшие технологии. Ну в общем занимаемся копипастом своих, а может чужих решений, например код для bin2bcd скопипастил у HHIMERA - раньше делал по другому из-за ограничений устаревших архитектур (приходилось каждый лишний байтик считать), а тут раздолье - и деление аппаратное и флэша в достатке. Програмка простая - считает секунды и должна показывать на семисегментном индикаторе:
Спойлер

Код: Выделить всё

#define SegA   (uint8_t)1<<0
#define SegB   (uint8_t)1<<1
#define SegC   (uint8_t)1<<2
#define SegD   (uint8_t)1<<3
#define SegE   (uint8_t)1<<4
#define SegF   (uint8_t)1<<5
#define SegG   (uint8_t)1<<6
#define SegH   (uint8_t)1<<7

#define digit_0   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF)
#define digit_1   (uint8_t)(SegB | SegC)
#define digit_2   (uint8_t)(SegA | SegB | SegG | SegE | SegD)
#define digit_3   (uint8_t)(SegA | SegB | SegG | SegC | SegD)
#define digit_4   (uint8_t)(SegF | SegG | SegB | SegC)
#define digit_5   (uint8_t)(SegA | SegF | SegG | SegC | SegD)
#define digit_6   (uint8_t)(SegA | SegF | SegE | SegD | SegC | SegG)
#define digit_7   (uint8_t)(SegA | SegB | SegC)
#define digit_8   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF | SegG)
#define digit_9   (uint8_t)(SegA | SegB | SegC | SegD | SegF | SegG)

const uint8_t seg7[10] =
{
    digit_0,
    digit_1,
    digit_2,
    digit_3,
    digit_4,
    digit_5,
    digit_6,
    digit_7,
    digit_8,
    digit_9
};

#define SEG_GPIO_ODR GPIOB->ODR
#define SEGA GPIO_ODR_0
#define SEGB GPIO_ODR_1
#define SEGC GPIO_ODR_2
#define SEGD GPIO_ODR_3
#define SEGE GPIO_ODR_4
#define SEGF GPIO_ODR_5
#define SEGG GPIO_ODR_6
#define AN_GPIO_ODR GPIOB->ODR
#define AN1 GPIO_ODR_7
#define AN2 GPIO_ODR_8
#define AN3 GPIO_ODR_9
#define AN4 GPIO_ODR_10
#define DOT_GPIO_ODR GPIOB->ODR
#define CDOT GPIO_ODR_11
#define ADOT GPIO_ODR_11

__IO uint8_t SegmentIndex = 0x01;
__IO uint8_t DigitIndex = 0;
__IO uint32_t Tick = 0;

uint16_t Counter = 0;
uint8_t DigitBuffer[4];
void SystemClock_Config(void);

//=======================
// TIM3 Interrupt Handler
//=======================
void TIM3_IRQHandler(void)
{
    if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
    {
        TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
        AN_GPIO_ODR &= ~( AN1 | AN2 | AN3 | AN4); // anodes off
        SEG_GPIO_ODR |= (SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG); //segment off
        SEG_GPIO_ODR &= (uint8_t)~SegmentIndex; // on one segment
        switch(DigitIndex)
        {
        case 0:
            if(DigitBuffer[3] & SegmentIndex) AN_GPIO_ODR |= AN1;
            break;
        case 1:
            if(DigitBuffer[2] & SegmentIndex) AN_GPIO_ODR |= AN2;
            break;
        case 2:
            if(DigitBuffer[1] & SegmentIndex) AN_GPIO_ODR |= AN3;
            break;
        case 3:
            if(DigitBuffer[0] & SegmentIndex) AN_GPIO_ODR |= AN4;
            break;
        default:
            break;
        }
        SegmentIndex <<= (uint8_t)0x01;
        if (SegmentIndex == 0)
        {
            SegmentIndex = (uint8_t)0x01;
            if(++DigitIndex == 4) DigitIndex = 0;
        }
        if(Tick > 0) Tick--;
        //GPIOB->ODR ^= GPIO_ODR_11;
    }
}

void Bin2Bcd(uint16_t value) // HHIMERA(c) copypast
{
    uint8_t *p = DigitBuffer;
    while (value > 0)
    {
        *p++ = seg7[value % 10];
        value /= 10;
    }
}

int main(void)
{
    //HAL_Init();
    /* Configure the system clock */
    SystemClock_Config();
    /* System interrupt init*/
    //HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    /* GPIOB Periph clock enable */
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
    GPIOB->MODER |=  (GPIO_MODER_MODER0_0 | GPIO_MODER_MODER1_0 |
                      GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0 |
                      GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_0 |
                      GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 |
                      GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0 |
                      GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0) ;    /* Configure PB0-PB12 in output  mode  */
    GPIOB->OTYPER &= ~( GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 |
                        GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_3 |
                        GPIO_OTYPER_OT_4 | GPIO_OTYPER_OT_5 |
                        GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 |
                        GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10 |
                        GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_12) ;   // Ensure push pull mode selected--default
    GPIOB->OSPEEDR |= ( GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 |
                        GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3 |
                        GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 |
                        GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 |
                        GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 |
                        GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12);    //Ensure maximum speed setting (even though it is unnecessary)
    GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR0 | GPIO_PUPDR_PUPDR1 |
                      GPIO_PUPDR_PUPDR2 | GPIO_PUPDR_PUPDR3 |
                      GPIO_PUPDR_PUPDR4 | GPIO_PUPDR_PUPDR5 |
                      GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7 |
                      GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10 |
                      GPIO_PUPDR_PUPDR11 | GPIO_PUPDR_PUPDR12);    //Ensure all pull up pull down resistors are disabled
    GPIOB->BSRRL = GPIO_BRR_BR_12;     // Set
    /* TIM3 clock enable */
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    TIM3->PSC = 48 - 1;       // Set prescaler to 48 = 48000000Hz/48 = 1000000 Hz = 1 us
    TIM3->ARR = 500 - 1;         // Auto reload value 500 = 500us
    TIM3->DIER = TIM_DIER_UIE; // Enable update interrupt (timer level)
    TIM3->CR1 = TIM_CR1_CEN;   // Enable timer
    NVIC_EnableIRQ(TIM3_IRQn); // Enable interrupt from TIM3 (NVIC level)
    while (1)
    {
        Bin2Bcd(Counter);
        Counter++;
        Tick = 2000;
        while (Tick);
    }
}

Воркает:
СпойлерИзображение

Ну вот получили почти часы, ну пусть не часы, а секундомер и ведь работает точно так же как и на стареньких, только ощущение, что как-то работаем по взрослому, а не упираемся во всякие ограничения - например захотел таймер чтобы переполнялся через 5 секунд - пожалуйста, захотел через 500 мкс - тоже пожалуйста и все легким движением руки. Молчу уже о математике - иногда надо быстро считать.
Занимаемое место: Program Size: Code=2236 RO-data=280 RW-data=36 ZI-data=1028
Можно и подсократить - куски HAL остались, но лень - вряд ли удастся заполонить всю флэш.
Это, понимаешь, часы! Они ходят, а потом бьют…(c)
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: ARM или не-ARM?

Сообщение dosikus »

КРАМ писал(а):dosikus, прочтите все сначала и уловите СМЫСЛ топика...
Не нужно ломиться в открытую дверь.
:)


А я собственно не для тебя стараюсь , тебе отвечая.
Да и смысла то никакого нет . те кто хотел давно на армы перешли .
А уговаривать адептов старья , неблагодарное занятие - все равно найдут отмазки, лишь бы их не трогали.
Пусть варятся в своем болоте ... :)))
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Продолжение.
Решил все таки ради интереса избавится от наследия HAL - вычистил проект от всего "лишнего". Та же програмка типа секундомер.
c HAL, там правда осталась только ХАЛовская настройка тактирования:
Program Size: Code=2236 RO-data=280 RW-data=36 ZI-data=1028
очищенная:
Program Size: Code=720 RO-data=236 RW-data=12 ZI-data=1028
С точки зрения пользователя стареньких получается очень много - в тини13 не войдет. Ну а пользователям армиков не жалко - "у нас этого гуталина..."
Если оставить чистый main:
Program Size: Code=300 RO-data=208 RW-data=0 ZI-data=1024
Получается стартап и настройка тактирования (а она очень мощная) заняли всего то жалких 300 байт. Наша програмка занимает совсем немного - 420 байт, что вполне так на уровне - может даже и лучше будет результат чем у стареньких, неохота сравнивать. Правда ассемблерщики на стареньких могут побороться, но думаю оно того не стоит.
на всякий случай пояснение:
Code - размер кода всего
RO-data - константы в коде (Read Only Data)
RW-data - переменные (Read Write Data)
ZI-data - переменные (Zero-Initialized Data)
Реклама
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: ARM или не-ARM?

Сообщение menzoda »

dosikus писал(а):те кто хотел давно на армы перешли

Меня расстраивает только отсутствие "специализированных" МК на основе ARM. Допустим, нету высокотемпературных (от 125 градусов) версий (у AD есть несколько слабеньких и у Infineon парочка). Очень мало простых МК в маленьких корпусах типа SOIC (хотя, последнее время стали появляться). Нету МК со всякими интересными штуками на борту, типа FRAM как у некоторых MSP430.

А так нормально, если не считать, что мне не нравится куда они ушли с архитектурой ARMv7-M, ARMv4T была поприятнее, но это другой разговор.
Реклама
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: ARM или не-ARM?

Сообщение HHIMERA »

Можно подумать... надобность в "специализированных" МК просто глобальная... :)
oleg110592 писал(а): Наша програмка занимает совсем немного - 420 байт, что вполне так на уровне - может даже и лучше будет результат чем у стареньких, неохота сравнивать. Правда ассемблерщики на стареньких могут побороться, но думаю оно того не стоит.

Заюзай ДМА... код ещё уменьшится... АВР/ПИК просто забьются в истерике... :)
Но смысла действительно в этом нет... Здесь важнее свобода действий и свобода выбора реализации...
Последний раз редактировалось ibiza11 Вт июл 01, 2014 11:34:16, всего редактировалось 1 раз.
Причина: Нарушение п.2.2 Правил форума. Предупреждение.
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

МК на основе ARM. Допустим, нету высокотемпературных (от 125 градусов)

ну почему же:
http://www.freescale.com/webapp/sps/sit ... staticFile
и корпуса есть маленькие: 16-pin TSSOP 5x6.4 mm, 24-pin QFN 4x4 mm
А Сhrom art accelerator разве не интересная штука - где еще есть?

DMA еще впереди
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: ARM или не-ARM?

Сообщение menzoda »

HHIMERA писал(а):Можно подумать... надобность в "специализированных" МК просто глобальная... :)

Конечно не глобальна, поэтому я и говорю, что в принципе все ОК, но иногда все же возникает такая необходимость и очень не хочется из-за этого использовать другой МК, тянущий за собой свои отладчики, компиляторы, среды разработки, неизведанные грабли и т.п.

oleg110592 писал(а):ну почему же:
http://www.freescale.com/webapp/sps/sit ... staticFile
и корпуса есть маленькие: 16-pin TSSOP, 24-pin QFN 4x4 mm

Действительно. Что же, хорошо, ситуация потихоньку исправляется.

oleg110592 писал(а):А Сhrom art accelerator разве не интересная штука - где еще есть?

С этим никогда не сталкивался, поэтому ничего не могу сказать.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Даже Renesas Cortex ядро начал применять - ну практически все производители микроконтроллеров "полюбили" ARM. Только обидно, что любимая фирма Microchip почему то пыжится с MIPSами.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: ARM или не-ARM?

Сообщение dosikus »

oleg110592 писал(а): Microchip почему то пыжится с MIPSами.


Ну бабло то вбухано уже ... :)))
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: ARM или не-ARM?

Сообщение HHIMERA »

Дык... Микрочип начал осваивать МИПС до всеобщего "АРМ-одобрямс"...

menzoda писал(а):не хочется из-за этого использовать другой МК, тянущий за собой свои отладчики, компиляторы, среды разработки, неизведанные грабли и т.п.

В этом свете Cortex (STM в частности) выглядит более перспективным... т.к. охватывает наибольший круг задач... а исключения всегда бывают...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Продолжение.
Пока ждал заказчика появилось немного времени. И так, такой способ динамической индикации (в прерывании таймера) имеет один существенный недостаток. Например нам надо дрыгать ногами с точными временными интервалами - известный датчик DS18B20 требует именно такого подхода. Выставили в "1" ногу порта и ожидаем пока не истечет нужное время, а тут бац и прерывание и все наши времена полетели в неизвестную даль. Конечно это все легко обходится, но требует лишних телодвижений. А тут разработчики микроконтроллеров на ядре АРМ подложили нам приятный сюрприз в виде DMA (есть еще в STM8L и вроде в XMEGAх).

Пришло время рассказать об одной потрясающей штуке под названием DMA(ПДП) – то есть прямой доступ к памяти (Direct Memory Access). Поясню что же это такое.
В двух словах – прямой доступ к памяти позволяет перемещать данные без(!) участия центрального процессора. То есть процессор работает себе преспокойненько, не отвлекается ни на что, а DMA в этот момент может пересылать огромные массивы данных, например, в USART. Думаю сразу понятно насколько это полезно, ведь процессору теперь не надо отвлекаться от основной полезной работы.
А в контроллерах STM32F10x даже не один, а два контроллера прямого доступа к памяти! И, соответственно, у каждого несколько каналов (у DMA1 – 7, а у DMA2 – 5).

Пробуем применить для динамической индикации. Опять наш товарищ HHIMERA уже прошел тяжелый джедайский путь в освоении DMA и любезно выложил код с коментариями на известном форуме "Казус" http://kazus.ru/forums/showpost.php?p=7 ... ostcount=8
Воспользуемся его трудами - копипастим и чуть правим под нашу задачу:
Спойлер

Код: Выделить всё

#include "stm32f0xx.h"

#define SegA   (uint8_t)1<<0
#define SegB   (uint8_t)1<<1
#define SegC   (uint8_t)1<<2
#define SegD   (uint8_t)1<<3
#define SegE   (uint8_t)1<<4
#define SegF   (uint8_t)1<<5
#define SegG   (uint8_t)1<<6
#define SegH   (uint8_t)1<<7

#define digit_0   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF)
#define digit_1   (uint8_t)(SegB | SegC)
#define digit_2   (uint8_t)(SegA | SegB | SegG | SegE | SegD)
#define digit_3   (uint8_t)(SegA | SegB | SegG | SegC | SegD)
#define digit_4   (uint8_t)(SegF | SegG | SegB | SegC)
#define digit_5   (uint8_t)(SegA | SegF | SegG | SegC | SegD)
#define digit_6   (uint8_t)(SegA | SegF | SegE | SegD | SegC | SegG)
#define digit_7   (uint8_t)(SegA | SegB | SegC)
#define digit_8   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF | SegG)
#define digit_9   (uint8_t)(SegA | SegB | SegC | SegD | SegF | SegG)

const uint8_t seg7[10] =
{
    digit_0,
    digit_1,
    digit_2,
    digit_3,
    digit_4,
    digit_5,
    digit_6,
    digit_7,
    digit_8,
    digit_9
};

#define SEG_GPIO_ODR GPIOB->ODR
#define SEGA GPIO_ODR_0
#define SEGB GPIO_ODR_1
#define SEGC GPIO_ODR_2
#define SEGD GPIO_ODR_3
#define SEGE GPIO_ODR_4
#define SEGF GPIO_ODR_5
#define SEGG GPIO_ODR_6
#define AN_GPIO_ODR GPIOB->ODR
#define AN1 GPIO_ODR_7
#define AN2 GPIO_ODR_8
#define AN3 GPIO_ODR_9
#define AN4 GPIO_ODR_10
#define DOT_GPIO_ODR GPIOB->ODR
#define CDOT GPIO_ODR_11
#define ADOT GPIO_ODR_12

__IO uint8_t SegmentIndex = 0x01;
__IO uint8_t DigitIndex = 0;
__IO uint32_t Tick = 0;

uint16_t Counter = 0;
uint8_t DigitBuffer[4];

uint16_t DataBuffer[4*7]=
{
    0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
    0x017F, 0x017F, 0x017F, 0x017F, 0x017F, 0x017F, 0x017F,
    0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F,
    0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F
 };

uint16_t BufferTIM[4*7]=
{
    500, 500, 500, 500, 500, 500, 500,
    500, 500, 500, 500, 500, 500, 500,
    500, 500, 500, 500, 500, 500, 500,
    500, 500, 500, 500, 500, 500, 500   
};

void Bin2Bcd(uint16_t value) // HHIMERA(c) copypast
{
    uint8_t *p = DigitBuffer;
    while (value > 0)
    {
        *p++ = seg7[value % 10];
        value /= 10;
    }
}

void GPIOInit(void)
{
    /* GPIOB Periph clock enable */
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
    GPIOB->MODER |=  (GPIO_MODER_MODER0_0 | GPIO_MODER_MODER1_0 |
                      GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0 |
                      GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_0 |
                      GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 |
                      GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0 |
                      GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0) ;    /* Configure PB0-PB12 in output  mode  */
    GPIOB->OTYPER &= ~( GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 |
                        GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_3 |
                        GPIO_OTYPER_OT_4 | GPIO_OTYPER_OT_5 |
                        GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 |
                        GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10 |
                        GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_12) ;   // Ensure push pull mode selected--default
    GPIOB->OSPEEDR |= ( GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 |
                        GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3 |
                        GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 |
                        GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 |
                        GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 |
                        GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12);    //Ensure maximum speed setting (even though it is unnecessary)
    GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR0 | GPIO_PUPDR_PUPDR1 |
                      GPIO_PUPDR_PUPDR2 | GPIO_PUPDR_PUPDR3 |
                      GPIO_PUPDR_PUPDR4 | GPIO_PUPDR_PUPDR5 |
                      GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7 |
                      GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10 |
                      GPIO_PUPDR_PUPDR11 | GPIO_PUPDR_PUPDR12);    //Ensure all pull up pull down resistors are disabled
    DOT_GPIO_ODR ^= ADOT;     // Set  pin ADOT
}   

void DMAInit(void)
{   
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;
       
    DMA1_Channel3->CPAR = (uint32_t)&GPIOB->ODR;     // DMA channel x peripheral address register
    DMA1_Channel3->CMAR = (uint32_t)DataBuffer;     // DMA channel x memory address register   
    DMA1_Channel3->CNDTR = 4*7;                       // DMA channel x number of data register

    DMA1_Channel3->CCR  |=  DMA_CCR_MSIZE_0;         // Memory size 16 bit
    DMA1_Channel3->CCR  |=  DMA_CCR_PSIZE_0;         // Peripheral size 16 bit

    DMA1_Channel3->CCR  |=  DMA_CCR_PL_1;            // Channel Priority level High
    DMA1_Channel3->CCR  |=  DMA_CCR_MINC;            // Memory increment mode
    DMA1_Channel3->CCR  |=  DMA_CCR_CIRC;            // Circular mode
    DMA1_Channel3->CCR  |=  DMA_CCR_DIR;             // Data transfer direction Memory -> Peripheral

    DMA1_Channel3->CCR  |=  DMA_CCR_EN;              // Channel enable
   
    //----------
    DMA1_Channel4->CPAR = (uint32_t)&TIM3->ARR;      // DMA channel x peripheral address register
    DMA1_Channel4->CMAR = (uint32_t)BufferTIM;      // DMA channel x memory address register   
    DMA1_Channel4->CNDTR = 4*7;                   // DMA channel x number of data register

    DMA1_Channel4->CCR  |=  DMA_CCR_MSIZE_0;         // Memory size 16 bit
    DMA1_Channel4->CCR  |=  DMA_CCR_PSIZE_0;         // Peripheral size 16 bit

    DMA1_Channel4->CCR  |=  DMA_CCR_PL;              // Channel Priority level Very High
    DMA1_Channel4->CCR  |=  DMA_CCR_MINC;            // Memory increment mode
    DMA1_Channel4->CCR  |=  DMA_CCR_CIRC;            // Circular mode
    DMA1_Channel4->CCR  |=  DMA_CCR_DIR;             // Data transfer direction Memory -> Peripheral

    DMA1_Channel4->CCR  |=  DMA_CCR_EN;              // Channel enable
}

void TIM3Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;   // TIM3 clock enable

    TIM3->PSC  = 48 - 1;   
    TIM3->ARR  = 500 - 1;

    TIM3->CCR1 = 25;                                   
           
    TIM3->DIER  |= TIM_DIER_UDE;                    // Upload DMA Enable
    TIM3->DIER  |= TIM_DIER_CC1DE;
           
    TIM3->CR1   |= TIM_CR1_CEN | TIM_CR1_ARPE;      // Counter Enable
}
void Copy2Buffer()
{
    uint16_t n;
    DigitIndex = 0x01;   
    for (n = 0; n < 7; n++)
    {
        if(DigitBuffer[3] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & 0x00FF ;
        else DataBuffer[n] = 0x00FF;
        DigitIndex <<= 0x01;
    }
    DigitIndex = 0x01;   
    for (n = 7; n < 14; n++)
    {
        if(DigitBuffer[2] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & 0x017F ;
        else DataBuffer[n] = 0x017F;
        DigitIndex <<= 0x01;
    }
    DigitIndex = 0x01;   
    for (n = 14; n < 21; n++)
    {
        if(DigitBuffer[1] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & 0x027F ;
        else DataBuffer[n] = 0x027F;
        DigitIndex <<= 0x01;
    }
    DigitIndex = 0x01;   
    for (n = 21; n < 28; n++)
    {
        if(DigitBuffer[0] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & 0x047F ;
        else DataBuffer[n] = 0x047F;
        DigitIndex <<= 0x01;
    }       
}
   
int main(void)
{
    GPIOInit();   
    DMAInit();   
    TIM3Init();

    Counter = 1234;   
    Bin2Bcd(Counter);
    Copy2Buffer(); 
   
    while (1)
    {
    }
}

Програмка должна отобразить на индикаторе "1234", что она успешно и делает - фото не выкладываю - поверьте на слово.
Нет никаких прерываний и теперь микроконтроллер должен втихаря петь песню:
Я свободен, словно птица в небесах.
Я свободен, я забыл, что значит страх.
Я свободен, с диким ветром наравне.
Я свободен, наяву, а не во сне

Размерчик чуть подрос:
Program Size: Code=924 RO-data=236 RW-data=120 ZI-data=1024
но оно того стоит.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: ARM или не-ARM?

Сообщение dosikus »

oleg110592 писал(а):Размерчик чуть подрос:


Дык озвучь что там еще и автоматическая коррекция разнояркости символов... :)))
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: ARM или не-ARM?

Сообщение HHIMERA »

Олег... там канал 4 и один массив действительно лишний... тебе же коррекция не нужна...
И Copy2Buffer слегка монструозный... но в принципе сути не меняет... если выводимые данные меняются не часто...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Назвался груздем - полезай в кузов.
Продолжение.
Одной из самых полезных функций, включенных в состав микроконтроллеров STM32 стали часы реального времени (RTC). Данный модуль обладает всеми классическими возможностями подобных часов и может иметь отдельное автономное питание от батареи. Такой подход позволяет использовать область памяти часов для резервного хранения данных, а также реализовывать различные схемы энергосбережения.
Основу модуля часов реального времени составляет двоично-десятичный таймер/счетчик. Результат счета отображается в двух 32-разрядных регистрах. Первый из них RTC_TR содержит информацию о времени, второй – RTC_DR представляет собой календарь, включающий год, месяц, неделю и день. Все данные представлены в BCD формате, что позволяет их сразу же использовать для отображения на различных индикаторах. Модуль календаря поддерживает автоматическое определение високосных лет, а также количества дней в текущем месяце. Кроме этого доступны функции перевода на зимнее и летнее время, вызываемые программно.
Среди функций модуля RTC следует отметить два отдельных регистра событий (ALARM_x), с помощью которых можно реализовать будильники, таймеры и т.п. Формат регистров событий аналогичен счетным регистрам, что несколько упрощает их программирование. Еще одним событием, формируемым RTC, может стать сигнал выхода из спящего режима (WakeUP). Данный сигнал формируется периодически, что позволяет легко реализовывать различные системы, критичные к энергопотреблению. Счетчик выхода из спящего режима работает независимо от часов/календаря. Максимальное значение периода сна составляет примерно 48 суток.
Модуль часов расположен в отдельной области памяти, имеющей возможность внешнего питания от батареи. Регистры RTC оснащены дополнительной защитой от записи, что обеспечивает невозможность случайного повреждения информации в них. Кроме часовых регистров в модуле выполнены 12 регистров резервирования пользовательских данных с разрядностью 32. Эти регистры не обнуляются по сигналу «Сброс» при наличии внешнего источника напряжения, что позволяет хранить в них важную информацию.


Так как мы делаем часы - грех не воспользоваться еще одной замечательной возможностью микроконтроллеров STM32. Читаем документацию и AN3371 Application note Using the hardware real-time clock (RTC) in STM32 F0, F2, F3, F4 and L1 series of MCUs, смотрим примеры, любезно предоставленные производителем нашего микроконтроллера. Пробуем применить:
Спойлер

Код: Выделить всё

#include "stm32f0xx.h"

#define SegA   (uint8_t)1<<0
#define SegB   (uint8_t)1<<1
#define SegC   (uint8_t)1<<2
#define SegD   (uint8_t)1<<3
#define SegE   (uint8_t)1<<4
#define SegF   (uint8_t)1<<5
#define SegG   (uint8_t)1<<6
#define SegH   (uint8_t)1<<7

#define digit_0   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF)
#define digit_1   (uint8_t)(SegB | SegC)
#define digit_2   (uint8_t)(SegA | SegB | SegG | SegE | SegD)
#define digit_3   (uint8_t)(SegA | SegB | SegG | SegC | SegD)
#define digit_4   (uint8_t)(SegF | SegG | SegB | SegC)
#define digit_5   (uint8_t)(SegA | SegF | SegG | SegC | SegD)
#define digit_6   (uint8_t)(SegA | SegF | SegE | SegD | SegC | SegG)
#define digit_7   (uint8_t)(SegA | SegB | SegC)
#define digit_8   (uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF | SegG)
#define digit_9   (uint8_t)(SegA | SegB | SegC | SegD | SegF | SegG)

const uint8_t seg7[10] =
{
    digit_0,
    digit_1,
    digit_2,
    digit_3,
    digit_4,
    digit_5,
    digit_6,
    digit_7,
    digit_8,
    digit_9
};

#define SEG_GPIO_ODR GPIOB->ODR
#define SEGA GPIO_ODR_0
#define SEGB GPIO_ODR_1
#define SEGC GPIO_ODR_2
#define SEGD GPIO_ODR_3
#define SEGE GPIO_ODR_4
#define SEGF GPIO_ODR_5
#define SEGG GPIO_ODR_6
#define AN_GPIO_ODR GPIOB->ODR
#define AN1 GPIO_ODR_7
#define AN2 GPIO_ODR_8
#define AN3 GPIO_ODR_9
#define AN4 GPIO_ODR_10
#define DOT_GPIO_ODR GPIOB->ODR
#define CDOT GPIO_ODR_11
#define ADOT GPIO_ODR_12

__IO uint8_t SegmentIndex = 0x01;
__IO uint8_t DigitIndex = 0;
__IO uint32_t Tick = 0;

uint16_t Counter = 0;
uint8_t DigitBuffer[4];
uint16_t DotMask = 0x1800;

uint16_t DataBuffer[4*7]=
{
    0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
    0x017F, 0x017F, 0x017F, 0x017F, 0x017F, 0x017F, 0x017F,
    0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F, 0x027F,
    0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F, 0x047F
 };

void GPIOInit(void)
{
    /* GPIOB Periph clock enable */
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
    GPIOB->MODER |=  (GPIO_MODER_MODER0_0 | GPIO_MODER_MODER1_0 |
                      GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0 |
                      GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_0 |
                      GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 |
                      GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0 |
                      GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0) ;    /* Configure PB0-PB12 in output  mode  */
    GPIOB->OTYPER &= ~( GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 |
                        GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_3 |
                        GPIO_OTYPER_OT_4 | GPIO_OTYPER_OT_5 |
                        GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 |
                        GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10 |
                        GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_12) ;   // Ensure push pull mode selected--default
    GPIOB->OSPEEDR |= ( GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 |
                        GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3 |
                        GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 |
                        GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 |
                        GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 |
                        GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12);    //Ensure maximum speed setting (even though it is unnecessary)
    GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR0 | GPIO_PUPDR_PUPDR1 |
                      GPIO_PUPDR_PUPDR2 | GPIO_PUPDR_PUPDR3 |
                      GPIO_PUPDR_PUPDR4 | GPIO_PUPDR_PUPDR5 |
                      GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7 |
                      GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10 |
                      GPIO_PUPDR_PUPDR11 | GPIO_PUPDR_PUPDR12);    //Ensure all pull up pull down resistors are disabled
    DOT_GPIO_ODR ^= ADOT;     // Set  pin ADOT
}   

void DMAInit(void)
{   
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;
       
    DMA1_Channel3->CPAR = (uint32_t)&GPIOB->ODR;     // DMA channel x peripheral address register
    DMA1_Channel3->CMAR = (uint32_t)DataBuffer;     // DMA channel x memory address register   
    DMA1_Channel3->CNDTR = 4*7;                       // DMA channel x number of data register

    DMA1_Channel3->CCR  |=  DMA_CCR_MSIZE_0;         // Memory size 16 bit
    DMA1_Channel3->CCR  |=  DMA_CCR_PSIZE_0;         // Peripheral size 16 bit

    DMA1_Channel3->CCR  |=  DMA_CCR_PL_1;            // Channel Priority level High
    DMA1_Channel3->CCR  |=  DMA_CCR_MINC;            // Memory increment mode
    DMA1_Channel3->CCR  |=  DMA_CCR_CIRC;            // Circular mode
    DMA1_Channel3->CCR  |=  DMA_CCR_DIR;             // Data transfer direction Memory -> Peripheral

    DMA1_Channel3->CCR  |=  DMA_CCR_EN;              // Channel enable
}

void TIM3Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;   // TIM3 clock enable

    TIM3->PSC  = 48 - 1;   
    TIM3->ARR  = 500 - 1;

    TIM3->CCR1 = 25;                                   
           
    TIM3->DIER  |= TIM_DIER_UDE;                    // Upload DMA Enable
    TIM3->DIER  |= TIM_DIER_CC1DE;
           
    TIM3->CR1   |= TIM_CR1_CEN | TIM_CR1_ARPE;      // Counter Enable
}

void Configure_RTC(void)
{
  /* Enable the peripheral clock RTC */
  /* (1) Enable the LSI */
  /* (2) Wait while it is not ready */
  /* (3) Enable PWR clock */
  /* (4) Enable write in RTC domain control register */
  /* (5) LSI for RTC clock */
  /* (6) Disable PWR clock */
  RCC->CSR |= RCC_CSR_LSION; /* (1) */
  while((RCC->CSR & RCC_CSR_LSIRDY)!=RCC_CSR_LSIRDY) /* (2) */
  {
    /* add time out here for a robust application */
  }
  RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* (3) */
  PWR->CR |= PWR_CR_DBP; /* (4) */
  RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1; /* (5) */
  RCC->APB1ENR &=~ RCC_APB1ENR_PWREN; /* (7) */
}

void Init_RTC(uint32_t Time)
{
  /* RTC init mode */
  /* Configure RTC */
  /* (1) Write access for RTC registers */
  /* (2) Enable init phase */
  /* (3) Wait until it is allow to modify RTC register values */
  /* (4) set prescaler, 40kHz/128 => 312 Hz, 312Hz/312 => 1Hz */
  /* (5) New time in TR, 24-hour format */
  /* (6) Disable init phase */
  /* (7) Disable write access for RTC registers */
  RTC->WPR = 0xCA; /* (1) */
  RTC->WPR = 0x53; /* (1) */
  RTC->ISR |= RTC_ISR_INIT; /* (2) */
  while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF) /* (3) */
  {
    /* add time out here for a robust application */
  }
  RTC->PRER = 0x007F0137; /* (4) */
  RTC->TR = RTC_TR_PM | Time; /* (5) */
  RTC->ISR &=~ RTC_ISR_INIT; /* (6) */
  RTC->WPR = 0xFE; /* (7) */
  RTC->WPR = 0x64; /* (7) */
}

void Copy2Buffer()
{
    uint16_t n, k = 0x00FF, c = 3;
    DigitIndex = 0x01;   
    for (n = 0; n < 28; n++)
    {
        if(n==7)
        {
            k = 0x017F;
            c = 2;
            DigitIndex = 0x01;
        }
        if(n==14)
        {
            k = 0x027F;
            c = 1;
            DigitIndex = 0x01;
        }
        if(n==21)
        {
            k = 0x047F;
            c = 0;
            DigitIndex = 0x01;
        }       
        if(DigitBuffer[c] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & k ;
        else DataBuffer[n] = k;
        if(n==0) DataBuffer[n] ^= DotMask;
        DigitIndex <<= 0x01;
    }
}
   
int main(void)
{
    volatile uint32_t TimeToCompute = 0;
    volatile uint32_t DateToCompute = 0;
    uint8_t Su, LastSu = 0;
    GPIOInit();   
    DMAInit();   
    TIM3Init();
    Configure_RTC();
    Init_RTC(0);
   
    while (1)
    {
        while(LastSu == Su)
        {   
            TimeToCompute = RTC->TR; /* get time */
            DateToCompute = RTC->DR; /* need to read date also */
            Su = (uint8_t)(TimeToCompute & RTC_TR_SU);
        }
        LastSu = Su;
        DigitBuffer[1] = seg7[(uint8_t)((TimeToCompute & RTC_TR_ST)>>4)];
        DigitBuffer[0] = seg7[(uint8_t)(TimeToCompute & RTC_TR_SU)];
        DigitBuffer[3] = seg7[(uint8_t)((TimeToCompute & RTC_TR_MNT)>>12)];
        DigitBuffer[2] = seg7[(uint8_t)((TimeToCompute & RTC_TR_MNU)>>8)];
        DotMask ^= 0x0800;
        Copy2Buffer();
     }
}


Убрал ненужный теперь bin2bcd и регулировку яркости, чуть оптимизировал copy2buffer. На индикатор выводятся минуты и секунды, но можно вывести и часы и день недели, месяц, год. Точечки мигают - 1 с светятся, 1 с нет. Обновление на индикаторе раз в секунду.
Размер программы: Code=916 RO-data=236 RW-data=64 ZI-data=1024.
Легко влезет с большим запасом в в классику TINY2313, но почему-то производитель не заложил в этом микроконтроллере ни DMA ни RTC. Что это жадность или наплевательское отношение к пользователям? Разве трудно было сделать какую нибудь типа TINY2313D с вышеперечисленными модулями, ведь сделали же picoPower version: ATtiny2313A.
Поставленная задача считаю выполнена - часы работают, добавить кнопки для установки времени , будильников и прочего - рутинная работа, совсем не трудная.
В общем оказалось, ничего уж такого сложного в этих армах как бы и нет - постепенно, не напрягаясь, можно освоить работу с портами, таймерами, пдп, ртц и другими модулями этих замечательных микроконтроллеров. Непонятно зачем тратить время на изучение пиков, пусть даже «улучшенной» серии чтобы написать на ассемблере часы, постоянно упираясь в ограничения старых технологий. Напоминает мазохизм, типа "стоя, в противогазе и в гамаке". Как это может помочь в последующем изучении более продвинутых микроконтроллеров?
И начинающим непонятно зачем учится на устаревших микроконтроллерах, если все равно необходимо знание английского и знание языка программирования Си. А чтобы учится, производители микроконтроллеров на ядре ARM (в частности ST) сделали все возможное.
А если бы в микроконтроллерах ядро ARM было изначально? Т.е. не Intel бы начала? Мы б сейчас спорили как тяжелы эти 51 микроконтроллеры, ох начинающим их никак не освоить - лучше на армах начинать.
Кто покажет тот порог, который отличает изучение пик, авр от изучения стм32. Мне кажется стм32 все таки легче изучать и главное - намного перспективнее.
Вот сегодня на форуме начинающий спрашивал о неработающей программе на меге128, а вот о фузе (M103C) он не знал, хотя об этом написано 4 странице документации и в интернете есть подобные вопросы с ответами. О том, что на фига этот фуз нужен уж молчу - ну выпускайте и мегу103 и мегу128. Да еще жытаг по умолчанию включен - порт не работает, тоже частый вопрос. Что это? Легкость изучения авр, когда не надо читать документацию, и полно готовых говнопримеров (зачастую не работающих) или это элементарная лень? Предвзятости меня к авр нет - меня устраивает для многих задач любимая мега48, только чуть подправить ее внутренности бы - добавить PLL (в тини некоторых почему то есть), добавить deadtime в в таймере (тоже в тини некоторых есть), таймеров бы 16 разрядных парочку (без RTC обойдусь), добавить ОУ (в некоторых мегах он есть) убрать параллельное программирование с фузами (лучше из программы фузы настраивать), добавить будлоадер, не занимающий основную флэш и программировать по компорту, или по USB (тоже в некоторых есть) - получается практически STM8S003, а он уже есть и дешевле меги48.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Не реклама (патамушта не дилер). Может кому интересно.
У наших барыг появились новая, очень симпатичная Отладочная плата на базе микроконтроллера STM32F030R8T6. Цена 326 Грн. (~30$) - в принципе не дорого (бонус - на борту полноценный программатор/отладчик) . Цена у ST - 10.12$. Отладчик/программатор на борту легким движением руки отламывается, превращаясь в автономное, очень полезное устройство. К основному, оставшемуся куску можно пристыковывать великое множество уже готовых shield (всякие там эзернеты, ви-фи, жпрс, реле, датчики и пр.). Любители ардуино могут писать в среде онлайн mbed, пользуясь набором высокоуровневых объектно ориентированных библиотек, которые реализуют взаимодействие с большинством интерфейсов ввода-вывода, имеющихся на плате. Но джедаи могут и обычным, дедовским способом - напрямую с железом.
Есть подобные платы и под другие микроконтроллеры.
Описание
Отладочная плата на базе микроконтроллера STM32F030R8T6, представляет собой гибкую платформу, позволяющую расширять свои функциональные возможности с помощью плат расширения для Arduino и ST Morpho. Для программирования не требуется внешнего программатора-отладчика, так как плата оснащена встроенным эмулятором ST-LINK/V2. Плата поставляется с программной библиотекой HAL, примерами программ и доступом к он-лайн ресурсу mbed.org
Особенности:
- Микроконтроллер STM32F030R8T6;
- Совместимость с платами расширения Arduino Uno R3 и ST Morpho;
- Поддержка mbed.org;
- Встроенный программатор-отладчик ST-LINK/V2;
- Возможность использования платы в качестве программатора ST-LINK/V2;
- Гибкая система подачи внешнего питания;
- Три светодиода;
- Две кнопки (Пользователь, Сброса);
- Поддержка через USB виртуального COM-порта, внешнего накопителя и отладочного порта;
- Программная библиотека HAL, включающая примеры кодов;
- Поддержка сред разработки IAR, KEIL и IDE

Мигание светодиодом на mbed:

Код: Выделить всё

#include "mbed.h"

DigitalOut myled(LED1);

int main() {
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

все очень просто
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: ARM или не-ARM?

Сообщение HHIMERA »

Олег...
TIM3->DIER |= TIM_DIER_CC1DE;
лишняя... коррекция то убрана...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: ARM или не-ARM?

Сообщение oleg110592 »

Спасибо - пропустил, значит теперь и в тини13 по объему влезет... 8)
Да - забыл название отладочной платы: NUCLEO-F030R8
Россиянам можно купить, например тут: http://www.chipdip.ru/news/stm32-nucleo ... ent-board/
ST предлагает такие платы на разных 64-ногих микроконтроллерах от F0 до F4 :
Изображение
По сути это одна плата, но впаяны разные микроконтроллеры (вот же молодцы - нет разнобоя в разных сериях). Файлы для этих плат (схема, печатная плата в формате любимого Altium) и герберов ST для свободного скачивания лежат на сайте ST. Можно самому заказать - утюгом вряд ли получится. Можно использовать куски схемы для создания своих плат - все готово для свободного творчества.
Аватара пользователя
abc
Друг Кота
Сообщения: 3684
Зарегистрирован: Чт мар 20, 2008 01:06:40
Откуда: Севастополь

Re: ARM или не-ARM?

Сообщение abc »

...по идее, ОНО просто обязано влезть во что угодно, ибо :

Program Memory Words Used: 259
Program Memory Words Free: 16125

Это, повторюсь, часы на PIC16F1938 c "набортным" RTC, ШИМ-ом для управления высоковольтным преобразователем для никсей и все тем же микропотреблением.
Для более дешевого PIC16F1516 :
Program Memory Words Used: 222
Program Memory Words Free: 7970

Поэтому все же надо ждать _непосильных_ для ПИК-ов задач, а то на моргании/часиках и прочей ... эээ... любительщине все навороты STM не сильно впечатляют.
Ответить

Вернуться в «МЯЯЯУ!»