Шим atmga328
Нужно настроить шим на 30кгц примерно, прочитал тут как можно сделать на arduino. Но фиг знает как конфигурируется порт внутри ардуино иде. Кто знает где найти исходник analogWrite или как сделать шим 30 кгц на atmega328?
- Реклама
тебе прям ровно надо? если нет или ДШ читай и калькулируй или, если самому лень: КодеВижнАВР (например) при создании нового проекта настрой как надо таймер и он тебе выдаст что надо в регистры вписать (уже готовый код, который ардуина должна понять).
если надо точно — ещё придётся или тактовой частотой играть (подбором кварца (или внешнего RC осциллятора)) или настройкой регистра отвечающего за частоту внутреннего генератора — в зависимости от того, чем тактируется контроллер) можно частоту не трогать, а ограничить размер ШИМа (изменить число, при котором будет обнуляться счетчик), но такое изменение придется учитывать при расчетах т.к. 100% заполнения тоже будет при другом значении регистра.
если надо точно — ещё придётся или тактовой частотой играть (подбором кварца (или внешнего RC осциллятора)) или настройкой регистра отвечающего за частоту внутреннего генератора — в зависимости от того, чем тактируется контроллер) можно частоту не трогать, а ограничить размер ШИМа (изменить число, при котором будет обнуляться счетчик), но такое изменение придется учитывать при расчетах т.к. 100% заполнения тоже будет при другом значении регистра.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
datasheet вкурить пытаюсь, но что то туплю
- Сообщения: 208
- Зарегистрирован: Вс дек 10, 2006 19:26:13
Вроде бы так.
Код: Выделить всё
#include <mega328p.h>
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
OCR0A= 125; // Тут задается скважность,можно и не в прерывании
}
void main(void)
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Fast PWM top=0xFF
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
TCCR0A=0x83;
TCCR0B=0x01;
TIMSK0=0x01;
// Global enable interrupts
#asm("sei")
}
- Реклама
Выходную частоту легко посчитать. Например для FAST PWM разделите тактовую частоту контроллера на коэффициент деления предделителя, затем получившиеся разделите на максимальное значение счетчика +1. Это и будет частота ШИМ.
Как вариант в мнемокодах
За счет буфера изменение значений будет в момент BOTTOM, поэтому можно обойтись без прерываний.
Код: Выделить всё
F_CPU=16000000
M=100; число градаций PWM
PB2/OC1B=OUT; выход сигнала
OCR1A=F_CPU/30000-1; период сигнала
OCR1B=N*F_CPU/30000/M-1;N=1...M-1; длительность сигнала
TCCR1A=COM1B1|WGM11|WGM10;
TCCR1B=WGM13|WGM12|CS10; режим FAST PWM 15; F_CPU/1
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
1 - Нужно рассчитывать значения.
a) Рассчитываем время такта МК. 1/F_CPU = t. Пусть частота кварца 16 МГц. Значит один такт выполняется за 0.0000000625.
b) 1/30000 = 0,00003333333 до бесконечности. Берем 33,3 микросекунды.
с) 0,0000333/0.0000000625 = ~ 533 такта. Но, чтобы получить нужную частоту, смена уровней должна быть в два раза выше рассчетного значения. Значит, ~ 267 тактов.
2 - Есть такая программа AVR Calc. Вводишь частоту или времянку, получаешь готовые цифры.

