реклама на сайте
подробности

 
 
> Связка Ведущий - Драйвер
Anub
сообщение Sep 19 2008, 20:33
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-08
Пользователь №: 37 825



Я делаю часы с индикацией на ЦСИ. Так как ЦСИ не цифровые пришлось самому сделать под них драйвер с регулированием яркости частоты перерисовки и т д. Ведущий МК отвечает за все остальное в то время как драйвер только отрисовывает цифры. Обмен между МК происходит по средствам пакетной передачи. Но с недавних пор я столкнулся с крайне неприятной проблемой - временами индикаторы тухнут, а это прямо говорит о том что драйверная функция потребила что то несъедобное, так как иначе появились бы нули. Вот как это выглядит
http://rutube.ru/tracks/1028588.html?v=c5e...bfe97242aa66f18
Функция получения пакета вроде бы как давно проверена, много раз ее использовал, вот она
Код
interrupt [USART_RXC] void usart_rx_isr(void)
{
    char data = UDR;

    if (!rx_done) {
        if (data == ':') fbp = 1;
            if (fbp) {
            rx_buffer[rx_wr_index++] = data;
            if (data =='/') {
                rx_done = 1;
                fbp = 0;
                rx_wr_index = 0;
                activeCommand(rx_buffer);
            }
            else if (rx_wr_index>=RX_BUFFER_SIZE) {
                     rx_wr_index = 0;
                     rx_buffer_overflow = 1;
                 }
        } else;
    } else rx_data_overrun = 1;

}

      void activeCommand(char c[])
{      
    USHORT a, b, d, e;
    a=rx_buffer[1];
    b=rx_buffer[2];
    d=rx_buffer[3];
    e=rx_buffer[4];
    fi=a-48;      //Так как преобразование идет в ASCII код приходится доводить значение
    se=b-48;
    th=d-48;
    fo=e-48;
          
    rx_done = 0;
}

Шлю команду по прерыванию каждую секунду так
Код
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{  
    PORTB=0x00;
    TCNT1=57723;//57723
    if (S!=59){
        S++;
    } else {
        S=0;
        M++;
    }
    if (M==60){
        M=0;
        H++;
    }
    if (H==24){
        H=0;
    }
      
        SetCountCommand[1]=M/10+48;
        SetCountCommand[2]=M%10+48;
        SetCountCommand[3]=S/10+48;
        SetCountCommand[4]=S%10+48;
        
        puts(SetCountCommand);          
}

Как видно из вышеприведенного все это прекрасно работает за исключением только того бага. Что это может быть и как это лечить?

Сообщение отредактировал Anub - Sep 19 2008, 20:34
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Sep 19 2008, 21:43
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Опреация деления (хоть и целочисленного), выполняемая в прерывании, это не есть хорошо sad.gif Замените деление умножением на "волшебное" число и сдвигами. А нахождение остатка от деления вычитанием и сдвигами.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 21 2008, 17:32
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rezident @ Sep 20 2008, 01:43) *
Опреация деления (хоть и целочисленного), выполняемая в прерывании, это не есть хорошо sad.gif Замените деление умножением на "волшебное" число и сдвигами. А нахождение остатка от деления вычитанием и сдвигами.

Я думаю, компилятор и сам догадается это сделать.
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 21 2008, 18:39
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(777777 @ Sep 21 2008, 23:32) *
Я думаю, компилятор и сам догадается это сделать.
А откуда у компилятора такая догадливость? Любая программа ничуть не умнее программиста ее написавшего. wink.gif И тот же компилятор это тоже программа.
Для примера вот в такой программке для вычисления значения y затрачивается в 1,5-2 раза меньше тактов, чем для вычисления x. Хотя на первый взгляд операций во втором выражении больше. При этом всякие аппаратные умножители конечно же отключены, иначе выигрыш получается еще больше smile.gif
Код
unsigned int x, y;
unsigned long z=65489;
x=z/10;
y=(z*0xCCCD)>>19;


Сообщение отредактировал rezident - Sep 22 2008, 07:27
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 22 2008, 06:40
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rezident @ Sep 21 2008, 22:39) *
А откуда у компилятора такая догадливость? Любая программа ничуть не умнее программиста ее написавшего. wink.gif И тот же компилятор это тоже программа.

Разумеется, но человек, писавший его, знает, что деление на константу лучше заменить умножением на обратную ей.
Цитата(rezident @ Sep 21 2008, 22:39) *
Для примера вот в такой программке для вычисления значения y затрачивается в 1,5-2 раза меньше тактов, чем для вычисления x.
Код
unsigned int x, y;
unsigned long z=65489;
x=z/10;
y=(x*0xCCCD)>>19;

Ну, еще бы! Ведь в этом примере результат вычисления 'y' всегда равен нулю. smile.gif
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 10:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016