51

Re: PWM 0-25V 3A

Вот скетч, убрал защиту, в монитор порта вывел состояние регистра OCR1A


// 0-25V 3A
#define KALL_U 7.405

#define CLK  PB4 // TM1637 D11
#define DIO  PB3 // TM1637 D12

#include <EEPROM.h>

float u,u_iz;
int reg;
bool w=1,w1,out=0;
unsigned long times;

void setup(){
 // u = float(EEPROM.read(0))/10.0;
 u=10.0;
  Serial.begin(9600);
  // TIMER_1 D9 OUTPUT
  DDRB |= (1 << PB1)|(1<<PB5); // D9 output pwm | D13 led error 
  DDRD |= (1<<PD2); //  D2 RELE
  PORTD |= (1<<PD3)|(1<<PD4)|(1<<PD5);
  PORTB |= (1<<PB1); 
  
   noInterrupts();
  TCCR1A = 0;TCCR1B = 0;
  TCCR1A |= (1 << COM1A1) | (1 << COM1A0) | (1 << WGM11);
  TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
  TCKCSR = 1 << F2XEN | 1 << TC2XS1;
  ICR1 = 5000;
  OCR1A =0;
  interrupts();
  ADMUX = 0b000;
  ADCSRD |= 1 << REFS2;
  ADCSRA |= 1 << ADEN | 1 << ADSC | 1 << ADATE | 0b111;
  delay(300);
  PORTD &=~ (1 << PD2);
  }

void loop(){ 
  if(((PIND >> PD3) & 1) == 0){u+=0.1;if(u>25){u=25;}w=1;w1=1;times=millis();delay(100);}
  if(((PIND >> PD4) & 1) == 0){u-=0.1;if(u<0){u=0;}w=1;w1=1;times=millis();delay(100);}
  if(((PIND >> PD5) & 1) == 0 && out==0){out=1;w=1;delay(300);}
  if(((PIND >> PD5) & 1) == 0 && out==1){out=0;w=1;delay(300);}
  
  while((ADCSRA & (1 << ADIF)) == 0);
   int u_data = (ADCL|ADCH << 8);
   u_iz = float(u_data)/1000.0*KALL_U;
  if(u_iz-u>5){reg-=100;}
  if(u-u_iz>1){reg+=10;} 
  if(u_iz-u>1){reg-=10;}
  if(u_iz<u){reg++;}
  if(u_iz>u){reg--;}
  if(reg<0){reg=0;}
  //if(reg>4900 && out==1){reg=0;OCR1A=0;PORTB|=(1<<PB5);out=0;w=1;delay(3000);}
  PORTB&=~(1<<PB5);
  if(out==0){reg=0;} OCR1A = reg;
  Serial.println(OCR1A);
  if(w==1){w=0;tm_print(u*10,1,5);}
  if(millis()-times>5000 && w1==1){EEPROM.update(0,u*10);w1=0;}
  }

void tm_dec(byte dig){
       for(byte i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void tm_print(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);
        tm_dec(0x40);tm_stop();tm_start();
        int data0 = t / 1000 % 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: if(out==1){data = 12;}else{data=10;};break;
        case 1: if(u<10){data=10;}else{data = data1;}break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        case 12: data = 0b00111110;break;     // U
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
void del(){delayMicroseconds(100);} 

52

Re: PWM 0-25V 3A

изменил в основном коде следующее:
DDRB |= (1 << PB1); // изменил-убрал РВ5
...
ICR1 = 5000;
OCR1A = 280;
...
// if(reg>4900 && out==1){reg=0;OCR1A=0;PORTB|=(1<<PB5);out=0;w=1;delay(3000);}
//PORTB&=~(1<<PB5);
сейчас включается и через некоторое время стабилизируется и держит стабильно выходное напряжение 5,00 В
на дисплее почему-то 222 и на кнопки не реагирует.
Разбираюсь дальше...

53

Re: PWM 0-25V 3A

Хочу поблагодарить автора за предоставленный материал и оказанную помощь.
После танца с бубном, как-то со скрипом, устройство стало запускаться само по себе.
Не понятно в чём была причина. В итоге схема и софт заработало как в описании.
Код без изменений, кроме #define KALL_U 7.405 подогнал под свой мультиметр.
Изначально грешил на немаркированный МК, но похоже он работает нормально.
Думаю, его можно широко использовать в качестве замены ATmega328.

При подключении, на ходу более мощной лампы вышел из строя КТ827В.
Вижу в другой ветке NEW_DIGITAL_POWER есть продолжение этой темы.
Позже перейду туда. Буду пробовать другие ключи...

54

Re: PWM 0-25V 3A

При подключении, на ходу более мощной лампы вышел из строя КТ827В.

if(reg>4900 && out==1){reg=0;OCR1A=0;PORTB|=(1<<PB5);out=0;w=1;delay(3000);}

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

55

Re: PWM 0-25V 3A

Хорошо буду иметь в виду.