Хочется побыстрее :-(
Apr. 6th, 2016 03:32 pmЕсть код преобразования четырёхзначного числа в символы, отображаемые на семисегментном индикаторе.
Индикация происходит по прерыванию от таймера примерно 45 раз в секунду, этого достаточно, индикатор не мерцает.
Если на время преобразования не запретить индикацию, то время от времени на индикаторе выскакивают "левые" цифры - происходит прерывание на этапе преобразования и отображается "as it is", что не красиво.
Запретил отображение до окончания преобразования - получились "дырки" :-( экран пригасает на мгновение, но это заметно, это некрасиво.

Вопросов, собственно два:
1. Поможет ли мне, если переписать часть кода "преобразование" на ассемблер ?
2. Кто поможет мне это сделать ? т.к. ассемблер я пока совершенно не изучал :-)
- можно на это забить, т.к. информация будет изменяться не чаще 1 раз в 30 секунд, либо при нажатии кнопки. т.о. можно получить подтверждение нажатия кнопки миганием индикатора - получится не баг, а фича :-)))
Для справки, часть кода вывода информации на индикатор:
//---------------------модуль отображения информации на индикаторе-----------------------------------
ISR(TIMER2_COMP_vect) // Обработчик прерывания таймера 2
{
asm("wdr"); // кормим "собаку" регулярно во время индикации (~45 раз в секунду)
unsigned char r = 0; // переменная, определяющая позицию и отображаемый символ
switch (ind_en){ // проверяем разрешение индикации
case 1: // индикация разрешена
while (r < 4) {
PORTB = vol[r]; // устанавливаем в порт значение сегментов
PORTC |= poz[r]; // включаем текщий разряд индикатора
_delay_us(light); // задержка в режиме свечения разряда (может регулировать яркость свечения) в микросекундах
r++; // переходим к следующей позиции индикатора
PORTC &= 0b11110000; // выключаем все разряды индикатора
}
F_clk_flag = 1; // устанавливаем флаг окончания этого цикла вывода информации
break;
case 0: // индикация запрещена
break;
}
}
набор сегментов для каждого числа хранится в массиве:
char digit[13] = {dig0, dig1, dig2, dig3, dig4, dig5, dig6, dig7, dig8, dig9, point, minus, black}; // код символа на индикаторе
уже сформированное число, для отображения хранится в массиве:
char vol[4] = {point, black, black, black}; // символы, отображаемые в настоящий момент в каждой позиции
UPD: простые и полезные основы оптимизации кода для AVR: http://microsin.net/programming/avr-troubleshooting-faq/tips-and-tricks-to-optimize-c-code-for-8-bit-avr.html
попробую сейчас оптимизировать свой кусок кода для увеличения быстродействия.
UPD2: Вот так видит этот код AtmelStudio7 http://pastebin.com/c4r04ZBr
время выполнения этого куска кода 227.88 микросекунд, период индикации у меня 25 миллисекунд. Непонятно, почему происходит наложение :-(((
Индикация происходит по прерыванию от таймера примерно 45 раз в секунду, этого достаточно, индикатор не мерцает.
Если на время преобразования не запретить индикацию, то время от времени на индикаторе выскакивают "левые" цифры - происходит прерывание на этапе преобразования и отображается "as it is", что не красиво.
Запретил отображение до окончания преобразования - получились "дырки" :-( экран пригасает на мгновение, но это заметно, это некрасиво.

Вопросов, собственно два:
1. Поможет ли мне, если переписать часть кода "преобразование" на ассемблер ?
2. Кто поможет мне это сделать ? т.к. ассемблер я пока совершенно не изучал :-)
- можно на это забить, т.к. информация будет изменяться не чаще 1 раз в 30 секунд, либо при нажатии кнопки. т.о. можно получить подтверждение нажатия кнопки миганием индикатора - получится не баг, а фича :-)))
Для справки, часть кода вывода информации на индикатор:
//---------------------модуль отображения информации на индикаторе-----------------------------------
ISR(TIMER2_COMP_vect) // Обработчик прерывания таймера 2
{
asm("wdr"); // кормим "собаку" регулярно во время индикации (~45 раз в секунду)
unsigned char r = 0; // переменная, определяющая позицию и отображаемый символ
switch (ind_en){ // проверяем разрешение индикации
case 1: // индикация разрешена
while (r < 4) {
PORTB = vol[r]; // устанавливаем в порт значение сегментов
PORTC |= poz[r]; // включаем текщий разряд индикатора
_delay_us(light); // задержка в режиме свечения разряда (может регулировать яркость свечения) в микросекундах
r++; // переходим к следующей позиции индикатора
PORTC &= 0b11110000; // выключаем все разряды индикатора
}
F_clk_flag = 1; // устанавливаем флаг окончания этого цикла вывода информации
break;
case 0: // индикация запрещена
break;
}
}
набор сегментов для каждого числа хранится в массиве:
char digit[13] = {dig0, dig1, dig2, dig3, dig4, dig5, dig6, dig7, dig8, dig9, point, minus, black}; // код символа на индикаторе
уже сформированное число, для отображения хранится в массиве:
char vol[4] = {point, black, black, black}; // символы, отображаемые в настоящий момент в каждой позиции
UPD: простые и полезные основы оптимизации кода для AVR: http://microsin.net/programming/avr-troubleshooting-faq/tips-and-tricks-to-optimize-c-code-for-8-bit-avr.html
попробую сейчас оптимизировать свой кусок кода для увеличения быстродействия.
UPD2: Вот так видит этот код AtmelStudio7 http://pastebin.com/c4r04ZBr
время выполнения этого куска кода 227.88 микросекунд, период индикации у меня 25 миллисекунд. Непонятно, почему происходит наложение :-(((