хочу девушке подарочек сварганить
Ёмае, у вас там брачный сезон, что ли?

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

Так что продолжу отвечать на ваши вопросы.
Как оказалось, не совсем на любом
Ясное дело, в пределах разумного. Если пин уже сконфигурирован под сервисную функцию, то его, понятное дело, одновременно для двух разных задач использовать не получится. Впрочем, как видно, если сильно хочется, даже RESET можно сделать обычным пином. Но делать этого не стоит, иначе прошивать надо будет только параллельным программатором.
Просто мне аж не верится, что я смогу полноценно использовать все ноги контроллера для ШИМ
Для
программного ШИМ, написанного руками. Чего не верится-то? Написать можно все, что угодно. И программный ШИМ в том числе. Но программный ШИМ - это не фунт изюму, тем более на столько ножек - частота будет малой, загрузка проца большой. Хотя для вашего применения это неважно. Будет герц 100 - и уже хорошо.
Если я не использую внутрисхемное программирование, смогу ли я использовать для ШИМ еще и РВ2 - РВ5 порты?
Извините, но с этим вопросом давайте все же к даташиту. Насколько они там зарезервированы - надо смотреть. Обычно ничто не мешает в рабочем режиме использовать ножки ISP как обычные пины.
Смогу ли я подключить кнопку к портам отличным от PCx, например, к PDx ... ?
Этому ничто не мешает.
Смогу ли я использовать для ШИМ порты PCx ... ?
Для
программного (!!!) ШИМ доступна любая ножка, к которой можно обратиться. Т.е., разумеется, кроме сервисных.
Можно ли сконфигурировать ATMEGA8A на работу 16 MHz (то есть, максимальную) без применения внешнего кварца?
Нет.
И последний вопрос, будет ли ATMEGA8A при 16 МГц, работать от 2,7 вольт? Судя по даташиту вроде должен, но так ли это на самом деле?
На этот вопрос уже ответили выше, зависит от частоты.
Понимаю, вопросов куча, но хочу заполнить дырки в своих знаниях восьмой меги.
Лучше найдите кого-то рядом, кто за мзду малую разработает электронику за вас. Как сделал упомянутный мной товарищ.
UPD.
Телепатически я вижу, что следующая пачка вопросов будет про то, как же реализовать программный ШИМ. Короче вот, держите реализацию программного ШИМ на все доступные ноги (20 шт., кроме RESET и XTAL1/XTAL2) для ATmega8. Код для AVR-GCC (WinAVR + AVR Studio). Предполагаемое тактирование - 8 МГц.
Неиспользованные выводы XTAL1/2 тоже в принципе можно использовать, но вдруг вы все же захотите внешний кварц?
Массив pwm_values - значения ШИМ для каждой ножки, от 0 до 255; pwm_pins - собственно битовые маски ножек; pwm_ports - соответствие масок ножек и портов.
Вызываем softPWM_Init(), разрешаем прерывания, а дальше просто пишем в pwm_values[] по нужному номеру ножки желаемое значение ШИМ на ней.
Спойлер
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#define PWM_PIN_COUNT 20
//PWM values for every pin
volatile uint8_t pwm_values[PWM_PIN_COUNT];
//PWM pin/port look-up table
uint8_t pwm_pins[PWM_PIN_COUNT] PROGMEM = {
_BV(PD0),_BV(PD1),_BV(PD2),_BV(PD3),_BV(PD4),
_BV(PD5),_BV(PD6),_BV(PD7),_BV(PB0),
_BV(PB1),_BV(PB2),_BV(PB3),_BV(PB4),_BV(PB5),
_BV(PC0),_BV(PC1),_BV(PC2),_BV(PC3),_BV(PC4),_BV(PC5)
};
#define PWM_PD 1
#define PWM_PB 2
#define PWM_PC 3
uint8_t pwm_ports[PWM_PIN_COUNT] PROGMEM = {
PWM_PD,PWM_PD,PWM_PD,PWM_PD,PWM_PD,
PWM_PD,PWM_PD,PWM_PD,PWM_PB,
PWM_PB,PWM_PB,PWM_PB,PWM_PB,PWM_PB,
PWM_PC,PWM_PC,PWM_PC,PWM_PC,PWM_PC,PWM_PC
};
ISR (TIMER0_OVF_vect)
{
static uint8_t pwm_counter=0;
uint8_t k;
if (!pwm_counter)
{
for (k=0; k<PWM_PIN_COUNT; k++)
{
switch (pgm_read_byte(&(pwm_ports[k])))
{
case PWM_PB:
PORTB|=pgm_read_byte(&(pwm_pins[k]));
break;
case PWM_PC:
PORTC|=pgm_read_byte(&(pwm_pins[k]));
break;
case PWM_PD:
PORTD|=pgm_read_byte(&(pwm_pins[k]));
break;
default:
break;
}
}
}
for (k=0; k<PWM_PIN_COUNT; k++)
{
if (pwm_counter>pwm_values[k])
{
switch (pgm_read_byte(&(pwm_ports[k])))
{
case PWM_PB:
PORTB&=~pgm_read_byte(&(pwm_pins[k]));
break;
case PWM_PC:
PORTC&=~pgm_read_byte(&(pwm_pins[k]));
break;
case PWM_PD:
PORTD&=~pgm_read_byte(&(pwm_pins[k]));
break;
default:
break;
}
}
}
pwm_counter++;
}
void softPWM_Init(void)
{
//Enable timer 0 overflow interrupt
TIMSK=_BV(TOIE0);
//Initialize and start timer 0
TCNT0=0;
TCCR0=_BV(CS00);
//All available ports are outputs
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
}
void main(void)
{
uint8_t i;
for (i=0; i<PWM_PIN_COUNT; i++)
{
pwm_values[i]=i*10;
}
softPWM_Init();
sei();
while (1);
}
Протестил в Proteus (кликабельно):

Разница между теорией и практикой на практике гораздо больше, чем в теории.