From c4c8c8c131c97233a65ca51346576e59ec137b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BB=D0=B0=D1=81=D1=81?= Date: Tue, 11 Apr 2023 15:02:16 +0300 Subject: [PATCH] update info, pwm --- info.txt | 37 ++++++++++++++++++++++++++++++++----- program PWM.c | 26 ++++++++++++++++---------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/info.txt b/info.txt index 4197acc..25710c6 100644 --- a/info.txt +++ b/info.txt @@ -2,21 +2,48 @@ 1 блок - опрашивание (пришла ли команда) 2 блок - TWI (I2C) 3 блок - работа с ШИМ (ВКЛ, частота, скважность) - 8-bit T/C0 - Самый низкий уровень - блок 2-wire и блок 8-bit timer - шим таймер: изначальные регистры инициализация до куда считать и когда сбрасывать компаратор + +Ширина импульса (скважность) изменяется в зависимости от значения, записанного в регистры сравнения OCR1A. +Когда значение в счетчике достигает значения регистра сравнения, то соответствующий ему вывод OC1A сбрасывается в ноль. +Используем Таймер 1 (16 bit Timer/Counter 1): +Конфигурируем регистр управления таймера – TCCR1A +COM1A1, COM1A0 – 0 0 – PWM отключен, нормальная работа порта +COM1A1, COM1A0 – 1 0 – Сброс OC1A при совпадении +Включить/выключить ШИМ: конфигурация портов +WGM13, WGM12, WGM11, WGM10 – 1 1 1 1 – Режим FAST PWM, TOP – OCR1A, Update of OCR0A – BOTTOM, TOV Flag set on – TOP. +Установить частоту (12 бит целое, 4 дробная часть): +4095,31 – максимальное число, 0,0625 – минимальное число +Частота = Частота_мк / (Предделитель * OCR1A) +Чем больше значение в OCR1A тем меньше частота +Значение OCR1A и OCR1B должно быть в пределах от 0 до 100 +Частота приходит от Master +CS12, CS11, CS10 – 1 0 1 – Устанавливаем предделитель 1024 +OCR1A = 16000000UL / 1024 / Частота +Конфигурируем регистр управления таймера - TCCR1B +Установить скважность (от 0 до 100%) +Скважность приходит от Master (в %) +OCR1B = OCR1A * Скважность / 100 -i2c -16000000UL +ДОБАВИТЬ: +tempTCCR1A, tempTCCR1B - присваивать TCCR1A и TCCR1B +скважность посчитать через доп переменную +freq целая и freq дробь это разные переменные приходящие от master Информация: +pwm https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf https://robotclass.ru/tutorials/pwm/ https://3d-diy.ru/wiki/arduino-moduli/interfeys-peredachi-dannykh-i2c/ https://smartep.ru/index.php?page=avr_c_examples#p12 http://microsin.net/programming/avr/example-using-the-twi-i2c.html -https://forum.amperka.ru/threads/%D0%B0%D0%BF%D0%BF%D0%B0%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-i2c-%D0%B2-atmega328p.18806/ \ No newline at end of file +https://forum.amperka.ru/threads/%D0%B0%D0%BF%D0%BF%D0%B0%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-i2c-%D0%B2-atmega328p.18806/ +ATmega328 - Таймеры и настройка ШИМ |AlNotes| +I2c +https://docs.arduino.cc/learn/communication/wire +https://embedjournal.com/two-wire-interface-i2c-protocol-in-a-nut-shell/ +https://wiki.bas-ip.com/2wire/ru/podklyuchenie-2752639.html diff --git a/program PWM.c b/program PWM.c index 663f8bd..d8814d4 100644 --- a/program PWM.c +++ b/program PWM.c @@ -4,29 +4,35 @@ #include -void timer1_init(int frequency, int dutycycle){ +void timer1_init(int intfrequency,int fracfrequency,int dutycycle){ DDRD |= (1 << PORTD6); //OC1A (12) DDRD |= (1 << PORTD5); //OC1B (11) + //Частота + int frequency = intfrequency + fracfrequency / 10000; + OCR1A = F_CPU / 1024 / frequency; + + //Скважность + uint8_t tempOCR1B = OCR1A * dutycycle / 100; + OCR1B = tempOCR1B; + TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; // Не инверсный режим работы и OC0B - TCCR1A |= (1 << COM1A1) | (0 << COM1A0); + uint8_t tempTCCR1A |= (1 << COM1A1) | (0 << COM1A0); //Fast PWM (Быстрый ШИМ) - TCCR1A |= (1 << WGM11) | (1 << WGM10); - TCCR1B |= (1 << WGM13) | (1 << WGM12); + tempTCCR1A |= (1 << WGM11) | (1 << WGM10); + uint8_t tempTCCR1B |= (1 << WGM13) | (1 << WGM12); //Предделитель - 1024 - TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10); + tempTCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10); - //Частота = Частота_мк / (Предделитель * OCR1A) - OCR1A = F_CPU / 1024 / frequency; - - //Скважность - OCR1B = OCR1A * dutycycle / 100; + //Присваивание регистров + TCCR1A = tempTCCR1A; + TCCR1B = tempTCCR1B; } int main(void){