PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wieso läuft dat net so?



Getaco
17.08.2005, 20:21
Tach alle zusammen.
Erstmal ist mein erstes C program,2 es ist garnicht kommentier,dritens es funktioniert aber nicht so wie vorgesehen. Kann da mal jemand helfen bitte ?
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <inttypes.h>
//#include <global.h> // include our global settings
//#include <uart.h> // include uart function library

#include <proc.h>
#include <avr/pgmspace.h>

#define uchar unsigned char
#define uint unsigned int



static void avr_init(void);

unsigned const int phaseAngleTiming[257] = {
498,704,863,997,1116,1223,1322,1414,1501,1583,
1662,1737,1809,1878,1946,2011,2074,2136,2196,2254,
2312,2368,2422,2476,2529,2581,2632,2682,2732,2780,
2828,2876,2922,2968,3014,3059,3103,3147,3191,3234,
3276,3319,3360,3402,3443,3483,3524,3564,3603,3643,
3682,3721,3759,3797,3835,3873,3910,3948,3985,4022,
4058,4094,4131,4167,4202,4238,4274,4309,4344,4379,
4414,4448,4483,4517,4551,4585,4619,4653,4687,4721,
4754,4787,4821,4854,4887,4920,4953,4985,5018,5051,
5083,5116,5148,5180,5212,5245,5277,5309,5341,5373,
5404,5436,5468,5500,5531,5563,5594,5626,5657,5689,
5720,5751,5783,5814,5845,5876,5908,5939,5970,6001,
6032,6063,6095,6126,6157,6188,6219,6250,6281,6312,
6343,6374,6405,6437,6468,6499,6530,6561,6592,6624,
6655,6686,6717,6749,6780,6811,6843,6874,6906,6937,
6969,7000,7032,7064,7096,7127,7159,7191,7223,7255,
7288,7320,7352,7384,7417,7449,7482,7515,7547,7580,
7613,7646,7679,7713,7746,7779,7813,7847,7881,7915,
7949,7983,8017,8052,8086,8121,8156,8191,8226,8262,
8298,8333,8369,8406,8442,8478,8515,8552,8590,8627,
8665,8703,8741,8779,8818,8857,8897,8936,8976,9017,
9057,9098,9140,9181,9224,9266,9309,9353,9397,9441,
9486,9532,9578,9624,9672,9720,9768,9818,9868,9919,
9971,10024,10078,10132,10188,10246,10304,10364,104 26,10489,
10554,10622,10691,10763,10838,10917,10999,11086,11 178,11277,
11384,11503,11637,11796,12002};

volatile unsigned char ch1_level = 50,ch2_level = 0;
volatile unsigned char next_trigger;
volatile int test = 50;
volatile unsigned char clk_msec = 0,clk_sec = 0,clk_min = 00,clk_hour = 20;
volatile unsigned int t_msec = 0,old_msec = 0;
volatile unsigned char c_on=0;

int main(void)
{
avr_init();
//Variable declaration
char btn_temp;
char btn1,btn2;
unsigned int btn1_time = 0;
while(1==1)
{
btn_temp = PINA & 0b00001111;
btn1 = PINA & 0b00000001;
btn2 = PINA & 0b00000010;
//btn3 = PINA & 0b00000100;
//btn4 = PINA & 0b00001000;

if (old_msec != t_msec){

if(!btn1){
btn1_time = btn1_time + (t_msec - old_msec);
}
old_msec = t_msec;
}


if (clk_msec>=100){
PORTB = PORTB ^ 1<<2;
clk_msec = 0;
clk_sec++;
}
if (!btn1){
//in_use = in_use ^ 1<<0; // Toggle
//in_use = in_use & ~(1<<0); // Set
if (btn1_time >= 150){
// put_char(ch1_level); //Debuging
PORTB = PORTB & ~(1<<0); //dem kneppi seng luuscht unmaan :
btn1_time=149;
ch1_level = ch1_level + 1;
if (ch1_level >=255){
ch1_level = 0;
}
}
}
else{
btn1_time = 0;
if (!(PORTB & 1<<0)){
PORTB = PORTB ^ 1<<0;
}
}
}
}
static void avr_init(void)
{
// Initialize device here.
// initialize the UART (serial port)
//UART einstellen 8 Bit, 1 Stoppbit
UCSRB = (1<<TXEN) ;
UBRRH = (uchar)(UART_BAUD_SELECT>>8); // (uart.h)
UBRRL = (uchar)(UART_BAUD_SELECT); //Baud rate einstellen
UCSRC = (1<<URSEL)| (1<<UCSZ1)| (1<<UCSZ0); // 8 Bit

DDRA = 0b11110000;
PORTA = 0x00;
DDRB = 0xFF;
PORTB = 0xFF;
DDRC = 0xFF;
PORTC = 0x00;
enable_int(0);
MCUCR = (1<<ISC01) | (1<<ISC00); // int0 sense: rising edge
TCCR1B = (1<<CS11);//Vorteiler auf 8
// TIMSK |= (1<<TOIE1);
TIMSK |= (1<<OCIE1A);
TCNT1 = 1;
OCR1A =65530;
sei();
return;
}

