Я изучаю микроконтроллеры во второй раз (я не очень разбираюсь в них, кроме базового программирования на ATMega128) и ищу помощь в школьном проекте. Мне нужно создать проект, в котором:
Я управляю светодиодом (или вентилятором) через ШИМ (через счетчики таймеров и т. Д.) Я создаю волну 1 Гц на выходе микроконтроллера
У меня проблемы с поиском, с чего начать. Кроме того, что мне нужно собрать все на макете (ATMega328p, led / fan и т. Д.), Я понятия не имею, как запустить код, даже если мне нужно написать его на C (так как я приличен в этом).
Я уже вообразил, каким будет код (в моей голове) более или менее. Я знаю, что у меня будет 3 или 4 переключателя для управления моим ШИМзначение (таким образом управляя светодиодом / вентилятором). Я также знаю, что мне нужно читать / возиться с таймерами.
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/io.h>
#define LED 1
volatile unsigned char count = 2; // Counter
volatile unsigned char led; // Verifies if LED is turned ON or OFF
void inic(void) {
PORTD = 0b00000011; // Defined PD0 / PD3 as outputs. PD0: Blinking LED ; PD3: LED (pwm) [OC2B].
DDRD = 0b00000011;
TCCR0A = (1<<WGM01); // COM0Ax: Normal port operation ; COM0Bx: Normal port operation ; Bits 3&2: Reserved and read as zero ; CTC mode (T = [Prescaler/Clock] * (OCR0 + 1)
TCCR0B = (1<<CS02)|(1<<CS00); // FOC0x: Read as zero ; Bits 5&4: Reserved and read as zero ; Prescaler = 1024 & Clock = 1Mhz
TIMSK0 = (1<<OCIE0A); // Timer/Counter0 Compare Match A interrupt enabled
OCR0A = 243; // 0,245 = [1024/1MHz] * (OCR0 + 1) <=> OCR0 = 243 (0,249 ms)
TCCR2A = (1<<COM2B1)|(1<<WGM21)|(1<<WGM20); // COM2Ax: Normal port operation ; COM2Bx: Clear OC2B on Compare Match & Set OC2B at Bottom ; Bits 3&2: Reserved and read as zero ; Fast PWM
TCCR2B = (1<<CS21)|(1<<CS20); // FOC2x: Read as zero ; Bits 5&4; Reserved and read as zero ; Prescaler = 32 & Clock = 1Mhz
OCR2B = 0;
ADMUX = (1<<REFS0)|(1<<ADLAR)|(1<<MUX2)|(1<<MUX0); // External capacitor on AREF pin (potentiometer) ; ADLAR adjusted to the left: Bit = 1 ; Bit 4 ; Reserved and read as zero ; PC5 (ADC5) defined as input
ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2); // ADEN enabled: Bit = 1 ; ADSC set when converting ; ADATE: Disabled auto triggering of the ADC ; ADIF: Set when conversion completes ; Prescaler = 8
sei(); // global int enable
}
ISR(ADC_vect) { // ADC interruption
OCR2B = ADCH; // Transfers the value of the potentiometer to the led on PD3
ADCSRA |= (1<<ADSC); // Starts the conversion
}
ISR(TIMER0_COMPA_vect) { // Led blink interruption
count--; // Counts 250ms
led = (PORTD & LED); // Blinking LED
if (count == 0 && led == 0) { // Count = 2 by default. 250ms * 2 = 500ms. Half a second on, Half a second off. Comes here if led is turned off
PORTD |= LED; // LED ON
count = 2; // Reset counter
}
if (count == 0 && led == 1) { // Comes here if led is turned on
PORTD &= ~LED; // LED OFF
count = 2; // Resets counter
}
}
void main(void) {
inic(); // Calls the inic function
ADCSRA |= (1<<ADSC); // Starts the ADC conversion
while(1){ // infinite cycle
}
}