Добавил:
I want to die Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лр4 / Текст программы пункт 2

.docx
Скачиваний:
0
Добавлен:
07.06.2023
Размер:
20.95 Кб
Скачать

/*

* GccApplication2.cpp

*

* Created: 20.04.2023 14:42:21

* Author : BTS-5662-1

*/

#include <avr/io.h>

#include <avr/interrupt.h>

#define F_CPU 8000000

#define IRQs_FOR_DUTY_CHANGE 20

uint8_t irq_counter = 0; // Counter of IRQs for changing PWM duty

int main(void)

{

CCP = 0xD8; // можем редактировать CLKMSR, CLKPSR, WDTCSR

CLKPSR = 0x00; // предделитель ядра 1

DDRA|=(1<<DDRA5);

// Настройка работы АЦП

ADCSRA=(1 << ADEN)|(1 << ADPS2)|(1 << ADIE); // разрешение использования АЦП, делитель АЦП 1:16, разрешение прерывания по завершению цикла преобразования

ADMUX=(1 << MUX1)|(1 << MUX0)|(0 << REFS1)|(0 << REFS0); // текущий канал АЦП PA[6], ИОН - напряжение питания

ADCSRB|=(1 << ADLAR);// выравнивание по левому краю

// Настройка работы таймера

TCCR0A|=(1 << COM0B1)|(1 << COM0B0)|(1 << WGM00); // инверсный ШИМ сброс при обнулении, установка при совпадении

TCCR0B|=(1 << CS01) |(1 << CS00); // предделитель таймера 64

TIMSK0|=(1 << TOIE0);

GTCCR = (1 << REMAP);

//ICR0=1023; // TOP, чтоб f=122 Гц, (8*10^6)/(64*1*(1+1023))=122

//TIMSK0|=(1<<TOIE0); // разрешение прерывания по переполнению таймера

sei(); // глобальное разрешение прерываний

while(1)

{

// Вся работа идет в прерываниях

}

}

//Обработчик прерывания по переполнению таймера

ISR(TIM0_OVF_vect)

{

irq_counter++;

// Раз в 20 прерываний запускаем единичное АЦП-преобразование

if (irq_counter == IRQs_FOR_DUTY_CHANGE)

{

irq_counter = 0; // Reset the counter

ADCSRA|=(1 << ADSC); // единичное АЦП-преобразование

}

}

//Обработчик прерывания по завершению АЦП преобразования

ISR(ADC_vect)

{

OCR0B = ADCH; // считываем значения с обоих регистров

}

2я прога:

#include <avr/io.h>

#include <avr/interrupt.h>

#define F_CPU 8000000

#define USART_BAUDRATE 9600 // скорость передачи данных

#define BAUD_PRESCALE ((F_CPU / (USART_BAUDRATE * 16))-1)

#define ADC_FS 5

int main(void)

{

CCP = 0xD8; // можем редактировать CLKMSR, CLKPSR, WDTCSR

CLKPSR = 0x00; // предделитель ядра 1

// Настройка режима работы UART

UCSRC|=(1 << UCSZ1)|(1 << UCSZ0)|(1 << USBS); // 8-битная посылка, 1 стоп-бит

//UCSRC|=(0 << UPM1)|(0 << UPM0) по умолчанию и так нули - без проверки на четность

UBRRH=(BAUD_PRESCALE >> 8); // скорость передачи данных - запихиваем BAUD_PRESCALE

UBRRL=BAUD_PRESCALE;

UCSRB|=(1 << TXEN)|(1 << RXEN); // разрешение передачи данных, разрешение приема данных

// Настройка работы АЦП

ADCSRA|=(1 << ADEN)|(1 << ADPS2)|(1 << ADIE); // разрешение использования АЦП, делитель АЦП 1:16, разрешение прерывания по завершению цикла преобразования

ADMUX|=(1 << MUX1)|(1 << MUX0)|(0 << REFS1)|(0 << REFS0); // текущий канал АЦП PA[6], ИОН - напряжение питания

ADCSRA|=(1 << ADATE);// выравнивание по левому краю => автозапуск АЦП-преобразования, тк в ADTS[2:0] - 000

ADCSRB|=(1 << ADLAR);// выравнивание по левому краю (нам нужен ADCH)

// Настройка работы таймера

TCCR0B|= (1 << WGM02)|(1 << CS02); // режим СТС, предделитель таймера 256

TCCR0A|= (1 << COM0A0); // переключение при совпадении

OCR0A=(F_CPU/(2*ADC_FS*256)-1); // TOP, f=5 Гц, ADC_FS=(F_CPU)/(2*256*1*(1+TOP))

TIMSK0|=(1<<OCIE0A); // разрешение прерывания по совпадению

sei(); // глобальное разрешение прерываний

while(1)

{

// Вся работа идет в прерываниях

}

}

//Обработчик прерывания по завершению АЦП преобразования

ISR(ADC_vect)

{

uint16_t analogReading = ADCL | (ADCH << 8); // Сохраняем результат в переменной analogReading (всё!)

UDR = (analogReading >> 8); // Посылаем только старшие биты по UART

//while (!(UCSRA & (1 << UDRE))) {}

}

Соседние файлы в папке лр4