Поможите чем можите.
Писано на CVAVR для Attiny85.
Что оно должно по моему мнению делать:Каждые несколько мс по прерыванию от таймера опрашивать АЦП, далее мажоритарная выборка из 3-х значений. По значению на канале АЦП выдавать сигнал шим, причем шим будет подходить снизу , то есть выдали значение OCR0A , он шимит до следующего прерывания , далее замеряем АЦП , если не хватило то добавляем наполнения, опять ждем до следующего прерывания.
Вот мой первый опыт:
Цитата:
|
/************************************************** ***
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project : Battery
Version : 1.01
Date : 08.03.2010
Author : Alex `
Company : UPZ
Comments:
Chip type : ATtiny85
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 128
************************************************** ***/
#include ‹tiny85.h›
#include ‹MATH.h›
#include ‹stdlib.h›
#include ‹delay.h›
// Timer1 output compare A interrupt service routine
#define ADC_VREF_TYPE 0x60
// Read the 8 most significant bits
// of the AD conversion result
unsigned char 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 ADCH;
}
// Declare your global variables here
unsigned char ADVal1=0;
unsigned char ADVal2=0;
unsigned char ADVal3=0;
unsigned char Y1=0;
unsigned char Y2=0;
unsigned char Y3=0;
int A=0;
void main(void)
{
// Declare your local variables here
// 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=In Func0=Out
// State5=P State4=T State3=T State2=T State1=T State0=0
PORTB=0x20;
DDRB=0x01;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Phase correct PWM top=FFh
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
TCCR0A=0x81;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
// Mode: CTC top=OCR1C
// OC1A output: Disconnected
// OC1B output: Disconnected
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
PLLCSR=0x00;
TCCR1=0x8E;
GTCCR=0x00;
TCNT1=0x00;
OCR1A=0xC4;
OCR1B=0x00;
OCR1C=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AREF pin
// ADC Bipolar Input Mode: Off
// ADC Reverse Input Polarity: Off
// ADC Auto Trigger Source: None
// Only the 8 most significant bits of
// the AD conversion result are used
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
DIDR0&=0x03;
DIDR0|=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;
ADCSRB&=0x5F;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
//мажоритарная выборка
ADVal1=read_adc(0);
delay_us(10);
ADVal2=read_adc(0);
delay_us(10);
ADVal3=read_adc(0);
Y1=abs(ADVal1-ADVal2);
Y2=abs(ADVal1-ADVal3);
Y3=abs(ADVal2-ADVal3);
if(Y1›Y2)
{ A=ADVal1+ADVal3;
if(Y2›Y3){A=ADVal2+ADVal3;}
}
else
{ A=ADVal1+ADVal2;
if(Y1›Y3){A=ADVal2+ADVal3;}
}
A=A/2;
if(A›90){OCR0A=0;}
else{
int STEP=(80-A)/2;
OCR0A=OCR0A+STEP; }
}
|
Теперь вопросы:
1)Взлетит?
2)Изначально прерывание самим код вижном было написано до инициализации ( я там оставил
// Timer1 output compare A interrupt service routine) дак вот из этого места он отказывался работать с ацп и переменными объявленными ниже( что логично). Правильно ли я сделал?
3)Почему протеус ругается на такой код, хотя кодвижн и аврстудия вроде не возмущены.
и еще - есть у кого симуляци для IPS5751 или какого другого Intelligent switch ( в протеусе или альтиуме)? Может кстати посоветуете уж заодно какой-нить на 35В , 10А в импульсе и с быстродействием получше - я его хочу шимом управлять).