LINUX.ORG.RU

Использование структур в программировании микроконтроллеров — дурной тон?

 , ,


1

1

$SUBJ. Где-то с месяц назад меня уверяли, что писать структуры, программируя мк, не нужно. Меня это слегка удивило, но ладно, спорить не стал — неблагодарное это дело. Сейчас делаю лабу и мыслительным органом чувствую, что тут нужна структура. Ну вот нужна и все, код тут же станет красивым и шелковистым. Я что-то делаю не так?

★★★★★
Ответ на: комментарий от qbe

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Сам понимаешь, что если заставить десяток студентов ручками мигать МИ, то они нет-нет, да разберутся.

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от f1xmAn

работать не будет. попробуй свернуть в 2 байта симаол A:

0b00000000
0b00111100
0b01000100
0b01000100
0b01111100
0b01000100
0b01000100
0b00000000

qbe
()
Ответ на: комментарий от f1xmAn

данная схема подразумевает динамическую индикацию, по С1-С8 формируется бегущий 0, на R1-R8 подаются биты изображения столбцов.

qbe
()
Ответ на: комментарий от Eddy_Em

В регистр D11 пишется байт, который «зажигает» конкретные строки (линии, подключенные к анодам), в регистр повыше пишется байт, который «зажигает» столбцы (линии, подключенные к катодам). Чтобы зажечь один диод, на анод нужно подать логическую единицу, на катод соответственно лог. 0. Т.е. чтобы светился левый верхний диод, в регистре D11 должно быть записано 0b00000001, а в регистре повыше — 0b11111110.

f1xmAn ★★★★★
() автор топика
Последнее исправление: f1xmAn (всего исправлений: 1)
Ответ на: комментарий от qbe

Точно же! Вот я тут чушь нес. ☹

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Да-да, я уже протер глаза и вспомнил про динамическую индикацию. Буду использовать 2-мерные массивы под каждый символ.

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от f1xmAn

главное - вовремя разобраться, чтобы потом не было мучительно больно при переразводке печатной платы ;)

qbe
()
Ответ на: комментарий от f1xmAn

Вот и дергай готовые. Ты же замучаешься одну только ASCII собирать, по 8 байт на символ. А если еще и русские буквы понадобятся — так вообще пожалеешь, что сразу не спер!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

да не так уж долго фонт набить, особенно, если компилятор имеет двоичный синтаксис вроде 0b01011010 :)

qbe
()
Ответ на: комментарий от qbe

А смысл, если готовых полно?

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от qbe

Ой, было у меня однажды. С часу ночи разводил пп в sprint layout, в 3 закончил. 10 раз все проверил, нажал save и программа самоубилась. Не сохранив ничего. Пришлось до 5 часов утра заново все разводить, сохраняясь каждые пару кликов.

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Да ладно, один раз соберу, хедер и реализацию сохраню и буду использовать когда понадобится.

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Ну тут простор для творчества большой, не спрою. В моей практике попадаются под руку мои шрифты спектрумовских времён, либо требования к шрифту нестандартные. То приходится символы на 90° разворачивать, то нужны пропорциональные шрифты.

qbe
()
Ответ на: комментарий от qbe

В моей практике попадаются под руку мои шрифты спектрумовских времён

О, такое было. Рисовал и сам когда-то на миллиметровке, потом загонял в массив.

символы на 90° разворачивать

Это же элементарная операция — пишешь малюсенькую программулинку, и она тебе из обычного массива "повернутый" делает.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от f1xmAn

Буду использовать 2-мерные массивы под каждый символ.

Одна размерность у всех символов - «бегущий» ноль (или единица).
Стоит использовать один двухмерный массив символов: одна размерность - код символа, вторая 8 байт - данные символа.