INTERRUPT(SIG_INTERRUPT0){
TCNT1 = 1; //TIMER_START + TIMER_FIXED_BIAS - (127 << 4) + (u16) (g_zeroCrossBias << 4);
TCCR1B = (1<<CS11); // CK/8
TIMSK &= ~((1<<OCIE1A) | (1<<OCIE1B) | (1<<TOIE2) | (1<<TOIE1));
GICR &= ~(1<<INT0); // make sure we're not called recursively
GIFR = (1<<INTF0); // clear flag in case it's been set again already
t_msec++;
clk_msec++;
TCNT1 = 1;
next_trigger = 1;
OCR1A = 498;
// OCR1A = phaseAngleTiming[(int) next_trigger];
PORTC = 0x00;
GICR |= (1<<INT0); // reenable this isr
TIMSK |= (1<<OCIE1A);
return;
}
INTERRUPT(SIG_OUTPUT_COMPARE1A){

if (next_trigger >= ch1_level){
PORTC = PORTC | 0b00000001;
}

next_trigger = next_trigger + 1;

OCR1A = phaseAngleTiming[(int) next_trigger];

return;
}
//Interrupt enabler
void enable_int(char interrupt)
{
switch(interrupt)
{
case 0:
GICR = (1<<INT0);
break;
case 1:
GICR = (1<<INT1);
break;
default:
break;
}
}
void disable_int(char interrupt)
//Interrupt disabler
{
switch(interrupt)
{
case 0:
GICR = (1>>INT0);
break;
case 1:
GICR = (1>>INT1);
break;
default:
break;
}
}
void put_int(char c)
{
char c1=0;
while( (UCSRA & 1<<UDRE) == 0 ); //bereit für neues Zeichen ???
// itoa(c,c1,10);
UDR = c1; //und ausgeben
}
void put_char(char c)
{
while( (UCSRA & 1<<UDRE) == 0 ); //bereit für neues Zeichen ???
UDR = c; //und ausgeben
}

also das ganze soll mal ne dimmer steuerung werden doch bis jetzt ist es nur ne "ich flakere nur mal kurz und bin dann ganz aus" steuerung.

Psiyou
18.08.2005, 10:40
Hmm,
Kommentare waehren schon nicht schlecht...
Mir ist da so auf Anhieb nicht klar was Du womit bezweckst, und dann ist natuerlich auch schwer nen Fehler zu finden wenn die richtige Funktion nicht bekannt ist...
Besonders wuerd mich dieses riesen Array interissieren...

Getaco
18.08.2005, 12:28
dieses riesen array sind zuendzeitpunkte.d.h. wie schon kurz gesagt soll das ganze mal ein 220V phasenanschnitt dimmer werden,ich muss also jede halbwelle der wechselspannung in 256 teile zerlegen, das sin eben diese werte im array.Das Programm soll an sich einen taster auswerten (die ganzen btnxxx variabeln) der die helligkeit beeinflussen soll. INT0 wird durch den Nulldurchgang des Phasenwechselstroms ausgeloest. Das andere Interrupt ist fuer den Timer Compare gedacht und ist an sich das herzstueck des dimmers. An PortC haengen die triacs,PortB sind ein par dumme Leds und PortA die Taster.

Psiyou
18.08.2005, 13:06
Hmm,
aber mueste es dann nicht bei 0 losgehen ?? Und der Verlauf ist doch vom Prinzip auch egal...
Brauchst doch nur die frequenz=>Periodendauer, davon die haelfte und das dann so fein unterteilen wie du moechtest (wie Dein Timer kann) und dann einfach n fache davon in den Timer laden und dann entsprechend zuenden...

fwallenwein
18.08.2005, 13:49
Nur ein paar Dinge, die mir aufgefallen sind.

phaseAngleTiming[257] ist 257 lang.
Dein next_trigger ist unsigned char ( 0..255 )
also erreichst du nie die letzen werte des arrays.


Im Interrupt0 wird next_trigger = 1;
also erreichst Du nie phaseAngleTiming[0]



