Пример работы с протоколом RC5 decoder на AVR микроконтроллере ATmega8

"...Хорошие художники - копируют,
великие художники - воруют..."
П.Пикассо

Далее я представлю рабочий код программы-декодера сигналов протокола RC5 для ИК пультов дистанционного управления.
Программа не моя, за нее хочу сказать большое спасибо парню по имени Peter Dannegger.
Комментарии мои, но в некоторых частях кода я реально не въеду что автор хотел сказать своими комментариями поэтому перевод был или оставлен как есть или далеко не дословный.

Программа протестирована с ИК датчиком TSOP1736. Программа обработки RC5 состоит из трех файлов, которые необходимо поместить в один проект AVR Studio, названия файлов необходимо сохранить так, чтобы они подтягивали без проблем друг друга.

Содержание первого файла, я назвал его RC5_german_lib.c
В файле находиться подпрограмма инициализации модуля USART, подпрограммы отправки символа по USART и строки.

  1. #include "rc5_german.h"
  2. #include "rc5_german_c.c"
  3.  
  4. //Программа вывода символа
  5. void putchar( char c )
  6. {
  7. while( (UCSRA & 1<<UDRE) == 0 );
  8. UDR = c;
  9. }
  10.  
  11. //Программа вывода строки
  12. void puts( char *s )
  13. {
  14. while( *s )
  15. putchar( *s++ );
  16. }
  17.  
  18. //Основная программа
  19. int main( void )
  20. {
  21. uint i;
  22. char s[30];//переменная строковая
  23.  
  24. TCCR0 = 1<<CS02; //Деление тактовой частоты на 256
  25. TIMSK = 1<<TOIE0; //Разрешаем прерывание по таймеру
  26.  
  27. UBRRL = bauddivider; //Устанавливаем значение baud rate
  28. UBRRH = bauddivider >> 8;
  29. UCSRA = 0;//не используем режим U2X
  30. UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0;//формат данных 8бит
  31. UCSRB = 1<<RXEN^1<<TXEN;//Разрешаем прием и передачу
  32.  
  33. sei();//Разрешаем глобально прерывания
  34. puts( "RC5-Decoder:\n\r" );//Выводим строку приветствия
  35. for(;;)//Главный цикл
  36. {
  37. cli();//запрет прерывания
  38. i = rc5_data;//Читаем два байта из прерывания
  39. rc5_data = 0;
  40. sei();//разрешаем прерывания
  41. if( i )
  42. {
  43. DDRB = i; // LED output
  44. putchar(( i >> 11 & 1) + '0');//Выводим значение триггерного бита
  45. putchar(' ');//пробел
  46. itoa( i >> 6 & 0x1F, s, 10);//Выводим адрес устройства
  47. puts( s );
  48. putchar(' '); //пробел
  49. itoa((i & 0x3F)|(~i >> 7 & 0x40), s, 10);//Выводим код команды
  50. puts( s );
  51. puts( "\n\r" ); //Выводим конец строки
  52. }
  53. }
  54. }

