ШИМ на Attiny13 управляемый напряжением или аналоговым сигналом

Дело было вечером — делать было нечего, ай думаю забацаю ШИМ который будет управляться сигналом с АЦП.Для создания сего чуда будем использовать Attiny13 — у меня их куча завалялась. Юзать будем апартный ШИМ. Причём один выход назначим инвертированный, а другой прямой. Ещё подключим кнопку для того чтобы менять частоту таймера ну и тем самым несущую  частоту ШИМ.

Вот такая модель вышла в Proteus

pwm

Принципиальная схема не собиралась в железе, но работать должна — тут собственно схемы той — резисторы и мк и транзистор на выход поставить, к примеру так:

pwm13

Кнопка на схеме, как говорилось выше, используется для изменения несущей частоты.

Пред-делитель  = 1.pwm 1

Пред-делитель  = 2.pwm 2

Пред-делитель  = 3.pwm 3

Пред-делитель  = 4.pwm 4

Пред-делитель  = 5.pwm 5

Применений много — от регулятора мощности до регулятора света или напряжения.

Исходный код программы:

#include <tiny13.h>
#include <delay.h>
#define ADC_VREF_TYPE 0x00
  unsigned int pwm = 0;
  float pwm_f=0;
  unsigned char pwm_val = 0;   
  eeprom unsigned char trc[2];
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out 
// State5=T State4=T State3=T State2=T State1=0 State0=0 
PORTB=0x00;
DDRB=0x03;
PORTB.4=1;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Phase correct PWM top=0xFF
// OC0B output: Non-Inverted PWM
// OC0A output: инвертрованое значение
TCCR0A=0xB1;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;

// ADC initialization
// ADC Clock frequency: 76,563 kHz
// ADC Bandgap Voltage Reference: Off
// ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
DIDR0&=0x03;
DIDR0|=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x87;
 if(PINB.4==0){delay_ms(10);while(!PINB.4){;}; TCCR0B=3; trc[0] = 0;} //если зажали кнопку при включении
 //то сбрасываем сохранения 
 if(trc[0]==1){TCCR0B = trc[1];} //проверяем сохранённое значение
 else{trc[1]=3; TCCR0B = trc[1];} //востанавливаем
while (1)
 { 
 pwm = (int)read_adc(1); //считываем значение АЦП
 pwm_f =(int) pwm/4; //делим его на 4 и берём только целую часть
 pwm_val=(char)pwm_f; //преобразование типов
 OCR0A = (char) pwm_val; //записываем значение в регистр А
 OCR0B = (char) pwm_val; //записываем значение в регистр В
 delay_ms(1);
 
 if(PINB.4==0){delay_ms(10);while(!PINB.4){;}; TCCR0B++; trc[1] = TCCR0B; trc[0]=1;} //изменяем частоту ШИМ
 if(TCCR0B>=6){TCCR0B=1;}
 }
}

07.04.17 FUSE


Скачать проект ШИМ на Attiny13 управляемый напряжением или аналоговым сигналом Скачали 3000 раз

ШИМ на Attiny13 управляемый напряжением или аналоговым сигналом: 45 комментариев

  1. Добрый день.
    Подcкажите , как сделать так чтобы шим работал только, когда напряжение на аналоговом входе меняется от 2,97 до 4,18 вольт, при меньшем чем 2,97 вольт низкий логический уровень на выходе, при напряжении более 4,18 вольт высокий уровень. Сам только начинаю изучать программирование, самостоятельно не могу разобраться.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *