RGB светодиод, INT0 прерывание и все это для ATtiny13

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

ibiza11, супер спасибо большое!!!!!все продвигается вперед)но добавил три строчки и память на 0.6 процентов переполнена...может еще что нидь убрать???вот код
еще может знаете почему прерывание иногда срабатывает если дотронуться до минуса?просто касаюсь и вырубает или врубает(

Код: Выделить всё

#define F_CPU 9600000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
unsigned char e;
unsigned char state = 0;
void abc(unsigned char a, unsigned char b, unsigned char c, unsigned char status);
unsigned char pwm[3]={255,255,255};
unsigned char to[3]={255,255,255};
int main(void)
{
   DDRB  = 0b00011001; 
   PORTB = 0b00011011;

   ACSR = (1<<ACD);
   GIMSK = (1<<INT0);

   TCCR0A = 0x00;
   TCCR0B = (1<<CS00);
   TIMSK0 = (1<<TOIE0);
   sei();
   while(1){
      if (pwm[0]<to[0]) pwm[0]++;
      if (pwm[0]>to[0]) pwm[0]--;
      if (pwm[1]<to[1]) pwm[1]++;
      if (pwm[1]>to[1]) pwm[1]--;
      if (pwm[2]<to[2]) pwm[2]++;
      if (pwm[2]>to[2]) pwm[2]--;
      if(pwm[0]==to[0]&&pwm[1]==to[1]&&pwm[2]==to[2]){
         to[0]=rand()%255;
         to[1]=rand()%255;
         to[2]=rand()%255;
      }
	  _delay_ms(20);							//задержка для заметности изменения цвета или скорость изменения цвета
      if (state == 0){
         sleep_disable();
      } else {
         PORTB |= 0b00011001;
         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
         sleep_enable(); 
         sleep_mode();
      }
   }
}

ISR(TIM0_OVF_vect)
{
   if(++e == 0)
      PORTB |= 0b00011001;
   else {
      if(pwm[0] == e)
         PORTB &= ~(1<<3);
      if(pwm[1] == e)
         PORTB &= ~(1<<4);
      if(pwm[2] == e)
         PORTB &= ~(1<<0);
   }
}


ISR(INT0_vect) { 
   state ^= 0x01;
   while(!(PINB&0b00000010));
   PORTB |= 0b00011001;     //задержка в секунду чтобы убрать руку от кнопки + отключение светодиодов сразу по нажатию на кнопку
   _delay_ms(1000);
} 
stalker007, спасибо уже проблема почти решена)но идею надо когда нибудь попробовать)
Реклама
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

сейчас замерил потребление тока в активном режиме и в спячке, 20 мА в активном, 0,03мкА в спячке!!!!я и не думал что так мало кушать будет!!!!
Реклама
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

ibiza11, а можно еще поинтересоваться зачем в прерывании эта строчка???

Код: Выделить всё

while(!(PINB&0b00000010));
без нее тоже пашет отлично, а память она кушает(
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

эта строчка проверяет нажата ли еще кнопка (у вас ведь кнопка замыкается на землю при нажатии?)
если нажата, то не выходит из прерывания. Это вместо Вашей задержки на 1 секунду.
Если в прерывании тушите светодиоды, то можно убрать аналогичную строчку "тушения" светодиодов из главного цикла (в условии проверки переменной state)
Ставим плюсы: )
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

не знаю почему, но если из кода который я скинул в прошлый раз убрать задержку на секунду из прерывания,то проц просыпается и засыпает если просто дотронуться рукой до минуса, плюс срабатывает неуверенно
надо бы сделать так чтобы как только была нажата кнопка были выключены светодиоды и переход в спячку, а при последющем нажатии соответственно все наоборот)
есть идею в чем затык с минусом?
ПС кнопка на минус идет все верно)
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

А с запиткой все правильно? Ну там блокировочные конденсаторы и все такое.
Контактная информация:
Реклама
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

планирую питать от часовой батарейки на 3 вольт, но сейчас подключен к обычному стабу 7805 с кондерами все как надо
на самом деле работает нормально если добавить задержку в секунду......странно
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

попробуйте так:

Код: Выделить всё