if(!btn1){
btn1_time = btn1_time + (t_msec - old_msec);

heist das - wenn Button 1 nicht gedrückt ist ?
Wolltest Du da nicht auf gedrückt abfragen ( if(btn1){ )



if (ch1_level >=255){
ch1_level = 0;

schadet nicht - ist aber auch nicht sinvoll.
ch1_level wird nie groesser als 255 - ist ja unsigned char.
Wenn nach 255 eine 1 addiert wird, geht er sowieso auf 0


Gruss
Frank

michaelb
18.08.2005, 13:57
hallo getaco,
warum muss dein erstes C programm gleich auch so riesig sein!!! Fang lieber erst mit kleineren an!
Gruß Michi

fwallenwein
18.08.2005, 13:59
Nach was -

was fuer einen Prozessor nimmst Du ?

Du hast mit
unsigned const int phaseAngleTiming[257]
ja schon 257*2 Bytes Ram verbraten.
Es gibt AVR Prozessoren mit 512 Byte Ram.
Wenn Du so einen hast, dann hast Du auf jeden Fall den Speicher überladen.

Kannst Diese Tabelle ja mal in's Flash legen.
#include <avr/pgmspace.h> hast Du ja schon drin,
nur noch nicht genutzt.

Frank

Getaco
18.08.2005, 15:46
Danke euch allen dass ihr so zahlreich geantwortet habt.

@ Psiyou : Ich habe bereits ein programm in Bascom geschrieben und das funtz mit der gleichen methode wie die aus dem C teil. Aber hast schon recht der verlauf ist fast egal.

@fwallenwein: Dass phaseAngleTiming[257] ist liegt nur daran dass ich bereits soviel rumgespielt und getested habe, und dabei halt auch des array auf 257 anstelle von 255 bzw 256. Da fällt mir gerade ein : Wo begint ein array in winavr bei array[0] oder array[1]?
zum next_trigger im Int0 der muss auf 1 weil der Nullte (0) eigentlich der reale nulldurchgang der phase ist.

!btn1 ist richtig die taster gehen gegen masse.

die If(ch1_level) geschichte ist mir auch klar nur wust ich meinen fingern keinen rat mehr und hab überal hinzugefügt und weg kommentiert

@michaelb : Warum? ist doch ein schönes kleines Problemschen das ich habe ;) aber hast schon recht nur hab ich keinen bock auf "kleine" programme.


Nochmal @fwallenwein : AHA :-O soviel Ram verbraten Hae? keine Ahnung Bascom hat mir das immer abgenommen :) Achso hmm dann sind die 103% die der compiler mir zeigt das ram :( Und wie krieg ich die variable ins flash ? Also mal ehrlich das mir dem Include hab ich irgendwo rauskopiert O:)

Psiyou
18.08.2005, 16:05
In C beginnt das Arry immer bei 0 !!
(Array variable ist Pointer auf das erste Element im Array).

fwallenwein
18.08.2005, 16:13
Danke euch allen dass ihr so zahlreich geantwortet habt.

Bitte !



@fwallenwein: Da fällt mir gerade ein : Wo begint ein array in winavr bei array[0] oder array[1]?

Bei 0



!btn1 ist richtig die taster gehen gegen masse.

Dann müssen wir uns aber das nochmal anschauen
Also, wenn die Taste gedrückt ist :

Wenn Taste Gedrückt.............if (!btn1){
wenn Zeit >= 150....................if (btn1_time >= 150){
Zeit = 149.................................btn1_time=149;
und Level hochzählen.................ch1_level = ch1_level + 1;

in der nächsten Millisekunde wir in

....if (old_msec != t_msec){
........if(!btn1){
.............btn1_time = btn1_time + (t_msec - old_msec);

die Zeit wieder von 149 auf 150 hochgesetzt.
Also kommt er in der nächsten millisekunde wieder
in die If abfrage oben rein, zaehlt den level wieder hoch,
setzt Zeit wieder auf 149 usw. usw.

Hab ich das richtig verstanden ? Ist das so gewollt ?



Nochmal @fwallenwein : AHA :-O soviel Ram verbraten Hae? keine Ahnung Bascom hat mir das immer abgenommen :) Achso hmm dann sind die 103% die der compiler mir zeigt das ram :( Und wie krieg ich die variable ins flash ? Also mal ehrlich das mir dem Include hab ich irgendwo rauskopiert O:)

Ins Flash ist einfach :
unsigned const int phaseAngleTiming[257] PROGMEM = {
....
}

rauslesen - da muss ich auch erst mal wieder die Doku befragen.
Ich habe immer Strukturen in's Progmem gelegt, und diese zum bearbeiten mit "memcpy_P" ins RAM geholt.
Aber da müsste ich selbst erst in der Doku nachlesen.
Weiss ich nicht mehr auswendig.

Gruss
Frank[/code]

Getaco
19.08.2005, 06:35
Ja hast du richtig verstanden Frank,ich benutze es kuasi als entprellung der taster und dass ich 150ms warte bevor zum ersten mal gezaehlt wird hat als grund dass ich ja ne lampe dimen will und die ja auch irgendwie ein- und ausschalten muss. Der Code in c ist noch nicht fertig aber in Bascom läuft er bereits.

Das mit dem PROGMEM werd ich jetzt gleich mal testen und dann schaun wer mal :-)

Getaco
19.08.2005, 08:36
Geil ! Hab das mit dem PROGMEM gerade getested :-) Es funtz. Ach ja Frank;Rauslesen des Array mach ich mit pgm_read_word(&phaseAngleTiming[(int) next_trigger]).