unsigned char alpha[256][8] =
{
  {0b00000000
   0b00111100
   0b01000100
   0b01000100
   0b01111100
   0b01000100
   0b01000100
   0b00000000},
  ...

anonymous
()
Ответ на: комментарий от Eddy_Em

Это же элементарная операция — пишешь малюсенькую программулинку, и она тебе из обычного массива «повернутый» делает.

Так и делал. Суть в том, что у меня почти всегда в каждой новой задаче шрифт отличается от предыдущих, хоть в чём-то.

//offtop: лень привела к тому, что русскоязычные сообщения в микроконтроллерах храню в UTF-8, поскольку сырцы мне удобнее хранить именно в этой кодировке ;)

qbe
()
Ответ на: комментарий от f1xmAn
const unsigned char alpha[256][8]={...};
const unsigned char alpha_runner[8]=
{
  0b11111110,
  0b11111101,
  0b11111011,
  0b11110111,
  0b11101111,
  0b11011111,
  0b10111111,
  0b01111111
}
void printChar(unsigned char ch)
{
  unsigned char i,*alpha_ptr = alpha[ch];
  for(i=0;i<8;i++)
  {
    porta = alpha_runner[i];
    portb = alpha_ptr[i];
  }
}
anonymous
()
Ответ на: комментарий от f1xmAn

да, и ещё, в реальной жизни тот пример работать будет крайне плохо (нет паузы между переключениями строк(столбцов) динамической индикации). стоит переписать примерно так:

void printChar(unsigned char ch)
{
  static unsigned char i = 0; i=(i+1)%8;
  porta = alpha_runner[i];
  portb = alpha[ch][i];
}

alpha_runner[] можно заменить простым битовым сдвигом с инверсией

и со сдвигом можно, дело вкуса.

anonymous
()
Ответ на: комментарий от anonymous

Возможно правильнее будет рассчитать частоту обновления и повпихивать delay'и с NOP'ами в цикл записи в порты?

f1xmAn ★★★★★
() автор топика
Ответ на: комментарий от f1xmAn

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

Никакого геморроя с программированием не будет: просто пихай (хоть через DMA) 8 байт в свои 64 D-триггера (отключив на время копирования генератор), затем запускай генератор и радуйся.

В принципе, можно и по таймеру это сделать: перебирать 8 байт (DMA?) циклически в зависимости от значения счетчика, этим же счетчиком выдавать бегущий нуль. Процедура: 1) указываешь адрес нужной буквы для выхлопа DMA → порт, 2) запускаешь таймер. А в обработчике прерываний таймера циклически сдвигаешь указатель и задаешь новое значение для скользящего нуля.


Вот, кстати, у меня была идейка, что светодиодный куб проще всего было бы именно на основе "железного" генератора скользящего нуля и сделать. Но там нужно будет уже реальную ОЗУ использовать. И лучше всего — с параллельным доступом.

Но все равно, при таких миганиях яркость свечения светодиодов будет невысокой. А подавать на них вместо 5В, скажем, 220 — неизвестно как скажется на сроке жизни этих светодиодов.

Eddy_Em ☆☆☆☆☆
()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Не будет ни примеров ни пруфов :P Просто слышал такие слухи. Конечно, сам-то я предпочитаю писать по стандартам и решать проблемы только в случае их возникновения и ТС советую делать так.

legolegs ★★★★★
()
Ответ на: комментарий от drBatty

Сами структуры часто дорого передавать.

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

да и опасно.

Нет. В самой по себе передаче структур опасности нет. Копирование указателей - другой вопрос.

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

Ну, ХЗ: не видел ни одного древнего компилятора. Тот же sdcc нормально обновляется. AVR/ARM прошиваются при помощи gcc…

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Геморрой с программированием будет, потому что я показывал готовый стенд с кучей девайсов и зафигачить туда что-то новое мне никто не даст. Но это ты интересно придумал, наверное даже при случае воспользуюсь твоим советом, спасибо.

f1xmAn ★★★★★
() автор топика

структура - просто сущность, которая объединяет набор полей. Их общее имя. Не более. Работа с ней - типичный доступ по указателю. Маленькие структуры компилятор и сам умеет по регистрам раскладывать. Или тогда и от массивов уж отказывайся, чего там

marvin_yorke ★★★
()
Ответ на: комментарий от marvin_yorke

Использование структур в программировании микроконтроллеров — дурной тон? (комментарий) во. 595й регистр и десятичный счетчик. В прерывании таймера пихаешь байт в SPI, в прерывании SPI transmit дернули клок счетчика. 9ку со счетчика завести на сброс

marvin_yorke ★★★
()

Сейчас делаю лабу

Если вы еще учитесь, то можно вообще никого не слушать. Набирайтесь опыта, набивайте шишки. Со временем сами поймете, где нерушимое правило, а где - лишь пожелание.

trex6 ★★★★★
()

считаю что использование структур и даже C++ с классами в разумных пределах - удобно и полезно, общий код на стороне контроллера, компьютера и даже WEB-клиента в некоторых случаях (например emscripten Qt), в общем как бы то ни было - общий код между контроллером и его хостом - это хорошо

а если у тебя самодостаточное устройство - то тоже хорошо

пользуйся и Си и структурами и всем чем хочешь

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от f1xmAn

stackoverflow спрашивал?

имхо если при использовании структур гарантируется отсутствее неожиданого алигна полей(как и структур как целого) - то пользуйся свободно.

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

qulinxao ★★☆
()
Ответ на: комментарий от prischeyadro

Ну и пожалуйста. А я делаю так, как удобнее, а не так как кто-то там сказал.

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.