Hallo, ich habe hier einen 16 Bit PWM Timer, der als Software-PWM arbeitet. Dabei funktioniert das PWM nur wenn eine Funktion zum senden des UARTS aufgerufen wird, die eigentlich nichts mit dem PWM zu tun hat. Die Fehlfunktion (also wenn das USART-Funktion nicht aufgerufen wird), nimmt der Duty bis zu 255, darüber geht mein PWM aus. Bis 255 (also 8-Bit geht es aber nach meiner Einschätzung richtig. Das ganze ist mir arg dubios und ich habe keine Ahnung womit das zusammenhängen kann. Kann es eventuell sein, dass wenn OCR1A geschrieben beschrieben wird, der Interrupt ausfällt? Aber wieso geht es dann bis 8 Bit. Hoffentlich hat jemand von euch eine Idee... Ich bin jedenfalls Ratlos... Grüße Michael Dateiübersicht: main.c: Der Main loop, hier ist auch nochmal die Funktion die zickt hervorgehoben. usart.c: Die USART-sendefunktion pwm.c: Die PWM sende funktion pwm.h: Headerdatei mit ein paar Makros
Langer Rede kurzer Sinn: Hör auf dem Compiler mit deinen Assembler und Register-Reservierungs Escapaden ins Handwerk zu pfuschen. Oder was glaubst du, wie er bei den UART Routinen, die getrennt von allem anderem übersetzt werden, berücksichtigen soll, dass du dir für die PWM Routinen ein paar Register reseviert hast?
Dort kommt es aber auf jeden Takt an, zudem sagt mir die avrlibc, dass es okay ist was ich mache. http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind >Typically, it should be safe to use r2 through r7 that way. Anbei mal das Listing... Auszüge: void usart0_putc( char data ) { 502: 28 2f mov r18, r24 unsigned char tmp; tmp = ( USART0_TxHead + 1 ) & USART0_TX_BUFFER_MASK; 504: 90 91 fb 00 lds r25, 0x00FB 508: 9f 5f subi r25, 0xFF ; 255 50a: 9f 73 andi r25, 0x3F ; 63 while ( tmp == USART0_TxTail ); 50c: 80 91 fc 00 lds r24, 0x00FC 510: 98 17 cp r25, r24 512: e1 f3 breq .-8 ; 0x50c <usart0_putc+0xa> USART0_TxBuf[tmp] = data; 514: e9 2f mov r30, r25 516: f0 e0 ldi r31, 0x00 ; 0 518: e5 54 subi r30, 0x45 ; 69 51a: ff 4f sbci r31, 0xFF ; 255 51c: 20 83 st Z, r18 USART0_TxHead = tmp; 51e: 90 93 fb 00 sts 0x00FB, r25 UCSR0B |= (1<<UDRIE0); 522: 55 9a sbi 0x0a, 5 ; 10 } 524: 08 95 ret 000006d2 <__vector_8>: // In inline ASM Schreiben, da sonst zu langsam! ISR(SIG_OVERFLOW1){ asm volatile ( 6d2: 4c bc out 0x2c, r4 ; 44 6d4: 5d bc out 0x2d, r5 ; 45 6d6: 32 ba out 0x12, r3 ; 18 6d8: 18 95 reti 000006da <__vector_6>: */ } ISR(SIG_OUTPUT_COMPARE1A){ asm volatile ( 6da: 22 ba out 0x12, r2 ; 18 6dc: 18 95 reti 000006de <__vector_1>: [addr_PIND] "M" (_SFR_IO_ADDR(PORTD)) ); // Old c code: PIND=_pwm_on; } ich sehe da kein Problem, dass sich die Regisgter irgendwie überplappen. Wäre aber echt toll, wenn du mir das gegenteil beweisen könntest.
1 | #define pwm_set_val(val) { \
|
2 | OCR1A=0xFFFF-val; \
|
3 | }
|
4 | ...
|
5 | uint_fast8_t rec; |
6 | ...
|
7 | rec=usart0_getc(); |
8 | //pwm_set_val(rec);
|
Verstehe ich das richtig, dass deine Frage lautet, warum du damit die PWM nur in einem 8-Bit-Bereich variieren kannst?
Oder geht es hierum?
1 | send=adc_read(0); |
2 | pwm_set_val(send); |
> main.c: Der Main loop, hier ist auch nochmal die Funktion die zickt > hervorgehoben. Worin soll denn die Hervorhebung bestehen?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.