Помогите разобраться с кодом на Си

Здравствуйте,
Есть контроллер Atmega8, возможно ли присвоить значение одной ножке микроконтроллера не трогая остальные? Т.е. хочется что то вроде PB0 = 1( или 0), а не PORTB = 0b00000001.

Объясни задачу, а именно что

Объясни задачу, а именно что происходит на других ногах???
Если другие ноги работают на прием данных то просто сконфигурируй изначально этот выход порта на вывод данных.
А вообще очень полезная програмулина есть BinHexDec в ней очень наглядно можно выставить состояния выводов порта. и сразу получить код для конфигурации порта.

Как вариант есть старый вид записи:

  1. PORTB |= _BV(PB0); //высокий уровень на вывод порта

Задача состоит в следующем,

Задача состоит в следующем, соединить 2 проекта этого сайта управление RGB светодиодом и клавиатура 4х4 с дисплеем. Изначально реализовал управление RGB через ножки PB1,PB2,PB3. А в проекте с клавиатурой идет обнуление порта полностью PORTB=0x00; Нашел так же на сайте про порты ввода-вывода они могут быть частично сконфигурированы. Отсюда появился вопрос об частичном обнулении порта. После кода еще несколько вопросов.

  1. #include <avr/io.h>
  2. #include <stdlib.h>
  3. #include <avr/interrupt.h>//Библиотека прерываний
  4. //Стандартная библиотека ввода/вывода
  5. //Стандартная библиотека ввода/вывода
  6. #define R_channel OCR1AL
  7. //Определяем канал OCR1AL для Красного цвета
  8. #define G_channel OCR1BL
  9. //Определяем канал OCR1BL для Зеленого цвета
  10. #define B_channel OCR2
  11. //Определяем канал OCR2 для Синего цвета
  12.  
  13.  
  14. unsigned char key;
  15. unsigned char key_code[4][4]={{'C','D','E','F'},
  16. {'B','3','6','9'},
  17. {'A','2','5','8'},
  18. {'0','1','4','7'}};
  19. //матрица соответствия кодов клавиш
  20. //Пауза для задержки
  21. //Программа формирования задержки
  22. void pause (unsigned int a)
  23. {
  24. unsigned int i; //Переменная для задержки
  25. for (i=a;i>0;i--); //Цикл формирования задержки
  26. }
  27.  
  28. //Подпрограмма инициализации таймера
  29. void init_timer (void)
  30. {
  31. TIMSK=(1<<TOIE0);//Разрешить прерывания по переполнению таймера0
  32. TCCR0=(1<<CS00)|(1<<CS01)|(0<<CS02); //Делитель =/64
  33. }
  34.  
  35. ISR (TIMER0_OVF_vect)
  36. {unsigned char i,j;
  37. DDRC &= ~_BV(PC0);//вход
  38. DDRC &= ~_BV(PC1);//...
  39. PORTC=0b00000011;//выводим на 4 младших бита порта C лог. 1
  40. DDRB |= _BV(PB0);//выход
  41. DDRB |= _BV(PB4);//выход
  42. PORTB &= ~_BV(PB0);
  43. PORTB &= ~_BV(PB4);
  44. pause(10); //Задержка для устранения всяких переходных процессов, важно ее не забыть!
  45. i=4;
  46. if ((PINC&0x01)==0x01) i=0; //Если нажата клавиша в 0й колонке, i=0
  47. if ((PINC&0x02)==0x01) i=1; //Если нажата клавиша в 1й колонке, i=1
  48. DDRC |= _BV(PC0);//выход
  49. DDRC |= _BV(PC1);//выход
  50. PORTC=0x00; //обнуляем порт C
  51. DDRB &= ~_BV(PB0);//вход
  52. DDRB &= ~_BV(PB4);//...
  53. PORTB |= _BV(PB0);
  54. PORTB |= _BV(PB4);
  55. pause(10); //Задержка для устранения всяких переходных процессов, важно ее не забыть!
  56. j=4;
  57. if ((PINB&0x01)==0x01) j=0; //Если нажата клавиша в 0й строке, j=0
  58. if ((PINB&0x10)==0x01) j=1; //...
  59. if ((i!=4)&&(j!=4)){ //Если была нажата клавиша
  60. key = key_code[i][j]; //Пишем ее код на ЖКИ
  61. if (key == 'C')
  62. {
  63. R_channel = 0x00;
  64. G_channel = 0xFF;
  65. B_channel = 0xFF;
  66. }
  67. if (key == 'D')
  68. {
  69. R_channel = 0xFF;
  70. G_channel = 0x69;
  71. B_channel = 0xB4;
  72. }
  73. if (key == 'B')
  74. {
  75. R_channel = 0x80;
  76. G_channel = 0x00;
  77. B_channel = 0x80;
  78. }
  79. if (key == '3')
  80. {
  81. R_channel = 0x8B;
  82. G_channel = 0x45;
  83. B_channel = 0x13;
  84. }
  85.  
  86. }
  87. TCNT0=0x00; //Очищаем счетчик
  88. TIFR=0x00; //Очищаем флаг переполнения
  89. return;
  90. }
  91.  
  92.  
  93.  
  94. //Основная программа
  95. int main(void)
  96. {
  97. pause(1000); //Задержка для включения ЖКИ
  98. init_timer(); //Инициализация нулевого таймера
  99. sei(); //Глобальное разрешение прерываний
  100. while(1); //Вечный цикл
  101. {}
  102. }

Почему при отладке нет перемещение в вечный цикл?

Где можно прочитать про объявление PINxy порта как переменные?

  1. #define R_channel OCR1AL - а ножка называется OC1A

Где можно прочитать о прерываниях по переполнению или книгу посоветуйте толковую с примерами на С

  1. TIMSK=(1<<TOIE0);
  2. TCCR0=(1<<CS00)|(1<<CS01)|(0<<CS02);

Заранее спасибо всем откликнувшимся.

Сбрасивыть пин

Сбрасивыть пин порта:

  1. PORTB&=~_BV(2);

Поднять пин:
  1. PORTB|=_BV(2);

Тоже самое применимо к регистрам DDRB, DDRD.

При отладке курсор не перемещается в вечный цикл из-за того, что не сработало условие if ((i!=4)&&(j!=4))
Чтобы заставить загнать курсор в вечный цикл - следует вручную повыставлять в эмуляторе состояние входов как будто была нажата клавиша. Это разумеется нужно делать перед перед самой проверкой условия.

  1. #define R_channel OCR1AL - а ножка называется OC1A

Это я не ножку переименовал, это переименован регист таймера 1.
Ножки с помощью дефайнов не советую переименовывать.

Про прерывания можно почитать:
Евстифеев. Микроконтроллеры AVR семейств Tiny и Mega фирмы ATMEL
и как мне рекомендовали:
"Применение МК АВР.Схемы, алгоритмы, программы" Н. В. Баранов.