#define F_CPU 9600000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
unsigned char e;
unsigned char state = 0;
void abc(unsigned char a, unsigned char b, unsigned char c, unsigned char status);
unsigned char pwm[3]={255,255,255};
unsigned char to[3]={255,255,255};
unsigned char timer;
void change_pwm(unsigned char index);

int main(void)
{
   DDRB  = 0b00011001; 
   PORTB = 0b00011011;

   ACSR = (1<<ACD);
   GIMSK = (1<<INT0);

   TCCR0A = 0x00;
   TCCR0B = (1<<CS00);
   TIMSK0 = (1<<TOIE0);
   sei();
   while(1) {
      if(timer==0) {
         change_pwm(0);
         change_pwm(1);
         change_pwm(2);
         if(pwm[0]==to[0] && pwm[1]==to[1] && pwm[2]==to[2]){
            to[0]=rand()%255;
            to[1]=rand()%255;
            to[2]=rand()%255;
         }
      }
      if (state == 0){
         sleep_disable();
      } else {
         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
         sleep_enable(); 
         sleep_mode();
      }
   }
}

ISR(TIM0_OVF_vect) {
   if(++e == 0) {
      timer++;
      PORTB |= 0b00011001;
   } else {
      if(pwm[0] == e)
         PORTB &= ~(1<<3);
      if(pwm[1] == e)
         PORTB &= ~(1<<4);
      if(pwm[2] == e)
         PORTB &= ~(1<<0);
   }
}


ISR(INT0_vect) { 
   state ^= 0x01;
   PORTB |= 0b00011001;
   while(!(PINB&0b00000010));
}

void change_pwm(unsigned char index) {
   if (pwm[index]<to[index]) pwm[index]++;
   if (pwm[index]>to[index]) pwm[index]--;
} 
Добавлю, что этот код (почти этот, с учетом перевода его на IAR) у меня скомпилировался в
291 bytes of CODE memory (+ 8 bytes shared)
9 bytes of DATA memory (+ 9 bytes shared)

Вы вообще оптимизацию не используете?
Ставим плюсы: )
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

а вот этот код не пашет((светодиод цвет не меняет, горит слабее раза в четыре чем обычно и всеми сразу цветами)
по нажатию на кнопку уходит спать, и то не всегда перед этим еще пару раз моргнет светодиодами и все, потом просыпается опять если потрогать минус, иногда вообще не просыпается, иногда нормально с кнопкой просыпается(
вот эта прошивка у меня компилируется в 962 байта + 13 байтов данных, программа занимает 93.9 процентов памяти)
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Блин да хоть плюс хоть минус,хоть п*сю потрогай, не должно ничего на Мк влиять :))) . Что еще за сенсорная схема?
Вообще схему в студию, а то я еще ни разу ее не видел, только догадываться могу по программе.

А насчет того что код большого размера получается ibiza11 правильно сказал- нужно включить оптимизацию по минимальному размеру.
Контактная информация:
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

ладно с минусами и п*сями проехали) схему выложу чуть позже) сейчас не могу)
я какой бы уровень оптимизации в мейкфайле не задавал мне всегда одно и то же компилирует(в чем проблема?
если я выберу другой уровень оптимизации, то смогу запихать туда в два раза больше получается?)
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Нужно уровень оптимизации -Os, тогда нормально должно быть.
В два раза больше не получится запихать, но точно размер выходного кода уменьшится.
Контактная информация:
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

так вот у меня S и стоит)один фиг)
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Сейчас попробовал скомпилировать- точно 94% занимает.
AVR Memory Usage
----------------
Device: attiny13

Program: 966 bytes (94.3% Full)
(.text + .data + .bootloader)

Data: 13 bytes (20.3% Full)
(.data + .bss + .noinit)
Зато без лишней функции :
AVR Memory Usage
----------------
Device: attiny13

Program: 954 bytes (93.2% Full)
(.text + .data + .bootloader)

Data: 13 bytes (20.3% Full)
(.data + .bss + .noinit)
убрал

Код: Выделить всё

void change_pwm(unsigned char index) {
   if (pwm[index]<to[index]) pwm[index]++;
   if (pwm[index]>to[index]) pwm[index]--;
}  
вместо

Код: Выделить всё

   change_pwm(0);
   change_pwm(1);
   change_pwm(2); 
вписал

