[Программирование микроконтроллеров, Электроника для начинающих] На распутье — Ардуино, Cи или Ассемблер?
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Сначала короткая предыстория появления этого поста. Относительно давно, помигав светодиодом, захотелось сделать что-то полезное. Так появился Беспроводной программируемый по Wi-Fi комнатный термостат с монитором качества воздуха и другими полезными функциями. Как назло, в это время перестал работать мой промышленный термостат. Меня выручила еще сырая поделка, наспех спрятанная в картонную коробочку. За время отопительного сезона напрягал лишь один недостаток прототипа – это необходимость таскать по квартире удлинитель 220В и кабель, который всегда путался под шваброй ногами. Поэтому решил сделать нечто похожее, но автономное, притом, с питанием от батареек, как в серийном образце. Тут я завис надолго.
Приступая к задаче, для меня было очевидно одно – вряд ли программы промышленных автономных устройств составлены на платформе Arduino IDE. Где все спрятано в громоздкие тяжеловесные библиотеки, а простые коды (скетчи) занимают в редакторе несколько десятков строк, делая работу в этой среде комфортной и не требующей особых усилий. Уточню сразу – дальше речь выборе языка программирования между Ардуино, Си или Ассемблером. Хотя, понятно, на потреблении устройства в целом сказывается слишком много факторов таких, как энергопотребление подключенных модулей, потребление самого контроллера, который управляет периферией, не последнюю роль тут играет оптимальное построение самого кода и алгоритм работы устройства.
«… направу ехати — женату быти; налеву ехати — богату быти»
В начале пути, перед выбором направления меня оптимистично настроила статья Почему многие не любят Arduino. Ниже, для наглядности, картинка оттуда с кодом «мигалки».
Пример слева написан на языке Ардуино, а справа — работа непосредственно с регистрами. Код на Ардуино выглядит несколько компактней, чем та же «мигалка», но с использованием регистров.
На изображении ниже — компиляция кода «мигалки» на Ассемблере. Как видно, былая компактность испарилась – количество строк в 3 раза больше, чем в Ардуино.
И так, с 2 картинок выше видно – размер памяти, занимаемой в контроллере кодом «мигалки» одним светодиодом, написанным на Ардуино, составляет 1030 байт, на Си – 176 байт, на Ассемблере – 42 байта.
Теперь взглянем на более сложный код. Поскольку в своих проектах использую модуль давления-температуры BMP280, составил код барометра-термометра на Си, чтобы заодно была какая-то польза.
барометр-термометр на Си
SPL
/*
На распутье - Ардуино, Cи или Ассемблер?
https://habr.com/ru/post/547752/
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bmp180/bmp180.c"
#include "uart.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nokia/nokia5110.h"
int main(void) {
serial_init();
DDRD |= (1 << 7); //pin 13, atmega328p
PORTD &= ~(1 << 7);
nokia_lcd_init();
while (1) {
init_sensor(bmp180_mode_0);
calculate();
PORTD |= (1 << 7);
_delay_ms(100);
printf("Temperature: %.2f C, Pressure: %.2f Pa, \n", (float) bmp_180.temperature / 10, (float)bmp_180.pressure);
nokia_lcd_clear();
nokia_lcd_write_string("789",1);
nokia_lcd_set_cursor(0, 10);
nokia_lcd_write_string("22.2", 3);
nokia_lcd_render();
_delay_ms(2000);
PORTD &= ~(1 << 7);
_delay_ms(100);
int a=54325;
char buffer[20];
itoa(a,buffer,2); // here 2 means binary
printf("Binary value = %s\n", buffer);
itoa(a,buffer,10); // here 10 means decimal
printf("Decimal value = %s\n", buffer);
itoa(a,buffer,16); // here 16 means Hexadecimal
printf("Hexadecimal value = %s\n", buffer);
}
return 0;
}
В проект входят следующие компоненты: контроллер ATMEGA328P, модуль давления-температуры BMP180 и дисплей Nokia 3110. ATMEGA328P принимает инфу с датчика BMP180 и после преобразований отображает ее на дисплее Nokia 3110, затем спит. Сон задается сторожевым таймером Watchdog. Проект собирается в Atmel Studio 7 и эмулируется в Proteus 8 Pro. Этот проект Atmel Studio был создан для отладки кода в Proteus'e. В библиотеке Proteus 8 Pro модуля BMP280 нет, поэтому пришлось составить код с включением BMP180. Светодиод в коде — для наглядности, чтобы придать динамику статичной картинке.
Ниже — электрическая схема устройства. При монтаже схемы обращайте внимание на функциональное назначение выводов контроллера и модулей. Подключение кварца — XTAL1, XTAL2 (ATMEGA328P). Уточню, схему барометра-термометра на BMP180 я "в железе" не собирал, поэтому тут могут проявиться проблемы, которые не видны при эмуляции в Proteus'e.
Для скачивания zip-файла проекта в Atmel Studio 7 перейдите по ссылке – тут все виртуальные проекты и коды программ из этой публикации.
Файл прошивки bmp180-nokia3110-watchdog-1.hex для Proteus'а находится в папке Debug. В файле main.c есть закомментированный код барометра-термометра на BMP280. Его электрическая схема такая же, как и у барометра-термометра на BMP180. Он успешно собирается в Atmel Studio 7 и работает "в железе". Для работы "в железе" пришлось внести изменения в строке #define BMP280_ADDR 0x77 файла библиотеки bmp280.c, а именно: заменить начальный адрес 0x77 на 0x76. Не забудьте сделать эту корректировку, если будете использовать в своих проектах код барометра-термометра на BMP280 из main.c, с уже подключенной библиотекой bmp280.c.
Ниже — код этого же барометра-термометра в платформе Arduino IDE. Естественно, с другими библиотеками.
барометр-термометр на Ардуино
SPL
/*
На распутье - Ардуино, Cи или Ассемблер?
https://habr.com/ru/post/547752/
*/
#include <SPI.h>
#include <LowPower.h>
#include <SimpleTimer.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_GFX.h> //https:esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942
#include <Adafruit_PCD8544.h> //https:esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942
Adafruit_BMP280 bmp280;
float Press, Tin; //давление, температура
Adafruit_PCD8544 display = Adafruit_PCD8544(5, 7, 6);
void setup() {
Serial.begin(9600);
display.begin();
// display.clearDisplay();
display.setContrast(60); // установка контраста
while (!bmp280.begin(BMP280_ADDRESS - 1)) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
delay(100);
}
}
void loop() {
// измерение температуры, давления
Tin = bmp280.readTemperature();
Press = bmp280.readPressure() / 133.3;
Serial.println("Temperature: " + String(Tin) + "*C");
Serial.println("Pressure: " + String(Press) + "mm Hq");
display.clearDisplay();
//давление, мм рт.ст.
{
display.setTextSize(1);
display.setCursor(20, 5);
display.println (Press, 0); // нет знаков после запятой
display.setCursor(41, 5);
display.println("mmHq");
}
//температура, *C
{
display.setTextSize(2);
display.setCursor(15, 20);
display.println (Tin, 1); // один знак после запятой
display.setCursor(66, 20);
display.println("C");
}
display.display();
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
Ресурсы, потребляемые программой барометра-термометра на Си и в Arduino IDE наглядно показаны на картинке:
Как видно, эти примеры потребляют 5954 байт (С) и 12956 байт (Arduino IDE) в Flash. Соотношение изменилось с 6-ти раз для «мигалки» до 2-х с небольшим. К сожалению, линейной зависимости нет – чем объемней код, тем меньше соотношение размеров памяти Ардуино к Си. В идеале на этой картинке должен присутствовать 3 столбец с кодом на Ассемблере, но такого кода в Интернете я не нашел, а составить код самому мне не под силу.
Попутно замечу, что использование компилируемых в Arduino IDE библиотек и функций на С/С++ особо имеет смысл в тех случаях, когда размер занимаемой памяти превышает или близок к размеру памяти контроллера. Мне, например, часто удается уходить от предупреждения: Недостаточно памяти, программа может работать нестабильно.
Теперь посмотрим еще один вариант – это цифровой термометр-гигрометр на AM2302 (DHT22), ATtiny13 и MAX7219, код которого составлен на Ассемблере.
Автор статьи задался целью разработать простой термометр-гигрометр выполненном на одном из самых «маленьких» микроконтроллеров — ATtiny13 с весьма скромными характеристиками – 1Кб программной памяти, 64 байтами ОЗУ и 5 интерфейсными выводами. Он решил эту непростую задачку, выбрав Ассемблер, заодно вспомнив те далекие времена, когда код можно было составлять на низкоуровневых языках, используя машины типа ZX-Spectrum.
Ниже скриншот со сборкой данного кода в Atmel Studio 7.
Код устройства на Ассемблере занимает 738 байт памяти в контроллере. Безусловно, программа барометра-термометра, о котором шла речь выше, будь ее код составлен на Ассемблере, заняла бы больше места. По нескольким причинам — в схеме реализовано управление дисплеем Nokia3110 по интерфейсу SPI (это 5 линий связи, тут – 3), связь с датчиком BMP280 осуществляется по протоколу I2C (2 линии, тут – 1) и дополнительные символы, которые позволяют не гадать – температура это или другой параметр.
Из того, что я нашел в Интернете, можно утверждать, Ассемблер даст выигрыш в размере кода для относительно больших проектов процентов 10-20 по сравнению с Си. Но надо учитывать, что в больших проектах Си может уменьшить размер кода за счёт лучшей оптимизации.
Код Ассемблера выполняется практически на машинном уровне: один цикл – одна команда. В качестве аргумента приведу пример из справочника по командам ассемблера AVR. Установка бита в регистре ввода/вывода — SBI A, b. Эта команда устанавливает заданный бит в регистре ввода-вывода. На выполнение этой операции контроллерами megaAVR потребуется 2 цикла и на tinyAVR, XMEGA — 1 цикл. Для схемы с контроллером ATtiny13 и резонатором 9,6 МГц выполнение команды займет один цикл, то есть 1/9600000 Гц = 0,104 мксек.
Выполнение похожей операции на языке Си, например, задать состояние порта — PORTB = 32; займет в этой же схеме не меньше времени. А о Ардуино и говорить нечего – там придется выполнить объемную функцию void digitalWrite(uint8_t pin, uint8_t val);. Подробно о размерах кода в Си и Ардуино читайте тут.
Поэтому разработчики серийных продуктов, как правило, пишут коды на низкоуровневых языках. С тем, чтобы разместить программу в контроллере с меньшей памятью. Тут работают законы экономики — контроллер с меньшими ресурсами стоит дешевле, следовательно себестоимость изделия становится ниже.
Теперь о энергосбережении немножко издали. Вспомним, что код Ассемблера выполняется на машинном уровне: один цикл – одна или несколько команд. в зависимости от типа контроллера. Это — десятые доли микросекунды. То есть, на выполнение программы с размером несколько десятков байт уйдут единицы-десятки микросекунд. Дальше контроллер бесконечно будет крутить этот набор «0» и «1», затрачивая энергию на перезаряд емкости затворов сотен полевых транзисторов, на которых построен кристалл контроллера, а также чтение и записи данных в его память. Длительность периода повтора будет зависеть только от размера кода в памяти контроллера, неважно на каком языке он составлен. Просто на Ассемблере он будет наименьшим, а на Ардуино – наибольшим. Соответственно, период цикла для кода на Ассемблере – наименьший, на Ардуино – наибольший.
Уменьшить эти затраты можно остановив процессор или программно уменьшив частоту его работы. В Ассемблере переход в "спящий" режим сна выполняет функция управления контроллером SLEEP. В других можно использовать функцию WDT (WatchDog Timer), а в Ардуино еще и функцию LowPower.powerDown (SLEEP_1S, ADC_OFF, BOD_OFF), заодно отключив все лишнее, что не используется в конкретной задаче. В эффективности этой функции сможет убедиться каждый, заменив в скетче «мигалки» (скетч — на картинке вначале статьи) функцию отсчета времени delay(1000); этой функцией и включив в разрыв питания контроллера амперметр. Да, не забудьте подключить библиотеку LowPower.h. На Си это сделал автор этой статьи. Ток в цепи питания attiny13a с паузой — 1,5мА, со сном — 240мкА. Потребление в 6(!) раз меньше.
Допустим, вы намерены собрать барометр-термометр и задумываетесь о энергосбережении. Понятно, что давление/температура в заданной разрядности не изменятся за несколько минут, которые для контроллера целая вечность. Ему можно выделить это время для сна. После сна он снова выполнит свою работу: примет информацию с датчика, преобразует в понятные для человека циферки и выведет все это на дисплей. И в таком режиме «работа-сон» он будет крутиться, пока не сядут батарейки. Объем «работы» контроллера, вернее время, которое контроллер будет занят выполнением работы, зависит от того, на каком языке составлена программа барометра-термометра. Если есть возможность загрузить в контроллер код на выбор – ArduinoIDE, C, Assembler, с одинаковым временем «сна», то в каком из трех предложенных вариантов батарейки сядут раньше (позже)? Мой ответ – ArduinoIDE (Assembler).
Кстати, настоятельно рекомендую хотя бы вскользь посмотреть Реальная правда о Программистах ненавидящих Arduino. Поучительный материал. Автор подробно описывает свою историю от первых радостей мигания светодиодом и чуда по тем временам — вывода температуры на дисплей от мобилки до Ардуино с дельными советами.
Так куда же идти? На мой взгляд, для любителей, как я, – это платформа Arduino IDE с низкоуровневыми вставками. Тем же, кому тесно в Ардуино, — в С. Assembler не освоить за несколько месяцев. Да и осваивать не имеет особого смыла — коды на С можно оптимизировать иногда до размеров не намного больше, чем в Ассемблере.
Спасибо за внимание. Всего наилучшего!
Ссылки по теме
- Превращаем Arduino в полноценный AVRISP программатор, HWman
- Почему многие не любят Arduino, HWman
- Atmel Studio (видео)
- PROTEUS 8 для начинающих (видео)
- Код blink в формате *.asm на github
- Простой цифровой термометр/гигрометр на AM2302 (DHT22), ATtiny13 и MAX7219, kdekaluga
- Справочник по командам ассемблера AVR
- AVR — Power management или как правильно спать
- Реальная правда о Программистах ненавидящих Arduino, free_arduino
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, C++, Программирование микроконтроллеров, Производство и разработка электроники] Создание аналога посмертного сore dump для микроконтроллера
- [Схемотехника, Производство и разработка электроники, DIY или Сделай сам, Электроника для начинающих] Gyrators
- [Программирование микроконтроллеров, Схемотехника] USB на регистрах: STM32L1 / STM32F1
- [Open source, Программирование микроконтроллеров, DIY или Сделай сам] USB Host, «Blue Pill», метод деления отрезка пополам и цена на водку в СССР
- [Программирование, Системное программирование, Промышленное программирование, Программирование микроконтроллеров] Добавляем modbus в Embox RTOS и используем на STM32 и не только
- [Разработка под Arduino, Гаджеты, DIY или Сделай сам, Электроника для начинающих] Как я сделал кнопку выхода из Zoom (перевод)
- [Системное программирование, Реверс-инжиниринг, Программирование микроконтроллеров, Интернет вещей, DIY или Сделай сам] Hello NXP JN5169 World
- [Гаджеты, DIY или Сделай сам, Электроника для начинающих] Цифровая паяльная станция своими руками (перевод)
- [Программирование, C++, Промышленное программирование, Программирование микроконтроллеров] Маленькие хитрости для STM32
- [Схемотехника, Производство и разработка электроники, DIY или Сделай сам, Электроника для начинающих] Разработка источника питания от трёхфазной сети 380В
Теги для поиска: #_programmirovanie_mikrokontrollerov (Программирование микроконтроллеров), #_elektronika_dlja_nachinajuschih (Электроника для начинающих), #_arduino_ide, #_c/c++, #_assembler, #_atmel_studio_7, #_proteus, #_programmirovanie_mikrokontrollerov (программирование микроконтроллеров), #_programmirovanie_mikrokontrollerov (
Программирование микроконтроллеров
), #_elektronika_dlja_nachinajuschih (
Электроника для начинающих
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:26
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Сначала короткая предыстория появления этого поста. Относительно давно, помигав светодиодом, захотелось сделать что-то полезное. Так появился Беспроводной программируемый по Wi-Fi комнатный термостат с монитором качества воздуха и другими полезными функциями. Как назло, в это время перестал работать мой промышленный термостат. Меня выручила еще сырая поделка, наспех спрятанная в картонную коробочку. За время отопительного сезона напрягал лишь один недостаток прототипа – это необходимость таскать по квартире удлинитель 220В и кабель, который всегда путался под шваброй ногами. Поэтому решил сделать нечто похожее, но автономное, притом, с питанием от батареек, как в серийном образце. Тут я завис надолго. Приступая к задаче, для меня было очевидно одно – вряд ли программы промышленных автономных устройств составлены на платформе Arduino IDE. Где все спрятано в громоздкие тяжеловесные библиотеки, а простые коды (скетчи) занимают в редакторе несколько десятков строк, делая работу в этой среде комфортной и не требующей особых усилий. Уточню сразу – дальше речь выборе языка программирования между Ардуино, Си или Ассемблером. Хотя, понятно, на потреблении устройства в целом сказывается слишком много факторов таких, как энергопотребление подключенных модулей, потребление самого контроллера, который управляет периферией, не последнюю роль тут играет оптимальное построение самого кода и алгоритм работы устройства. «… направу ехати — женату быти; налеву ехати — богату быти» В начале пути, перед выбором направления меня оптимистично настроила статья Почему многие не любят Arduino. Ниже, для наглядности, картинка оттуда с кодом «мигалки». Пример слева написан на языке Ардуино, а справа — работа непосредственно с регистрами. Код на Ардуино выглядит несколько компактней, чем та же «мигалка», но с использованием регистров. На изображении ниже — компиляция кода «мигалки» на Ассемблере. Как видно, былая компактность испарилась – количество строк в 3 раза больше, чем в Ардуино. И так, с 2 картинок выше видно – размер памяти, занимаемой в контроллере кодом «мигалки» одним светодиодом, написанным на Ардуино, составляет 1030 байт, на Си – 176 байт, на Ассемблере – 42 байта. Теперь взглянем на более сложный код. Поскольку в своих проектах использую модуль давления-температуры BMP280, составил код барометра-термометра на Си, чтобы заодно была какая-то польза. барометр-термометр на СиSPL/*
На распутье - Ардуино, Cи или Ассемблер? https://habr.com/ru/post/547752/ */ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include "bmp180/bmp180.c" #include "uart.c" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "nokia/nokia5110.h" int main(void) { serial_init(); DDRD |= (1 << 7); //pin 13, atmega328p PORTD &= ~(1 << 7); nokia_lcd_init(); while (1) { init_sensor(bmp180_mode_0); calculate(); PORTD |= (1 << 7); _delay_ms(100); printf("Temperature: %.2f C, Pressure: %.2f Pa, \n", (float) bmp_180.temperature / 10, (float)bmp_180.pressure); nokia_lcd_clear(); nokia_lcd_write_string("789",1); nokia_lcd_set_cursor(0, 10); nokia_lcd_write_string("22.2", 3); nokia_lcd_render(); _delay_ms(2000); PORTD &= ~(1 << 7); _delay_ms(100); int a=54325; char buffer[20]; itoa(a,buffer,2); // here 2 means binary printf("Binary value = %s\n", buffer); itoa(a,buffer,10); // here 10 means decimal printf("Decimal value = %s\n", buffer); itoa(a,buffer,16); // here 16 means Hexadecimal printf("Hexadecimal value = %s\n", buffer); } return 0; } В проект входят следующие компоненты: контроллер ATMEGA328P, модуль давления-температуры BMP180 и дисплей Nokia 3110. ATMEGA328P принимает инфу с датчика BMP180 и после преобразований отображает ее на дисплее Nokia 3110, затем спит. Сон задается сторожевым таймером Watchdog. Проект собирается в Atmel Studio 7 и эмулируется в Proteus 8 Pro. Этот проект Atmel Studio был создан для отладки кода в Proteus'e. В библиотеке Proteus 8 Pro модуля BMP280 нет, поэтому пришлось составить код с включением BMP180. Светодиод в коде — для наглядности, чтобы придать динамику статичной картинке. Ниже — электрическая схема устройства. При монтаже схемы обращайте внимание на функциональное назначение выводов контроллера и модулей. Подключение кварца — XTAL1, XTAL2 (ATMEGA328P). Уточню, схему барометра-термометра на BMP180 я "в железе" не собирал, поэтому тут могут проявиться проблемы, которые не видны при эмуляции в Proteus'e. Для скачивания zip-файла проекта в Atmel Studio 7 перейдите по ссылке – тут все виртуальные проекты и коды программ из этой публикации. Файл прошивки bmp180-nokia3110-watchdog-1.hex для Proteus'а находится в папке Debug. В файле main.c есть закомментированный код барометра-термометра на BMP280. Его электрическая схема такая же, как и у барометра-термометра на BMP180. Он успешно собирается в Atmel Studio 7 и работает "в железе". Для работы "в железе" пришлось внести изменения в строке #define BMP280_ADDR 0x77 файла библиотеки bmp280.c, а именно: заменить начальный адрес 0x77 на 0x76. Не забудьте сделать эту корректировку, если будете использовать в своих проектах код барометра-термометра на BMP280 из main.c, с уже подключенной библиотекой bmp280.c. Ниже — код этого же барометра-термометра в платформе Arduino IDE. Естественно, с другими библиотеками. барометр-термометр на АрдуиноSPL/*
На распутье - Ардуино, Cи или Ассемблер? https://habr.com/ru/post/547752/ */ #include <SPI.h> #include <LowPower.h> #include <SimpleTimer.h> #include <Adafruit_BMP280.h> #include <Adafruit_GFX.h> //https:esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942 #include <Adafruit_PCD8544.h> //https:esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942 Adafruit_BMP280 bmp280; float Press, Tin; //давление, температура Adafruit_PCD8544 display = Adafruit_PCD8544(5, 7, 6); void setup() { Serial.begin(9600); display.begin(); // display.clearDisplay(); display.setContrast(60); // установка контраста while (!bmp280.begin(BMP280_ADDRESS - 1)) { Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); delay(100); } } void loop() { // измерение температуры, давления Tin = bmp280.readTemperature(); Press = bmp280.readPressure() / 133.3; Serial.println("Temperature: " + String(Tin) + "*C"); Serial.println("Pressure: " + String(Press) + "mm Hq"); display.clearDisplay(); //давление, мм рт.ст. { display.setTextSize(1); display.setCursor(20, 5); display.println (Press, 0); // нет знаков после запятой display.setCursor(41, 5); display.println("mmHq"); } //температура, *C { display.setTextSize(2); display.setCursor(15, 20); display.println (Tin, 1); // один знак после запятой display.setCursor(66, 20); display.println("C"); } display.display(); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); } Ресурсы, потребляемые программой барометра-термометра на Си и в Arduino IDE наглядно показаны на картинке: Как видно, эти примеры потребляют 5954 байт (С) и 12956 байт (Arduino IDE) в Flash. Соотношение изменилось с 6-ти раз для «мигалки» до 2-х с небольшим. К сожалению, линейной зависимости нет – чем объемней код, тем меньше соотношение размеров памяти Ардуино к Си. В идеале на этой картинке должен присутствовать 3 столбец с кодом на Ассемблере, но такого кода в Интернете я не нашел, а составить код самому мне не под силу. Попутно замечу, что использование компилируемых в Arduino IDE библиотек и функций на С/С++ особо имеет смысл в тех случаях, когда размер занимаемой памяти превышает или близок к размеру памяти контроллера. Мне, например, часто удается уходить от предупреждения: Недостаточно памяти, программа может работать нестабильно. Теперь посмотрим еще один вариант – это цифровой термометр-гигрометр на AM2302 (DHT22), ATtiny13 и MAX7219, код которого составлен на Ассемблере. Автор статьи задался целью разработать простой термометр-гигрометр выполненном на одном из самых «маленьких» микроконтроллеров — ATtiny13 с весьма скромными характеристиками – 1Кб программной памяти, 64 байтами ОЗУ и 5 интерфейсными выводами. Он решил эту непростую задачку, выбрав Ассемблер, заодно вспомнив те далекие времена, когда код можно было составлять на низкоуровневых языках, используя машины типа ZX-Spectrum. Ниже скриншот со сборкой данного кода в Atmel Studio 7. Код устройства на Ассемблере занимает 738 байт памяти в контроллере. Безусловно, программа барометра-термометра, о котором шла речь выше, будь ее код составлен на Ассемблере, заняла бы больше места. По нескольким причинам — в схеме реализовано управление дисплеем Nokia3110 по интерфейсу SPI (это 5 линий связи, тут – 3), связь с датчиком BMP280 осуществляется по протоколу I2C (2 линии, тут – 1) и дополнительные символы, которые позволяют не гадать – температура это или другой параметр. Из того, что я нашел в Интернете, можно утверждать, Ассемблер даст выигрыш в размере кода для относительно больших проектов процентов 10-20 по сравнению с Си. Но надо учитывать, что в больших проектах Си может уменьшить размер кода за счёт лучшей оптимизации. Код Ассемблера выполняется практически на машинном уровне: один цикл – одна команда. В качестве аргумента приведу пример из справочника по командам ассемблера AVR. Установка бита в регистре ввода/вывода — SBI A, b. Эта команда устанавливает заданный бит в регистре ввода-вывода. На выполнение этой операции контроллерами megaAVR потребуется 2 цикла и на tinyAVR, XMEGA — 1 цикл. Для схемы с контроллером ATtiny13 и резонатором 9,6 МГц выполнение команды займет один цикл, то есть 1/9600000 Гц = 0,104 мксек. Выполнение похожей операции на языке Си, например, задать состояние порта — PORTB = 32; займет в этой же схеме не меньше времени. А о Ардуино и говорить нечего – там придется выполнить объемную функцию void digitalWrite(uint8_t pin, uint8_t val);. Подробно о размерах кода в Си и Ардуино читайте тут. Поэтому разработчики серийных продуктов, как правило, пишут коды на низкоуровневых языках. С тем, чтобы разместить программу в контроллере с меньшей памятью. Тут работают законы экономики — контроллер с меньшими ресурсами стоит дешевле, следовательно себестоимость изделия становится ниже. Теперь о энергосбережении немножко издали. Вспомним, что код Ассемблера выполняется на машинном уровне: один цикл – одна или несколько команд. в зависимости от типа контроллера. Это — десятые доли микросекунды. То есть, на выполнение программы с размером несколько десятков байт уйдут единицы-десятки микросекунд. Дальше контроллер бесконечно будет крутить этот набор «0» и «1», затрачивая энергию на перезаряд емкости затворов сотен полевых транзисторов, на которых построен кристалл контроллера, а также чтение и записи данных в его память. Длительность периода повтора будет зависеть только от размера кода в памяти контроллера, неважно на каком языке он составлен. Просто на Ассемблере он будет наименьшим, а на Ардуино – наибольшим. Соответственно, период цикла для кода на Ассемблере – наименьший, на Ардуино – наибольший. Уменьшить эти затраты можно остановив процессор или программно уменьшив частоту его работы. В Ассемблере переход в "спящий" режим сна выполняет функция управления контроллером SLEEP. В других можно использовать функцию WDT (WatchDog Timer), а в Ардуино еще и функцию LowPower.powerDown (SLEEP_1S, ADC_OFF, BOD_OFF), заодно отключив все лишнее, что не используется в конкретной задаче. В эффективности этой функции сможет убедиться каждый, заменив в скетче «мигалки» (скетч — на картинке вначале статьи) функцию отсчета времени delay(1000); этой функцией и включив в разрыв питания контроллера амперметр. Да, не забудьте подключить библиотеку LowPower.h. На Си это сделал автор этой статьи. Ток в цепи питания attiny13a с паузой — 1,5мА, со сном — 240мкА. Потребление в 6(!) раз меньше. Допустим, вы намерены собрать барометр-термометр и задумываетесь о энергосбережении. Понятно, что давление/температура в заданной разрядности не изменятся за несколько минут, которые для контроллера целая вечность. Ему можно выделить это время для сна. После сна он снова выполнит свою работу: примет информацию с датчика, преобразует в понятные для человека циферки и выведет все это на дисплей. И в таком режиме «работа-сон» он будет крутиться, пока не сядут батарейки. Объем «работы» контроллера, вернее время, которое контроллер будет занят выполнением работы, зависит от того, на каком языке составлена программа барометра-термометра. Если есть возможность загрузить в контроллер код на выбор – ArduinoIDE, C, Assembler, с одинаковым временем «сна», то в каком из трех предложенных вариантов батарейки сядут раньше (позже)? Мой ответ – ArduinoIDE (Assembler). Кстати, настоятельно рекомендую хотя бы вскользь посмотреть Реальная правда о Программистах ненавидящих Arduino. Поучительный материал. Автор подробно описывает свою историю от первых радостей мигания светодиодом и чуда по тем временам — вывода температуры на дисплей от мобилки до Ардуино с дельными советами. Так куда же идти? На мой взгляд, для любителей, как я, – это платформа Arduino IDE с низкоуровневыми вставками. Тем же, кому тесно в Ардуино, — в С. Assembler не освоить за несколько месяцев. Да и осваивать не имеет особого смыла — коды на С можно оптимизировать иногда до размеров не намного больше, чем в Ассемблере. Спасибо за внимание. Всего наилучшего! Ссылки по теме
=========== Источник: habr.com =========== Похожие новости:
Программирование микроконтроллеров ), #_elektronika_dlja_nachinajuschih ( Электроника для начинающих ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:26
Часовой пояс: UTC + 5