Далее листинг содержания файла rc5_german_c.c
В этом файле непосредственно реализован алгоритм декодера RC5.

  1. #include "rc5_german.h"
  2.  
  3. #define RC5TIME 1.778e-3 // 1.778msec Длительность одного бита
  4. #define PULSE_MIN (uchar)(XTAL / 512 * RC5TIME * 0.4 + 0.5)
  5. #define PULSE_1_2 (uchar)(XTAL / 512 * RC5TIME * 0.8 + 0.5)
  6. #define PULSE_MAX (uchar)(XTAL / 512 * RC5TIME * 1.2 + 0.5)
  7.  
  8. uchar rc5_bit;//значение бита
  9. uchar rc5_time;//Подсчет количества бит
  10. uint rc5_tmp;//Переменная для хранения временных значений
  11. uint rc5_data;//Переменная для результата
  12.  
  13. //Обработчик прерывания по таймеру
  14. SIGNAL (SIG_OVERFLOW0)
  15. {
  16. uint tmp = rc5_tmp; // for faster access
  17.  
  18. TCNT0 = -2; // 2 * 256 = 512 cycle
  19.  
  20. if( ++rc5_time > PULSE_MAX ){ // count pulse time
  21. if( !(tmp & 0x4000) && tmp & 0x2000 )//Только если приняли 14 бит
  22. rc5_data = tmp;
  23. tmp = 0;
  24. }
  25.  
  26. if( (rc5_bit ^ xRC5_IN) & 1<<xRC5 ){ // change detect
  27. rc5_bit = ~rc5_bit; // 0x00 -> 0xFF -> 0x00
  28.  
  29. if( rc5_time < PULSE_MIN ) // to short
  30. tmp = 0;
  31.  
  32. if( !tmp || rc5_time > PULSE_1_2 ){ // start or long pulse time
  33. if( !(tmp & 0x4000) ) // not to many bits
  34. tmp <<= 1; // shift
  35. if( !(rc5_bit & 1<<xRC5) ) // inverted bit
  36. tmp |= 1; // insert new bit
  37. rc5_time = 0; // count next pulse time
  38. }
  39. }
  40.  
  41. rc5_tmp = tmp;
  42. }

И наконец третий файл rc5_german.h
В этом файле находятся все конфигурационные данные и переменные необходимые для работы.

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/signal.h>
  4. #include <stdlib.h>
  5.  
  6. #define uchar unsigned char
  7. #define uint unsigned int
  8.  
  9. #define xRC5_IN PIND//Задаем порт для датчика
  10. #define xRC5 PD2 //Задаем ногу порта для датчика
  11.  
  12. #define XTAL 16e6//Задаем частоту кварца
  13. //#define XTAL 11.0592e6
  14. //#define XTAL 7.3728e6
  15. //#define XTAL 5e6
  16.  
  17. #define BAUD 19200//Задаем скорость соединения по USART
  18. //#define BAUD 115200
  19.  
  20. #define bauddivider (uint)(XTAL / BAUD / 16 - 0.5)
  21.  
  22. extern uint rc5_data;//Задаем переменную для хранения полученного результата

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

По моим комментариям все думаю понятно, сам принцип работы протокола RC5 и структура пакета уже упоминались. Данную программу можно применять в различных конструкция требующих дистанционного управления, то есть не требующие физического контакта с объектом. Программа разработана под микроконтроллер семейства AVR Atmega8.

Принципиальная схема для декодера сигналов протокола RC5 на микроконтроллере ATmega8 показана на рис. 1
принципиальная схема RC5 декодера
Рис. 1

Atmega8 макетная плата
Вот так выглядит собранная схема для проверки работы декодера RC5 команд.

Откомпилированный код занимает совсем мало места в памяти микроконтроллера, поэтом возможны некоторые добавки к коду, например система декодера команд - выполнение определенной функции по приходу определенной команды.

Программа выполняет прием и обработку принятой команды с пульта и отправляет полученное по порту USART на компьютер. Для приема данных от модуля USART микроконтроллера на компьютер необходимо собрать конвертер уровней.

Мониторить принятые данные рекомендую через программу Terminal RS232.

Вот что вы увидите после запуска программы.
RC5 декодер в работе
Отклик от устройства состоит из трех частей, первая - значение триггер бита, второе - код устройства, номер команды.

По многочисленным просьбам файл с проектом:
Скачать проект RC5 на ATmega8
Как ни странно, забил все файлы, выбрал контроллер, нажал "Build" и все ок.
Никаких ошибок. Сразу вспомнился анекдот про прокладку между рулем и сидением :-)
Примечание: сам файл с библиотекой обработки RC5 протокола добавлять не нужно, его нужно просто сохранить в папку с основным файлом проекта.

Видео работы декодера RC5, немного хреновенько видно что там происходит, но поверьте оно работает:

Следующий код, выполняет определенные действия в зависимости от полученного номера кнопки нажатой на пульте Д/У.

  1. #include "rc5_german.h"
  2. #include "rc5_german_c.c"
  3. //Программа вывода символа
  4. void putchar( char c )
  5. {while( (UCSRA & 1<<UDRE) == 0 ); UDR = c;}
  6.  
  7. //Программа вывода строки
  8. void puts( char *s )
  9. { while( *s ) putchar( *s++ );}
  10.  
  11. //Основная программа
  12. int main(void)
  13. {
  14. uint i;
  15. char s[30];//переменная строковая
  16.  
  17. TCCR0 = 1<<CS02; //Деление тактовой частоты на 256
  18. TIMSK = 1<<TOIE0; //Разрешаем прерывание по таймеру
  19.  
  20. UBRRL = bauddivider; //Устанавливаем значение baud rate
  21. UBRRH = bauddivider >> 8;
  22. UCSRA = 0;//не используем режим U2X
  23. UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0;//формат данных 8бит
  24. UCSRB = 1<<RXEN^1<<TXEN;//Разрешаем прием и передачу
  25.  
  26. sei(); //Разрешаем глобально прерывания
  27. puts( "RC5-Decoder:\n\r" ); //Выводим строку приветствия
  28.  
  29. for(;;) //Главный цикл
  30. {
  31. cli(); //запрет прерывания
  32. i = rc5_data; //Читаем два байта из прерывания
  33. rc5_data = 0;
  34.  
  35. sei();//разрешаем прерывания
  36.  
  37. if( i )
  38. {
  39. int n = ((i & 0x3F)|(~i >> 7 & 0x40)); //Выделяем только код команды
  40.  
  41. switch (n) //Проверяем что выполнять в зависимости от команды
  42. {
  43. case 7: puts( "This is 7"); puts( "\n\r" ); break; //выполняем действие по кнопке 7
  44. case 5: puts( "This is 5"); puts( "\n\r" ); break; //выполняем действие по кнопке 5
  45. case 0: puts( "This is 0"); puts( "\n\r" ); break; //выполняем действие по кнопке 0
  46. }
  47. }
  48. }
  49. }

включить-выключить по одной кнопке

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

  1. #include "rc5_german.h"
  2. #include "rc5_german_c.c"
  3. void putchar( char c )
  4. {while( (UCSRA & 1<<UDRE) == 0 ); UDR = c;}
  5.  
  6. void puts( char *s )
  7. { while( *s ) putchar( *s++ );}
  8.  
  9. int main(void)
  10. {
  11. uint i;
  12. int u=0;
  13. char s[30];
  14.  
  15. DDRB = 00000111; настройка порта В на выход
  16. TCCR0 = 1<<CS02;
  17. TIMSK = 1<<TOIE0;
  18.  
  19. UBRRL = bauddivider;
  20. UBRRH = bauddivider >> 8;
  21. UCSRA = 0;
  22. UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0;
  23. UCSRB = 1<<RXEN^1<<TXEN;
  24. PORTB = 0x00;
  25. sei();
  26. puts( "RC5-Decoder:\n\r" );
  27.  
  28. for(;;)
  29. {
  30. cli();
  31. i = rc5_data;
  32. rc5_data = 0;
  33.  
  34. sei();
  35.  
  36. if( i )
  37. {
  38. int n = ((i & 0x3F)|(~i >> 7 & 0x40));
  39.  
  40. switch (n)
  41. {
  42. case 7:
  43. if (u==0)
  44. {u=1;}
  45. else
  46. {u=0;}
  47. break;
  48. case 5:
  49. if (u==0)
  50. {u=1;}
  51. else
  52. {u=0;}
  53. break;
  54. case 1:
  55. if (u==0)
  56. {u=1;}
  57. else
  58. {u=0;}
  59. break;
  60.  
  61. }
  62. }
  63. }
  64. void u_check (void)
  65. {
  66. if(u==0) {PORTB = 0b00000111;}
  67. else {PORTB = 0b00000000;}
  68. }
  69. }