Код: Выделить всё

 
for(uint8_t index=0;index<=2;index++){
    if (pwm[index]<to[index]) pwm[index]++;
    if (pwm[index]>to[index]) pwm[index]--;
} 
Контактная информация:
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

даже если исправить точку с запятой на запятую выдает сообщение об ошибке(((((
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

попробуйте зашить вот этот кекс
604 bytes of CODE memory (+ 12 range fill )
28 bytes of DATA memory (+ 9 absolute )
Вложения
222.hex
(1.72 КБ) 339 скачиваний
Ставим плюсы: )
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

не пашет вообще)даже не горит ничего)
давайте вернемся к тому месту где все работало и не хватало места на еще одну строчку задержки)есть возможность впихнуть ее туда?)

Код: Выделить всё

#define F_CPU 9600000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
unsigned char e;
unsigned char state = 0;
void abc(unsigned char a, unsigned char b, unsigned char c, unsigned char status);
unsigned char pwm[3]={255,255,255};
unsigned char to[3]={255,255,255};
int main(void)
{
   DDRB  = 0b00011001; 
   PORTB = 0b00011011;

   ACSR = (1<<ACD);
   GIMSK = (1<<INT0);

   TCCR0A = 0x00;
   TCCR0B = (1<<CS00);
   TIMSK0 = (1<<TOIE0);
   sei();
   while(1){
      if (pwm[0]<to[0]) pwm[0]++;
      if (pwm[0]>to[0]) pwm[0]--;
      if (pwm[1]<to[1]) pwm[1]++;
      if (pwm[1]>to[1]) pwm[1]--;
      if (pwm[2]<to[2]) pwm[2]++;
      if (pwm[2]>to[2]) pwm[2]--;
      if(pwm[0]==to[0]&&pwm[1]==to[1]&&pwm[2]==to[2]){
         to[0]=rand()%255;
         to[1]=rand()%255;
         to[2]=rand()%255;
      }
     _delay_ms(20);                     //задержка для заметности изменения цвета или скорость изменения цвета
      if (state == 0){
         sleep_disable();
      } else {
         PORTB |= 0b00011001;
         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
         sleep_enable(); 
         sleep_mode();
      }
   }
}

ISR(TIM0_OVF_vect)
{
   if(++e == 0)
      PORTB |= 0b00011001;
   else {
      if(pwm[0] == e)
         PORTB &= ~(1<<3);
      if(pwm[1] == e)
         PORTB &= ~(1<<4);
      if(pwm[2] == e)
         PORTB &= ~(1<<0);
   }
}


ISR(INT0_vect) { 
   state ^= 0x01;
   while(!(PINB&0b00000010));
   PORTB |= 0b00011001;     //задержка в секунду чтобы убрать руку от кнопки + отключение светодиодов сразу по нажатию на кнопку
   _delay_ms(1000);
}
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

robototechnik В курсе, что delay_Xs(YY) это на самом деле гора ненужных команд, которые с использованием аппаратного счетчика в режиме таймера можно сократить?
Контактная информация:
Открыл глаза
Сообщения: 75
Зарегистрирован: Сб апр 20, 2013 23:15:21

Сообщение robototechnik »

в курсе, сокращать не умею(((
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

к слову о предыдущей прошивке. При переходе на IAR я мог накосячить где-нибудь в настройках проекта, поскольку давно в нем не работал (сейчас плотно в keil-mdk работаю).
таймер у Вас тикает с частотой контроллера, без предделителя, таймер 8-битный, соответственно переполняется каждые 256 тиков контроллера. Т.е. с частотой 9600000/256=37500 Гц, это значит, что каждые 26,(6) микросекунд происходит прерывание таймера по переполнению. С такой дискретностью (26,6мкс) можно выдержать любой интервал времени, вместо использования delay_ms(x), просто заведя переменную, которая будет инкрементироваться при каждом прерывании в таймере. Значение этой переменной Вы можете проверять перед выполнением какой-либо функции, и если значение меньше необходимого значения, то просто не выполнять функцию, иначе обнулить переменную и выполнить функцию. Вуаля. И никаких задерживающих циклов.
Преимущество данного метода очевидно: контроллер не стоит на месте во время необходимой задержки, а продолжает идти дальше по коду, обслуживая при этом другие задачи.
PS + бонус - тратится меньше программной памяти)
Ставим плюсы: )
Ответить

Вернуться в «AVR»