Перейти к содержанию
    

Как сократить код на C++

Еще один вариант.

  uint8_t reg = 0;
  do {
    reg = (reg<<1 | reg>>7); reg ^= 0x01;
    PORTC = reg;
    wait1();
  } while (reg);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вариантов куча) Спасибо, тогда можно еще вопрос, когда запись у меня была такого рода PORTC.0=1;

wait1();

PORTC.1=1;

wait1(); намного легче было реализовать программный ШИМ, чтобы когда загорались и тухли это происходило плавно, то есть для каждого порта при включении повышал , а при отключении понижал, правда код огромный но понятный, а как в коротком варианте это применять?

кстати пока остановился на этом варианте

for (mask = 0x01; mask; mask <<= 1)

{

PORTC |= mask;

wait1();

}

 

// задержка

wait1();

пробовал для всего порта шим но видимо это не правильно )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну или может кто подскажет решение моей проблемы, или подскажите от чего оттолкнутся. По шим перечитал же кучу статей, но в них или про аппаратный или так как у меня было на каждый порт по отдельности. Спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я правильно понял, вы теперь хотите, чтобы светодиоды не просто включались поочерёдно, а делали это плавно?

Тогда можно заменить

  PORTC |= mask;

на вызов некой функции, которая будет плавно зажигать светодиод:

led_on(mask);

Сама функция может выглядеть как-то так:

void led_on(unsigned int mask){
  unsigned char on_time;
  for (on_time = 1; on_time < 100; on_time++) {
    PORTC &= ~mask;    // выключаем светодиод
    delay(100-on_time);   // отсчитываем время в выключенном состоянии
    PORTC |= mask;    // включаем светодиод
    delay(on_time);   // отсчитываем время во включенном состоянии
}

Здесь мы постепенно увеличиваем процент времени, который светодиод находится во включённом состоянии.

Реализацию функции delay() оставляю вам в качестве самостоятельной работы:)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я правильно понял, вы теперь хотите, чтобы светодиоды не просто включались поочерёдно, а делали это плавно?

Тогда можно заменить

  PORTC |= mask;

на вызов некой функции, которая будет плавно зажигать светодиод:

led_on(mask);

Сама функция может выглядеть как-то так:

void led_on(unsigned int mask){
  unsigned char on_time;
  for (on_time = 1; on_time < 100; on_time++) {
    PORTC &= ~mask;    // выключаем светодиод
    delay(100-on_time);   // отсчитываем время в выключенном состоянии
    PORTC |= mask;    // включаем светодиод
    delay(on_time);   // отсчитываем время во включенном состоянии
}

Здесь мы постепенно увеличиваем процент времени, который светодиод находится во включённом состоянии.

Реализацию функции delay() оставляю вам в качестве самостоятельной работы:)

 

 

Сделал, все работает, осталось дождатся когда приедет программатор с ebay и потестить на железе но в протеусе работает, спасибо за помощь и домашнее задание, теперь переделываю все задержки в своей программе )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дабы не создавать новую тему, спрошу в этой. Подскажите как плавно зажечь и через 10 сек. потушить все светодиоды на порту D. Сейчас использую вот так

 

void led_on(unsigned int mask){
    for (pwm = 1; pwm < Fade; pwm++) { 
    
    PORTD &= mask;     // выключаем светодиоды
    delay(Fade-pwm);   // отсчитываем время в выключенном состоянии
    
    PORTD |= ~mask;    // включаем светодиоды 
    delay(pwm);   // отсчитываем время во включенном состоянии
}


for (mask = 0x01; mask; mask <<= 1)
                {
                 led_on(mask);

 

но включаются они помаргивая.

Изменено пользователем ururur

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помаргивают - видимо слишком большая задержка, глаз начинает видеть моргание.

Уменьшите задержку в 10 раз (например), а для компенсации добавьте внутренний цикл, чтобы на каждом уровне яркости было 10 морганий:

void led_on(unsigned int mask){
    for (pwm = 1; pwm < Fade; pwm++)
        for (char j = 1; j < 10; j++) {  // вот эту строчку добавили

Зы. При оформлении исходников пользуйтесь кнопкой Code: rte-code-button.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Отредактировал сообщение. Спасибо, но при уменьшении задержки плавность включения незаметна ) Просто резкое включение.

Изменено пользователем ururur

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Видимо, где-то со скобочками напутали. Вот как это будет выглядеть целиком:

void led_on(unsigned int mask){
    char j;
    for (pwm = 1; pwm < Fade; pwm++) {
        for (j = 1; j < 10; j++) {    
            PORTD &= mask;     // выключаем светодиоды
            delay(Fade-pwm);   // отсчитываем время в выключенном состоянии
    
            PORTD |= ~mask;    // включаем светодиоды
            delay(pwm);   // отсчитываем время во включенном состоянии
        }
   }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, все-таки моя ошибка в коде(. Теперь включается плавно. Спасибо

 

 

Изменено пользователем ururur

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите пожалуйста, как добавить ограничение яркости в данный код. Сейчас максимальная яркость 100% , хочется сделать 75-50 % . Спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь так просто не получится. Мы же не управляем яркостью всё время, а лишь делаем плавное включение/выключение.

Боюсь, придётся переделывать всю программу - задействовать прерывание от таймера, и в нём делать ШИМ на светодиоды.

Или задействовать аппаратный ШИМ, и регулировать им общее питание светодиодов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задействовать апаратный шим . Не получится ли оставить программу как есть , а ШИМ сделать на весь порт ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не получится ли оставить программу как есть , а ШИМ сделать на весь порт ?

Хотите изврата, тогда ладно. Как вариант вам нужен режим Fast PWM.

Используйте два прерывания по переполнению таймера 1 и по совпадению OCIE1А или OCIE1B, тут разницы нет. Если св.диоды включаются нулем, то в прерывании по совпадению настраивайте Ваш порт на выход. В преривании по переполнению Т1 Ваш порт на вход. Для игрушки в самый раз.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

/*обработчик прерывания**********************************************************************
************************************/
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
countr++;
if (countr == 0){                                
        pwm1   = red;                         
        PORTD.0   = 1;                                               
        }

if (pwm1   == countr) { PORTD   = 0;}            
}
/********************************************************************************
************************************************/

TCCR0=0x01;                                     
TCNT0=0x00;

TIMSK=0x01;                                     

#asm("sei")

 

запускаю таймер

 

а вот как дальше до меня не доходит. Или лучше сразу переписывать прогу ?

Спасибо

Изменено пользователем ipf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...