для использования кварца на

для использования кварца на 7.372
#define PULSE_MIN (uchar)(XTAL / 512 * RC5TIME * 0.4 + 0.5)
#define PULSE_1_2 (uchar)(XTAL / 512 * RC5TIME * 0.8 + 0.5)
#define PULSE_MAX (uchar)(XTAL / 512 * RC5TIME * 1.2 + 0.5)
только тут нужно меня значения если uart не используется? и на какие подскажите

Тут ничего менять не нужно, у

Тут ничего менять не нужно, у тебя переменная XTAL зажается выше и тут она уже сама учатвует со своим значением. Форумыл не трогай, задай свою частоту кварца и все. В юарте если будешь использовать его посмотри в таблицу скоростей и найти свое значение Baud rate. Таблица в даташите на твой микроконтроллер.

Подскажите, хочу

Подскажите, хочу использовать,кварц на 7.372,кроме строчки XTAL 7.3728e6, нужно еще что ни будь менять, и еще вопрос если захочу на мегу16 залить, то просто изменть в настройках проекта на 16 вместо 8?

1. Да просто меняешь строчку

1. Да просто меняешь строчку и частоту в настройках проекта.
2. Да, меняешь в настройках проекта микроконтроллер на ATmega16.

Пробуй и отписывайся о успехах.

кто может, объясните строчки

кто может, объясните строчки

  1. {case 7: puts( "This is 7"); puts( "\n\r" ); break; //выполняем действие по кнопке 7
  2. case 5: puts( "This is 5"); puts( "\n\r" ); break; //выполняем действие по кнопке 5
  3. case 0: puts( "This is 0"); puts( "\n\r" ); break; //выполняем действие по кнопке 0

так ли будет
  1. case 3: puts( "This is 3"); puts( "\n\r" ); break; //выполняем действие для кнопки 3

и как конкретней вписать и куда действие для вкл светодиода на ножке 3, можно ли сделать что бы по одной команде вкл она и по повторном нажатии выкл?

По двум нажатиям все можно,

По двум нажатиям все можно, для этого заводится переменная состояния включенного или выключенного светодиода.
При нажатии кнопки выполняется смена переменной например с "1" на "0" что будет означать включение светодиода. Отдельно пишешь функцию, которая проверяет эту переменную и если она равна "0" включает светодиод, только её надо вызывать сразу же после изменения состояния переменной. Все понял?

К сожалению нет, я

К сожалению нет, я начинающий, а ты можешь пример привести для вкл и выкл для
case 7: puts( "This is 7"); puts( "\n\r" ); break; //выполняем действие по кнопке 7
, а для остальных я уже тогда по аналогии, буду бесконечно признателен

вот код

  1. int u=0;//декларируем переменную состояния, задаем значение 0
  2. /////////////////////////////////////////////////
  3. case 7: puts( "This is 7"); puts( "\n\r" );
  4. if(u==0) //если предидущее значение было ноль
  5. {u=1;}//меняем на единицу
  6. else
  7. {u=0;}//если не ноль то меняем на ноль
  8. break;
  9. /////////////////////////////////////////////////
  10.  
  11. void u_check (void)
  12. {
  13. if(u==0) {PORTB = 0b00000001;}//включаем светодиод
  14. else (PORTB = 0b00000000;}//выключаем светодиод
  15. }

Огромное спасибо :)

Огромное спасибо :)

Попробуй и отпишись, вышло

Попробуй и отпишись, вышло или нет.

