Результаты опроса: Нужна ли вам такая функция на телевизоре?

Голосовавшие
191. Вы ещё не голосовали в этом опросе
  • Нет.

    28 14.66%
  • Да.

    129 67.54%
  • Нужна , только руки кривые, самому не осилить

    34 17.80%
Показано с 1 по 10 из 921

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #11
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию Re: Фоновая подсветка телевизора Ambilight

    вот, выкладываю сурсы.

    Соединение такое:

    PortD Pin7 (Arduino digital 7) соединен с RCK 74hc595 (Pin 12)

    PortB Pin3 (Arduino digital 11) соединен с SI 74hc595 (Pin 14)
    PortB Pin5 (Arduino digital 13) соединен с SCK 74hc595 (pin 11)

    Код выполнен в AVR Studio, поэтому в нем нет
    void Setup(void)
    и
    void loop(void)
    вместо них единый
    void main(void)

    Brightness[48] - массив яркостей, который нужно показать.

    Для примера яркость меняется по циклическому закону - увеличивается.

    for (i=0;;i++)
    {
    _delay_ms(1);
    for (uint8_t j=0;j<48;j++)
    Brightness[j]++;
    }

    bitdata[6] (48 бит) побитово хранит то, что нужно выдать в 595-ые. Параллельно подключенные светодиоды одного цвета одной зоны соответствуют одному биту.
    Когда начинается новая итерация ШИМ (PWM_Counter==0) bitdata заполняется битовыми единицами - 0xFF.

    if (PWM_Counter==0)
    {
    // по умолчанию при PWM_Counter==0 все светодиоды горят, а затем гаснут по мере необходимости.
    for (uint8_t l=0;l<6;l++)
    bitdata[l]=0xff;


    Затем, каждый элемент Brightness[] проверяется и если он меньше или равен PWM_Counter, то соответствующий бит в bitdata[] сбрасывается и этим гасится одна зона одного цвета.

    Таким образом, из 256 итераций цикла (PWM_Counter от 0 до 255) каждый из 48 битов в bitdata[] установлен в 1 ровно столько итераций, сколько установлено в байтах яркости Brightness[].

    Код тут оптимизирован, но несмотря на это код из таймера жрет порядка 70% процессорного времени. _delay_ms(1) реально длится 2.5 мс.

    Если же повторяющийся кусок убрать в цикл, то быстродействие падает еще почти в полтора раза - _delay_ms(1) ждет уже 3.5 мс...

    Замеры производились при оптимизации -O3.

    Если же проводить замеры со стандартной для Arduino оптимизации -O2
    то приведенный код дает
    3.5 мс вместо _delay_ms(1)

    а в случае замены повторяющегося куска циклом, таймер начинает потреблять 100% процессорного времени.

    PHP код:
    #define TCNT2_Const 256-9

    uint8_t volatile PWM_Counter_v;
    uint8_t Brightness[48];
    uint8_t bitdata[6];


    void SPI_MasterInit(void)
    {
    /* Set MOSI and SCK output, all others input */
    DDRB |= (1<<3)|(1<<5);
    /* Enable SPI, Master, set clock rate fck/2 */
    SPSR =(1<<SPI2X);
    SPCR = (1<<SPE)|(1<<MSTR);
    }


    void SPI_MasterTransmit(char cData)
    {
        
    uint8_t a=SPSR;
        
    a=SPDR// очищаем SPIF перед отправкой данных, чтобы этот бит выставился только после завершения отправки
        
    SPDR cData;
    }

    void Out(void)
    {
         while(!(
    SPSR & (1<<SPIF)));// ждем пока не завершится передача данных
        
    uint8_t a=SPDR;
        
    PORTD |= (1<<PIN7);
        
    PORTD &= ~(1<<PIN7); 
        
    PORTD PORTD ^ (1<<PIN3);
    }

    SIGNAL(TIMER2_OVF_vect)
    {
        
    TCNT2 TCNT2_Const;

        
    Out();

        
    uint8_t PWM_Counter=PWM_Counter_v;
        
        {
            if (
    PWM_Counter==0)
            {
    // по умолчанию при PWM_Counter==0 все светодиоды горят, а затем гаснут по мере необходимости.
                
    for (uint8_t l=0;l<6;l++)
                    
    bitdata[l]=0xff;

            }

            
    uint8_t Bright;
            
    Bright= &Brightness[0];
            for (
    uint8_t j=0;j<6;j++)
            {
                
    uint8_t CurrData=bitdata[j];
                
    uint8_t bit=1;
    //            for (uint8_t k=0;k<8;k++)
    // 0
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 1
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 2
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 3
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 4
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 5
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 6
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
    // 7
                
    {
                    if (*
    Bright<=PWM_Counter)
                        
    CurrData &= ~bit;
                    
    bit=bit<<1;
                    
    Bright++;
                }
                
    bitdata[j]=CurrData;

                
    SPI_MasterTransmit(CurrData); // выводим очередные 8 бит
            
    }
        }
        
    PWM_Counter_v++;
    }

    int main(void)
    {
        
    PWM_Counter_v=255;// первым делом копируем данные в CurrBrihgtness
        
    uint8_t i;

        for (
    i=0;i<48;i++)
        {
            
    Brightness[i]=(1<<(i&7));
    //        Brightness[i]=0;
        
    }

            

        
    PORTB 0;
        
    PORTD 0;
        
    DDRD |= (1<<PIN3);
        
    DDRD |= (1<<PIN7);

        
    SPI_MasterInit();

        
    TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2  
        
    TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика 
        
    TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика 
        
    TCCR2B |= (1<<CS22);
        
    ASSR &= ~(1<<AS2);  //Выбор источника синхронизации таймера если AS2=0 от системного генератора 
        
    TCNT2 TCNT2_Const//  16000000/256/100/64=8 tcnt2=256-8=248.     
        
    TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2. 

        
    sei();



        for (;;)
        {
            
    _delay_ms(1);
            for (
    uint8_t j=0;j<48;j++)
                
    Brightness[j]++;
        }
        



    UPD: код я у себя тут еще оптимизировал, но выигрыш копеечный.
    Последний раз редактировалось SBorovkov; 11.03.2010 в 05:20.

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 5 (пользователей: 0 , гостей: 5)

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •