Atmeg32+czujnik przyspieszenia+PWM
Atmeg32+czujnik przyspieszenia+PWM
Witam.
Mam takie pytanie:)
Algorytm:
odczyt z czujnika ---> porownanie z wartościa w tablicy ---> wystawienie odpowiedniego sygnału PWM
Ze wzgledu na to ze jestem poczatkujący w programowaniu, ale nie oporny na wiedze , dlatego tez czy ktoś moglby wrzucic kawalek jakiegos programu w C ktory realizowalby powyzszy schemat i pomoglby mi zrozumiec jak zastosować przerwania, tablice itd ?.
Poczatkowo ustawilem juz przetworniki ADC do ktorych podpiete sa czujniki i wlaczylem przerwania od timera1 gdyz go bede wykorzystywal do PWM.
Pozdrawiam
Mam takie pytanie:)
Algorytm:
odczyt z czujnika ---> porownanie z wartościa w tablicy ---> wystawienie odpowiedniego sygnału PWM
Ze wzgledu na to ze jestem poczatkujący w programowaniu, ale nie oporny na wiedze , dlatego tez czy ktoś moglby wrzucic kawalek jakiegos programu w C ktory realizowalby powyzszy schemat i pomoglby mi zrozumiec jak zastosować przerwania, tablice itd ?.
Poczatkowo ustawilem juz przetworniki ADC do ktorych podpiete sa czujniki i wlaczylem przerwania od timera1 gdyz go bede wykorzystywal do PWM.
Pozdrawiam
-
keruseykaryu
To nie bascom, że to można załatwić dwoma albo trzema instrukcjami. Nic nie wiemy co i jak masz popodłączane. Albo jak to chcesz mieć.odczyt z czujnika ---> porownanie z wartościa w tablicy ---> wystawienie odpowiedniego sygnału PWM
Ze wzgledu na to ze jestem poczatkujący w programowaniu, ale nie oporny na wiedze , dlatego tez czy ktoś moglby wrzucic kawalek jakiegos programu w C ktory realizowalby powyzszy schemat i pomoglby mi zrozumiec jak zastosować przerwania, tablice itd ?.
Mogę napisać
Kod: Zaznacz cały
OCR1A = search_table(PWMTABLE, read_g_detector(REAR_DETECTOR));
Po co ci przerwania z PWMa? Obejdzie się bez.Poczatkowo ustawilem juz przetworniki ADC do ktorych podpiete sa czujniki i wlaczylem przerwania od timera1 gdyz go bede wykorzystywal do PWM.
A wiec teraz dokladniej:
Podlączenia:
PWM PORTD 4,5
Czujnik PORTA 0,1,2
Beda dwie tablice:
Tablica1
Tablica2
Bede upuszczać pewien obiekt z wysokosci do 0,5m, w tym czasie wartość z czujnika bedzie calkowana aby uzyskac predkość i wartość ta bedzie porownywana z tablicy1 I 2. Gdy odczyty bedzie sie zawieral w tablicy1 ma nie wystepowac sygnał PWM, a gdy w tablicy2 sygnał PWM ma sie pojawic. Sygnał PWM zostaje podawanay na tr MOSFET i tak jest generowany aby wytworzyc prąd wartości od 1 - 5 A
Pozdrawiam
Podlączenia:
PWM PORTD 4,5
Czujnik PORTA 0,1,2
Beda dwie tablice:
Tablica1
Tablica2
Bede upuszczać pewien obiekt z wysokosci do 0,5m, w tym czasie wartość z czujnika bedzie calkowana aby uzyskac predkość i wartość ta bedzie porownywana z tablicy1 I 2. Gdy odczyty bedzie sie zawieral w tablicy1 ma nie wystepowac sygnał PWM, a gdy w tablicy2 sygnał PWM ma sie pojawic. Sygnał PWM zostaje podawanay na tr MOSFET i tak jest generowany aby wytworzyc prąd wartości od 1 - 5 A
Pozdrawiam
czujnik trzyosiowy, jest wykorzystywany podczas tlumienia upadku a dokladniej:
zamontowany jest na stopie robota wraz z elektromagnesami i ciecza magnetoreologiczna. W trakcie upadku wczytuje wattrosci i odpowiednio zamienia je na sygnal PWM, ktory nastepnie wysylany jest do elektromagnesów tworząc odpowienie pola magnetyczne dla Cieczy MR. Jest to moja praca do obrony mam juz calość tylko opowiednio zaprogramowac UK w C dlatego tyle pytan odnosnie wytlumaczenia mi od czego rozpoczac pisanie, dodam ze wyswietlacz LCD, petle opoznien, przyciski sa juz gotowe.
Czujnik MMA734..
zamontowany jest na stopie robota wraz z elektromagnesami i ciecza magnetoreologiczna. W trakcie upadku wczytuje wattrosci i odpowiednio zamienia je na sygnal PWM, ktory nastepnie wysylany jest do elektromagnesów tworząc odpowienie pola magnetyczne dla Cieczy MR. Jest to moja praca do obrony mam juz calość tylko opowiednio zaprogramowac UK w C dlatego tyle pytan odnosnie wytlumaczenia mi od czego rozpoczac pisanie, dodam ze wyswietlacz LCD, petle opoznien, przyciski sa juz gotowe.
Czujnik MMA734..
Zamieszczam skrypt tego co do chwili obecnej zrobilem. Prosze o spraqwdzenie poprawnosci napiisania przerwania dla ADC.
Kod: Zaznacz cały
//#define F_CPU 16000000
#include "hd.h"
#include<avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#define przycisk PINC
#define ELEKTROMAGNES PORTD
#define ELM1 4
#define ELM2 5
#define set_ELM1 ELEKTROMAGNES |= _BV(ELM1) //wymusza stan niski
#define clr_ELM1 ELEKTROMAGNES &= ~_BV(ELM1) //wymusza stan wysoki
#define toggle_ELM1 ELEKTROMAGNES ^= _BV(ELM1)
#define set_ELM2 ELEKTROMAGNES |= _BV(ELM2) //wymusza stan niski
#define clr_ELM2 ELEKTROMAGNES &= ~_BV(ELM2) //wymusza stan wysoki
#define toggle_ELM2 ELEKTROMAGNES ^= _BV(ELM2)
#define probki 128
#define nieczulosc 3
signed int vh1,vh2,vh3,vh4,vh5,vh6,vh7,vh8,vh9,v10,v9,v8,v7,v6,adcz1,ADCval,a1,v;
unsigned char czujnik,wypelnienie1,wypelnienie2,adcz,licznik;
ISR(ADC_vect)// przerwanie dla przetwornika
{
adcz+=ADC;// odczytana wartość dodawana jest do adcz
licznik++;
ADCSRA |= (1<<ADSC);
if(licznik=probki)// wynik 128 probek
{
licznik=0;
ADCval=adcz; //uaktualnienie zamiennej ADCval ( ona bedzie calkowana);
if(ADCval>nieczulosc|ADCval<-nieczulosc)
{
v=v+((ADCval+ADCval)>>1);
}// calkowanie
adcz=0;
}
}
ISR(TIMER1_OVF_vect)
{
set_ELM1;
set_ELM2;
sei();
}
void ADC_init()
{
ADMUX=(1<<ADLAR)|(1<<MUX0);//0x21;//wyrownanie do lewej, zew vref, ADC1
ADCSRA=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//0x9F; // prescaler 128,wlaczenie ADC, przerwania
}
void PWM_init()
{
TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);
}
int wait(void)// funkcja opozniajaca
{
int i;
for(i=0;i<50;i++)
{
_delay_ms(50);
asm volatile ("nop");
}
}
int kalibracja(void)
{
lcd_puts("...");
wait();
LCD_CLEAR;
}
int main(void)
{
sei();
DDRA=0x00;
DDRB=0xFF;
DDRC=0xFC;
DDRD=0xFF;
PORTA=0x00;
PORTB=0x00;
PORTC=0x03;
PORTD=0x00;
double P_U[9];
P_U[0]=3.13;
P_U[1]=2.97;
P_U[2]=2.80;
P_U[3]=2.62;
P_U[4]=2.43;
P_U[5]=2.21;
P_U[6]=1.98;
P_U[7]=1.72;
P_U[8]=1.40;
char Po_U[5];
_delay_ms(10);
lcd_init();//inicjalizacja wyświetlacza
ADC_init();
TIMSK=(1<<TOIE1);
ADCSRA=(1<<ADSC);
LCD_DISPLAY(LCDDISPLAY);//wlaczenie LCD
lcd_puts("K");//wpisanie ciagu znaków
_delay_ms(10);//opoznienie
lcd_puts("W");
_delay_ms(10);
LCD_LOCATE(0,1);
_delay_ms(10);
lcd_puts("Politechnika Sl.");
wait();
LCD_CLEAR;
lcd_puts(" Praca mgr inz.");
wait();
LCD_CLEAR;
lcd_puts("Temat:");
_delay_ms(10);
lcd_puts(" UKLAD DO");
_delay_ms(10);
LCD_LOCATE(0,1);
lcd_puts("TLUMIENIA UPADKU");
wait();
LCD_CLEAR;
while(1)
{
LCD_LOCATE(2,0);
lcd_puts("Wybierz tryb");
_delay_ms(10);
LCD_LOCATE(4,1);
lcd_puts(" pracy:");
_delay_ms(10);
wait();
LCD_CLEAR;
lcd_puts("1:Normalny");
_delay_ms(10);
LCD_LOCATE(0,1);
lcd_puts("2:Awaryjny");
while(1)
{
if(!(przycisk & 0x01)) /* Jeśli pierwszy przycisk wciśnięty */
{
_delay_ms(80);/* Czas na wygaśnięcie drgań styków przycisku*/
while(!(przycisk & 0x01)) {}/* Oczekuje na zwolnienie przycisku*/
_delay_ms(80);/* Czas na wygaśnięcie drgań styków przycisku*/
LCD_CLEAR;
lcd_puts(" Tryb awaryjny:");
wait();
LCD_CLEAR;
LCD_LOCATE(3,0);
lcd_puts("Kalibracja");
_delay_ms(10);
LCD_LOCATE(4,1);
lcd_puts("Czujnika");
wait();
LCD_CLEAR;
lcd_puts("Prosze czekac...");
wait();
wait();
wait();
wait();
kalibracja();
LCD_CLEAR;
LCD_LOCATE(3,0);
lcd_puts("Kalibracja");
LCD_LOCATE(3,1);
lcd_puts("zakonczona");
wait();
LCD_CLEAR;
kalibracja();
break;
}
if(!(przycisk & 0x02))/* Jeśli drugi przycisk wciśnięty */
{
_delay_ms(80);
while(!(przycisk & 0x02)) {}
_delay_ms(80);
LCD_CLEAR;
LCD_LOCATE(3,0);
lcd_puts("Zakonczenie");
_delay_ms(10);
LCD_LOCATE(2,1);
lcd_puts("pracy ukladu");
wait();
wait();
LCD_CLEAR;
break;
}
}
}
}
Czy cos takiego ma mozliwość działania?
Kod: Zaznacz cały
ISR(ADC_vect)// przerwanie dla przetwornika
{
adc_mux=0x0F & ADMUX;
adcz=ADCH;// odczytana z przetwornika ADC
ADMUX++;
ADCSRA |= (1<<ADSC);
adcz1=adcz-a0;
a1=a1+adcz1;
if((adcz1<nieczulosc)&(adcz1>-nieczulosc)) //gdy wynik sumowania jest poniżej progu nieczułości
{mov++;}
else {mov=0;}
if(mov>25){v=0;}
licznik++;
if(licznik>32) //uśrednij wynik pomiaru z 32 próbek
{ licznik=0;
a1=(a1>>5);
if(a1>nieczulosc|a1<-nieczulosc){v=v+((a1+a0p)>>1);} //całkowanie metodą trapezową
a0p=a0;
a0=0;
}
}
ISR(TIMER1_OVF_vect)
{
set_ELM1;
set_ELM2;
sei();
if((v<=vh1)&(vh2<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh2)&(vh3<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh4)&(vh5<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh5)&(vh6<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh6)&(vh7<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh7)&(vh8<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=vh8)&(vh9<v)){ OCR1AL=0;OCR1BL=0;}
if((v<=v1)&(v2<v)){ OCR1AL=64;OCR1BL=64;}
if((v<=v2)&(v3<v)){ OCR1AL=128;OCR1BL=128;}
if((v<=v3)&(v4<v)){ OCR1AL=192;OCR1BL=192;}
if((v<=v4)&(v5<=v)){ OCR1AL=255;OCR1BL=255;}
}
void ADC_init()
{
ADMUX=(1<<ADLAR)|(1<<MUX0);//0x21;//wyrownanie do lewej, zew vref, ADC1
ADCSRA=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//0x9F; // prescaler 128,wlaczenie ADC, przerwania
}
void PWM_init()
{
TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);
}
int main(void)
{
sei();
DDRA=0x00;
DDRB=0xFF;
DDRC=0xFC;
DDRD=0xFF;
PORTA=0x00;
PORTB=0x00;
PORTC=0x03;
PORTD=0x00;
ADC_init();
PWM_init();
TIMSK=(1<<TOIE1)|(1<<TOIE0);
ADCSRA|=(1<<ADSC);
double P_U[9]={vh9=3.13,vh8=2.97,vh7=2.80,vh6=2.62,vh5=2.43,vh4=2.21,vh3=1.98,vh2=1.72,vh1=1.40};
double Po_U[5]={v1=4,v2=4.5,v3=5,v4=5.5,v5=6};
while(1);
}
-
keruseykaryu