Эта программа реализует “бегущий огонь” из 8-ми светодиодов, подключенных к порту “A” микроконтроллера. В данном случае использовался внешний тактовый генератор с частотой 11.0592 МГц
. Переключаться между использованием внешнего и внутреннего генератора можно при помощи FUSE-битов.
//#define F_CPU 1000000UL // Тактовая частота 1МГц #define F_CPU 11059200UL // Тактовая частота 11.0592 МГц #include <inttypes.h> #include <avr/io.h> #include <util/delay.h> 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); } }
Эта программа периодически считывает напряжение с АЦП (первая ножка порта “A”) и выдаёт уровень, последовательно зажигая линейку из 8-ми светодиодов (ножки порта “C”).
#define F_CPU 11059200UL // Тактовая частота 11.0592 MHz #include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> 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; // Зажигаем нужные светодиоды } }