====== Примеры программ для микроконтроллеров AVR ======
===== 8 светодиодов =====
Эта программа реализует "бегущий огонь" из 8-ми светодиодов, подключенных к порту "A" микроконтроллера. В данном случае использовался внешний тактовый генератор с частотой ''11.0592 МГц''. Переключаться между использованием внешнего и внутреннего генератора можно при помощи [[microcontrollers|FUSE-битов]].
//#define F_CPU 1000000UL // Тактовая частота 1МГц
#define F_CPU 11059200UL // Тактовая частота 11.0592 МГц
#include
#include
#include
int main() // Главная функция программы
{
DDRA = 0b11111111; // Установка всех ножек порта "A" в режим вывода
//DDRC = 0b11111111; // Установка всех ножек порта "C" в режим вывода
while (1) // Бесконечный цикл
{
PORTA = 0b00000001; // Включение светодиода №1
_delay_ms(500); // Пауза в 500мс
PORTA = 0b00000010; // Включение светодиода №2
_delay_ms(100); // Пауза в 100мс
PORTA = 0b00000100; // И так далее
_delay_ms(100);
PORTA = 0b00001000;
_delay_ms(100);
PORTA = 0b00010000;
_delay_ms(100);
PORTA = 0b00100000;
_delay_ms(100);
PORTA = 0b01000000;
_delay_ms(100);
PORTA = 0b10000000;
_delay_ms(100);
}
}
===== АЦП и 8 светодиодов =====
Эта программа периодически считывает напряжение с АЦП (первая ножка порта "A") и выдаёт уровень, последовательно зажигая линейку из 8-ми светодиодов (ножки порта "C").
#define F_CPU 11059200UL // Тактовая частота 11.0592 MHz
#include
#include
#include
volatile uint16_t adcval; // Значение, считываемое с АЦП
ISR(ADC_vect) // Обработчик прерывания АЦП
{
adcval = ADCW;
}
int main() // Главная функция
{
uint16_t digits = 0;
int i;
// Включаем АЦП и устанавливаем частоту дискретизации = F_CPU / 128
ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADPS2);
sei(); // Разрешаем прерывания
DDRA = 0b00000000; // Устанавливаем все ножки порта "A" на ввод
DDRC = 0b11111111; // станавливаем все ножки порта "C" на вывод
PORTC = 0b00000000;
ADCSRA |= _BV(ADIE); // Разрешаем прерывания АЦП
// Выбираем первую ножку (№0) для считывания напряжения АЦП
ADMUX &= ~_BV(MUX0) & ~_BV(MUX1) & ~_BV(MUX2) & ~_BV(MUX3) & ~_BV(MUX4);
// Выбор внутреннего напряжения 1.22В для считывания АЦП
//ADMUX &= ~_BV(MUX0) ;
//ADMUX |= _BV(MUX1) | _BV(MUX2) | _BV(MUX3) | _BV(MUX4);
ADMUX |= _BV(REFS0) | _BV(REFS1); // Внутреннее опорное напряжение 2.56В
ADCSRA |= _BV(ADATE); // Разрешаем автозапуск
// Выбираем "Free running mode"
SFIOR &= ~_BV(ADTS0) & ~_BV(ADTS1) & ~_BV(ADTS2);
ADCSRA |= _BV(ADSC); // Запуск первого преобразования
while (1) // Бесконечный цикл
{
//ADCSRA |= _BV(ADSC); // Запуск преобразования
// Вычисляем количество светодиодов, которые нужно
// зажечь при данном напряжении
digits = 0b00000000;
for (i=0; i< (adcval+1) / 128; i++)
{
digits = (digits << 1) +1;
}
/*
if (adcval >= 1023) digits = 0b11111111;
else if (adcval >= 895) digits = 0b01111111;
else if (adcval >= 767) digits = 0b00111111;
else if (adcval >= 639) digits = 0b00011111;
else if (adcval >= 511) digits = 0b00001111;
else if (adcval >= 383) digits = 0b00000111;
else if (adcval >= 255) digits = 0b00000011;
else if (adcval >= 127) digits = 0b00000001;
else digits = 0b00000000;
*/
PORTC = digits; // Зажигаем нужные светодиоды
}
}
===== I2C / TWI =====
http://www.nongnu.org/avr-libc/user-manual/group__twi__demo.html