не получилось((( делал

не получилось((( делал так:

  1. #include "rc5_german.h"
  2. #include "rc5_german_c.c"
  3. //Программа вывода символа
  4. void putchar( char c )
  5. {while( (UCSRA & 1<<UDRE) == 0 ); UDR = c;}
  6.  
  7. //Программа вывода строки
  8. void puts( char *s )
  9. { while( *s ) putchar( *s++ );}
  10.  
  11. //Основная программа
  12. int main(void)
  13. {
  14. uint i;
  15.  
  16. int u=0;
  17.  
  18. char s[30];//переменная строковая
  19.  
  20. TCCR0 = 1<<CS02; //Деление тактовой частоты на 256
  21. TIMSK = 1<<TOIE0; //Разрешаем прерывание по таймеру
  22.  
  23. UBRRL = bauddivider; //Устанавливаем значение baud rate
  24. UBRRH = bauddivider >> 8;
  25. UCSRA = 0;//не используем режим U2X
  26. UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0;//формат данных 8бит
  27. UCSRB = 1<<RXEN^1<<TXEN;//Разрешаем прием и передачу
  28.  
  29. sei(); //Разрешаем глобально прерывания
  30. puts( "RC5-Decoder:\n\r" ); //Выводим строку приветствия
  31.  
  32. for(;;) //Главный цикл
  33. {
  34. cli(); //запрет прерывания
  35. i = rc5_data; //Читаем два байта из прерывания
  36. rc5_data = 0;
  37.  
  38. sei();//разрешаем прерывания
  39.  
  40. if( i )
  41. {
  42. int n = ((i & 0x3F)|(~i >> 7 & 0x40)); //Выделяем только код команды
  43.  
  44. switch (n) //Проверяем что выполнять в зависимости от команды
  45. {
  46. case 7:
  47. if(u==0) //если предидущее значение было ноль
  48. {u=1;}//меняем на единицу
  49. else
  50. {u=0;}//если не ноль то меняем на ноль
  51. break;
  52. case 5: puts( "This is 5"); puts( "\n\r" );
  53. break; //выполняем действие по кнопке 5
  54. case 0: puts( "This is 0"); puts( "\n\r" );
  55. break; //выполняем действие по кнопке 0
  56. }
  57. }
  58. }
  59. void u_check (void)
  60. {
  61. if(u==0) {PORTB = 0b00000001;}//включаем светодиод
  62. else {ORTB = 0b00000000;}//выключаем светодиод
  63. }
  64. }

Прошивка

Проблема с компиляцией в hex. Собираю все 3 файла в одном проекте студии и при компиляции вижу:

Build started 8.5.2011 at 23:53:28
avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -O0 -Wp,-M,-MP,-MT,RC5_german_lib.o,-MF,dep/RC5_german_lib.o.d -c ../../RC5_german_lib.c
../../RC5_german_lib.c:5: warning: conflicting types for built-in function 'putchar'
../../RC5_german_lib.c:12: warning: conflicting types for built-in function 'puts'
../../RC5_german_lib.c:54: fatal error: opening dependency file dep/RC5_german_lib.o.d: No such file or directory
compilation terminated.
make: *** [RC5_german_lib.o] Error 1
Build failed with 1 errors and 2 warnings...

Кто знает в чём проблемма, подскажите пожалуйсто.

выложи исходники

У меня теже грабли.
Автор выложи проект в AVRStudio. Так будет намного проще разбираться

Добавил, качайте.

Добавил, качайте.

Прошивка

Пытаюсь компилировать как вы сказали, но постоянно выдает ошибку:

RC5_german_lib.o: In function `__vector_9':
D:\RC5\default/../rc5_german_c.c:12: multiple definition of `__vector_9'
rc5_german_c.o:D:\RC5\default/../rc5_german_c.c:12: first defined here
make: *** [rc5_german_c.elf] Error 1
Build failed with 1 errors and 4 warnings...

Как исправить?

Прошивка

Уважаемый автор.
Я не силен в программировании микроконтроллеров.
Пожалуйста, подскажите, где можно скачать откомпилированную прошивку? Или расскажите пошагово как получить .hex
Спасибо.

Читаем Цель - получить *.hex

У меня такая же ошибка

У меня такая же ошибка прикомпиляции.

RC5_german_lib.o: In function `__vector_9':
D:\RC5\default/../rc5_german_c.c:12: multiple definition of `__vector_9'
rc5_german_c.o:D:\RC5\default/../rc5_german_c.c:12: first defined here

К чему писать про "Цель - получить *.hex файл"? multiple definition of `__vector_9' - hex-файл не собирается, потому что множественное определение __vector_9.

Мало того, в хидере надо закомментировать строку 3, #include , иначе тоже компилятор орет благим матом:
c:/avr/winavr/lib/gcc/../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use ."

Выкладывайте рабочий проект.

Уважаемый АНОНИМ, качай

Уважаемый АНОНИМ, качай проект, тот который я за 2 минуты билднул.
В результате ошибок 0! замечаний 3 - связаны с функциями вывода по UART данных.

Добрый день, Уважаемый

Добрый день,
Уважаемый extremist -есть вопросы по выложенному проекту - не нашел строк где определяется то, как будут использоваться порты В и D, также не понял вот этой строки в файле RC5_german_lib.c
DDRB = i; // LED output - по идее должно быть PORTB = i ?
Сори если вопросы чайницкие.
Михаил.

1. Михаил чего не

1. Михаил чего не регистрируешься на сайте?
2. DDRB = i; // LED output - имеется в виду настройка порта на вывод информации.

Зачем порты B и D?
Нужен один порт, даже просто один вывод порта, для подключения к нему ИК датчика.
С остальными портами можно делать что хочешь.

В других устройствах.

А чтобы в других устройствах использовать RC-5 мне надо переменную rc5_data брать и подставлять в нужные функции? И как мне значения переменной каждой кнопки узнать, подключить к компу и все кнопки считать, наверно так?
Если я не так понял, можешь небольшой кусок кода для примера выложить? Скажем: одна кнопка зажигает светодиод, а другая гасит. Думаю, кому-то пригодится. :)

Вот так обработку массива я делал

Код срабатывает если первый элемент массива "1" а второй "2".
Так же можно выполнить проверку на соответствие другой комбинации цифр, и на большее количество цифр.

  1. //Массив в который будем принимать код команды
  2. char mass [2] = {0,0};
  3.  
  4. while(1)
  5. {
  6. if (mass[0]=='1') //Если первый элемент "1"
  7. {
  8. if(mass[1]=='2') //Если второй элемент "2"
  9. {
  10. USART_Transmit('Y'); //Выводим
  11. USART_Transmit('e'); //на USART
  12. USART_Transmit('S'); //слово "YES"
  13.  
  14. USART_Transmit(0x0d); //Начало строки
  15. USART_Transmit(0x0a); //Переход на новую строку
  16.  
  17. mass [0] = 0; //После срабатывания
  18. mass [1] = 0; //устанавливаем все элементы равными "0"
  19. }
  20. }
  21. }

В данном коде я делал что один МК принимает ИК команды пульта а второй выполняет действия при приеме определенной последовательности чисел. Это было по причине что МК который принимает ИК команды, все время срабатывает на прерывание по счетчику, по сему нормально работать он не может.

хм. а если мне надо, чтобы

хм. а если мне надо, чтобы программа одновременно смотрела и пульт, и нажатие кнопки? интересно,какое энергопотребление будет у устройства в режиме ожидания сигнала с ИК пульта?

Так заводишь устройство в

Так заводишь устройство в спящий режим, ждешь пока не будет принять сигнал на TSOP после чего будишь устройтво и обрабатываешь уже принятую комманду.

в теории легко, увидеть бы

в теории легко, увидеть бы это в синтаксисе c...
кстати, не в курсе, чем отличаются 17 от 18 серии?

Производителем и несущей

Производителем и несущей частотой.
Для кода программы определенного назначения для начала ТЗ необходимо составить и хотя бы наброски кода.
А дальше я думаю пользователи помогут.

просто видел в продаже и

просто видел в продаже и tsop1736 и tsop1836 - частота как будто одинаковая)

про ТЗ - думал попробовать в качестве эксперимента типа для учебных целей сделать термометр с несколькими датчиками на ds1820, который бы сам включался от пульта и переключался между датчиками им же, а, скажем, через минуту после включения - выключался.

как в выключенном режиме измерить энергопотребление? (просто оценить, насколько живуч он будет от батарейки?)
ставить амперметр в цепь? кажется, мне все же придется внимательно проштудировать все 223 страницы даташыта... :-)

кстати, немного не ясно про датчики - видел на инстрактаблз.ком, как подключают пульт от мака (там как будто нековский протокол, отличный от RC5, и частота не 36, а 38кГц). и там просто сказано, нужен фотоприемник -не указывали, какой именно. зачем там вообще эти разные частоты? разве мы частоту светодиода задаем не программным путем? или я не так понял? и как это решается на фотоприемниках? (что это, фотодиод? фтотранзистор или фоторезистор?) я спалил свой датчик - какое можно найти применение его фототранзистору?

и вопрос по схеме - обязательно ли нужен внешний кварц, или можно обойтись внутренним (опять по количеству ножек пытаюсь уложиться)

На первой странице даташита

На первой странице даташита на атмеловские АВР-ки дано потребление в спящем режиме. Доплюсуй до этого потребление остальной периферии (ЖКИ, датчики и прочую лабуду можно отрубать от питания в спящем режиме). Только теперь встает вопрос - как будить? Через внешнее прерывание?

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

более менее понятно. еще

более менее понятно. еще разобраться, какой командой уводить в сон, и что начинает происходить после пробуждения (и что, если это же внешнее прерывание уже используется в других целях?). приплюсовать потребление в этом случае - подразумевается потребление ИК датчика (и резонатора)? и кстати, отрубать остальную периферию - через 0 на ножке микроконтроллера, или есть какие-то другие хитрые методы?

про точность измерений - в том-то и вопрос, хватит мне внутреннего для отсчета импульсов RC5 и DS18B20?

asm("sleep"); После

asm("sleep");

После пробуждения происходит загрузка состояния МК из "свопа".

Тогда внешнее прерывание будет выводить МК из сна.

Отрубать остальное можно и через 0 и через 1. Сморя какой транз поставишь.

Для работы с DS18b20 хватит точности встроенного RC генератора.

а для ИК внутреннего

а для ИК внутреннего генератора хватит? а для управления сервой?

то есть транзистор в закрытом состоянии энергию не потребляет? а микроконтроллер в спящем режиме по-прежнему способен выдавать 1 и при этом с минимальным потреблением?

и еще, как отключать сервопривод? или если нет pwm сигнала, то энергию он тоже не потребляет?

Ну блин, подумай, хватит тебе

Ну блин, подумай, хватит тебе тактовой частоты 8Мгц?

Транзистор в закрытом состоянии потребляет, зависит от типа и модели транзистора. МК в спящем режиме может выдавать на ножки как лог. ноль, так и лог. единицу.

Сервопривод отключи от питания транзисторным ключом. Если на входе ШИМа ноль, то серва все равно есть какой-то ток.

Все правильно, делаешь

Все правильно, делаешь программу, которая определяет какой код кнопки пришел.
Код из трех цифр состоит. Выбрал нужные кнопки напрмиер кнопка громкость + и -.
Записал к примеру номера кнопок: 102 и 103. Теперь надо программу, которая будет реагировать на эти масивы данных. Я именно так и делал, потом провреял поэлементно на сходство с принятым кодом. И если код пришел тот, что надо, значит выполняются действия.
Код программы вечером попробую выложить.

Для записи видео с монитора.

Есть хорошая программа HyperCam.

Ок А то бывает иногда очень

Ок А то бывает иногда очень надо что-то снять, а айфон не снимает видео у меня 3G а старый Сони Эриксон вот так снимает как на видео.