Разобравшись с драйвером неплохо научиться выводить на него информацию. Как вы помните с первого курса, текст и числа в любом формате на экран можно выводить через printf. Так вот, давайте адаптируем эту функцию под выбранный тип, с позволения сказать, экрана. Про особенности языка потом, сперва нужен алфавит, ну чтож, википедия, настало твоё время:
Теперь, как будем вносить эту таблицу, думаете массивом? Было бы логично, но не в моем случае. Поступим по другому, на каждый сегмент выделим по макросу. А символы будем задавать в switch case как сумму макросов. Контроллер хоть и не железный, но проглотит и такой код. Так вот, при таком подходе можно менять биты, соответствующие разным сегментам. То есть теперь можно и не по порядку 0-1-2-3-4-5-6-7 и A-B-C-D-E-F-G-DP, а произвольно. Таким способом мы и получили возможность развести печатную плату так, как нам удобнее. Здесь приведу только отрывок функции uint8_t alphabet(char c) где c - ACSI символ, а возвращаемое восьмибитное число, это то что отправляется в драйвер.
case '9':
return SEGA + SEGB + SEGC + SEGD + SEGF + SEGG;
break;
case 'A':
case 'a':
return SEGA + SEGB + SEGC + SEGE + SEGF + SEGG;
break;
case 'B':
case 'b':
return SEGC + SEGD + SEGE + SEGF + SEGG;
break;
case '[' :
case 'C' :
case 'c' :
return SEGA + SEGD + SEGE + SEGF;
break;
case 'D' :
case 'd' :
return SEGB + SEGC + SEGD + SEGE + SEGG;
Там есть еще одна маленькая сложность, символ и точка в одном и том же байте а не отдельно. Поэтому кроме функции преобразователя кодировки из аски в семисегментную нужно еще одно условие распознавания и добавления точек. Вот оно, видите, если условие верно SEGDP добавляется, иначе просто перевод кодировки.
for( uint8_t i = 0 ; (i < strlen(buffer)) && (outCnt < DIGITS) ; ++i )
{
if( (buffer[i] != '.') && (buffer[i] != ',') && \
((buffer[i+1] == '.') || (buffer[i+1] == ',')) ) {
dispBuffer[outCnt++] = (alphabet(buffer[i++]) | SEGDP);
} else {
dispBuffer[outCnt++] = (alphabet(buffer[i]));
}
}
А вот тут самое необычное. Очень мало используемая возможность языка си - функция с переменным количеством аргументов. Хорошо что нам эти аргументы самим обрабатывать не надо, а нужно только передать в функцию sprintf, и из нее получить уже готовую строку.
void myprintf(char *format, ... )
{
char buffer[DIGITS*4];
uint8_t dispBuffer[DIGITS];
va_list args;
va_start (args, format);
vsprintf (buffer, format, args);
va_end (args);
Вот и вся магия, осталось передать обработанную выше строку драйверу. (количество символов захардкожено).
tmUpd(dispBuffer);
А теперь, не побоюсь этого слова, во же сколько нам обойдется такой шик. В случае с восьмибитками нереально дорого. Эти полтора килобайта 1/5 всей памяти какой нибудь восьмой меги. Для stm с их 32 на минималках, как то пофиг, попробуйте забить у них всю память, у меня только на половину получалось. Файлы с кодом
вот и
вот.
Комментариев нет :
Отправить комментарий