a) Рассчитываем время такта МК. 1/F_CPU = t. Пусть частота кварца 16 МГц. Значит один такт выполняется за 0.0000000625.
b) 1/30000 = 0,00003333333 до бесконечности. Берем 33,3 микросекунды.
с) 0,0000333/0.0000000625 = ~ 533 такта. Но, чтобы получить нужную частоту, смена уровней должна быть в два раза выше рассчетного значения. Значит, ~ 267 тактов.
2 - Есть такая программа AVR Calc. Вводишь частоту или времянку, получаешь готовые цифры.
Последний раз редактировалось Demiurg Пн сен 18, 2017 07:08:03, всего редактировалось 1 раз.
Для режима FPWM (а скорее всего он и нужен ТС, если еще нужен) делить на два не надо. Ну и конечно уж ни как не на разрядность.Demiurg писал(а): F_CPU/делитель таймера/разрядность таймера/2
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
При расчете частоты обязательно учитывается разрядность ШИМ-а. Считайте сами.
Наверное Вы неверно понимаете что такое разрядность. По Вашей формуле для Т0и 2 надо делить на 8, для Т1 на 16.
Добавлено after 59 seconds:
А нужно делить на количество возможных состояний счетчика или на TOP+1.
Добавлено after 59 seconds:
А нужно делить на количество возможных состояний счетчика или на TOP+1.
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Да, внесем поправку, количество возможных состояний счетчика.
[uquote="daaar",url="/forum/viewtopic.php?p=3185043#p3185043"]Нужно настроить шим на 30кгц примерно, прочитал тут как можно сделать на arduino. Но фиг знает как конфигурируется порт внутри ардуино иде. Кто знает где найти исходник analogWrite или как сделать шим 30 кгц на atmega328?[/uquote]
Такие вещи на ардуинках не приветствуются (ибо там таймеры сконфигурированы под системные функции - самостоятельным вмешательством в конфигурацию можно где-нибудь в ином месте прожку "запороть", даже не подозревая про то - попандос может случится в самом неожиданном месте, когда функции измерения времени или чего "штатно" использующее таймера встретятся ).
Надо брать "чистый" АВР (или иное) и писать на ассемблере или на Си.
Как альтернатива - внешний "малолапый" МК собственно с ШИМ (типа ATTiny25/45/85), последовательным интерфейсом и самодельной системой команд для того интерфейса и собственно ардуинка, управляющая тем "переферийным с мозгами" МК согласно того самопального протокола.

Такие вещи на ардуинках не приветствуются (ибо там таймеры сконфигурированы под системные функции - самостоятельным вмешательством в конфигурацию можно где-нибудь в ином месте прожку "запороть", даже не подозревая про то - попандос может случится в самом неожиданном месте, когда функции измерения времени или чего "штатно" использующее таймера встретятся ).
Надо брать "чистый" АВР (или иное) и писать на ассемблере или на Си.
Как альтернатива - внешний "малолапый" МК собственно с ШИМ (типа ATTiny25/45/85), последовательным интерфейсом и самодельной системой команд для того интерфейса и собственно ардуинка, управляющая тем "переферийным с мозгами" МК согласно того самопального протокола.
На ассемблере это будет выглядеть примерно так.daaar писал(а):...как сделать шим 30 кгц на atmega328
Спойлер
Код: Выделить всё
; Генерация PWM частотой 30кГц на ATmega328
;18.09.2017
; PB2 - выход сигнала.
.INCLUDE "m328def.inc"
.equ Fo=16000000
.equ N=25
.equ M=100
;*******************************
.CSEG
GO:
SBI DDRB,2
LDI R22,1<<SE
OUT SMCR,R22 ; режим SLEEP IDLE
LDI XH,HIGH(Fo/30000-1)
LDI XL,LOW(Fo/30000-1)
STS OCR1AH,XH
STS OCR1AL,XL
LDI YH,HIGH(N*Fo/30000/M-1)
LDI YL,LOW(N*Fo/30000/M-1)
STS OCR1BH,YH
STS OCR1BL,YL
LDI R22,1<<COM1B1|1<<WGM11|1<<WGM10
STS TCCR1A,R22 ; режим FAST PWM 15
LDI R22,1<<WGM13|1<<WGM12|1<<CS10
STS TCCR1B,R22 ; режим FAST PWM 15
; SEI
WAIT:
SLEEP
NOP
;опрос органов управления и занесение новых значений
; RJMP GO
.EXIT



