Fórum témák

» Több friss téma
Fórum » AVR - Miértek hogyanok
 
Témaindító: pakibec, idő: Márc 11, 2006
Témakörök:
WinAVR / GCC alapszabályok:
1. Ha ISR-ben használsz globális változót, az legyen "volatile"
2. Soha ne érjen véget a main() függvény
3. UART/USART hibák 99,9% a rossz órajel miatt van
4. Kerüld el a -O0 optimalizációs beállítást minden áron
5. Ha nem jó a _delay időzítése, akkor túllépted a 65ms-et, vagy rossz az optimalizációs beállítás
6. Ha a PORTC-n nem működik valami, kapcsold ki a JTAG-et
Bővebben: AVR-libc FAQ
Lapozás: OK   812 / 812
(#) Istvanpisti válasza Milligram hozzászólására (») Feb 11, 2020 / 1
 
Szia!
Te a TIMER1/COUNTER1 8-as PWM módját választottad, ahol a TOP értéket (ameddig felfelé számol a számláló) az ICR1 regiszter határozza meg, egyszerűbben mondva ez fogja meghatározni a PWM frekvenciát, az OCR1A, és OCR1B pedig a két output compare unit kimenetén a kitöltési tényezőt.
Adjál értéket az ICR1 regiszternek.
(#) Milligram válasza Istvanpisti hozzászólására (») Feb 11, 2020 /
 
Ha ICR1 regiszternek értéket adok akkor még a PB1 se kapcsol.
Próbáltam változtatni a WGM de a PB2 akkor se akar változni . :/
(#) Istvanpisti válasza Milligram hozzászólására (») Feb 11, 2020 /
 
A kérdés, mekkora értéket adtál?
(#) Milligram válasza Istvanpisti hozzászólására (») Feb 11, 2020 /
 
Próbáltam több értéket 0-tól 65535-ig.
(#) Milligram hozzászólása Feb 11, 2020 /
 
Sikerült egy attiny85 amit akartam.
Ha egy bement ADC ként szolgál és ezt az értéket beírom a pwm jeléhez ez szépen változik is de csak akkor ha a függvény lefutott.
Egy megszakítást szeretnék a main függvénybe meghívtam a sei() parancsot és azon kívül pedig a ISR(ADC_vect),de nem változik a kimenet amíg le nem fut az összes függvény.
Vagy esetleg meg lehet oldani másként is?
(#) Istvanpisti válasza Milligram hozzászólására (») Feb 11, 2020 /
 
Ha kódot mutatnál, talán könnyebb lenni megpróbálni segíteni.
(#) Milligram válasza Istvanpisti hozzászólására (») Feb 11, 2020 /
 
Kiszedtem a megszakítást de szeretném hogy csak akkor legyen a kimenet aktiv (PB1-OC0B) ha PB0 -ra rákapcsolom a mínuszt.
Ugyan igy a PB3(Bemenet) és PB4(Kimenet).
Ha a PB0 megkapja a jelet akkor fel is kapcsol arra a PWM jelre ami épp be van állítva az ADC bemeneten de úgy marad sajnos :/ .

  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3. #include <avr/interrupt.h>
  4.  
  5.  
  6.  
  7. void adc_setup (void){
  8.  
  9.         ADMUX |= (1 << MUX0);
  10.         ADMUX |= (1 << ADLAR);
  11.  
  12.  
  13.         ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN) | (1<<ADIF) ;
  14. }
  15.  
  16. int adc_read (void){
  17.  
  18.         ADCSRA |= (1 << ADSC);
  19.  
  20.         while (ADCSRA & (1 << ADSC));
  21.  
  22.         return ADCH;
  23. }
  24.  
  25. void pwm_writeL (int val)
  26. {
  27.         OCR0B = val;
  28.         OCR1B = 255;
  29.        
  30.         }
  31.        
  32. void pwm_writeR (int val){
  33.        
  34.         OCR1B = val;
  35.         OCR0B = 255;
  36.        
  37.        
  38. }
  39.  
  40. void pwm_setup(){
  41.        
  42.         TCCR0B |= (1 << CS01) | (1 << CS00);
  43.         TCCR0A |= (1 << WGM00)|(1 << WGM01);
  44.         TCCR0A |= (1 << COM0B1);
  45.        
  46.         TCCR1 |= (1<<CS12);
  47.         GTCCR |= (1<<COM1B1)|(1<<PWM1B);
  48.  
  49.        
  50. }
  51.  
  52. int main (void){
  53.         int val;
  54.         int b;
  55.         b=0;
  56.  
  57.        
  58.         DDRB &= ~((1<<PB0)|(1<<PB3));
  59.         PORTB |= (1<<PB0)|(1<<PB3);
  60.        
  61.        
  62.        
  63.        
  64.         adc_setup();
  65.         pwm_setup();
  66.  
  67.        
  68.         while (1) {
  69.                
  70.                 val = adc_read();
  71.                
  72.                
  73.                
  74.                                
  75.         if (((PINB &(1<<PINB0))==0) && (b==0)){
  76.                        
  77.                         DDRB |= (1<<PB1);
  78.                         b=1;
  79.                 }
  80.                                                                
  81.                         if((PINB &(1<<PINB0))==0){
  82.                         _delay_ms(5);
  83.                         pwm_writeL(val);                       
  84.                         }
  85.                
  86.                                
  87.        
  88.         if (((PINB &(1<<PINB3))==0) && (b==1)){
  89.                
  90.                 DDRB |= (1<<PB4);
  91.                 b=2;
  92.         }
  93.        
  94.                  if((PINB &(1<<PINB3))==0){
  95.                                 _delay_ms(5);
  96.                                 pwm_writeR(val);       
  97.                                
  98.                         }
  99.                        
  100.                
  101.                
  102.                
  103.         }
  104. }



Köszönöm a segítséget.
(#) Milligram hozzászólása Feb 11, 2020 /
 
Át írtam a kódot egy kicsit .

  1. int main (void){
  2.         int val;
  3.         int b;
  4.         b=0;
  5.  
  6.        
  7.         DDRB &= ~((1<<PB0)|(1<<PB3));
  8.         PORTB |= (1<<PB0)|(1<<PB3);
  9.        
  10.         DDRB |= (1<<PB1)|(1<<PB4);
  11.        
  12.        
  13.        
  14.         adc_setup();
  15.         pwm_setup();
  16.        
  17. pwm_writeL(255);
  18. pwm_writeR(255);
  19.        
  20.         while (1) {
  21.                
  22.                 val = adc_read();
  23.                        
  24.                                                                
  25.                         if((PINB &(1<<PINB0))==0){
  26.                         _delay_ms(5);
  27.                         pwm_writeL(val);                       
  28.                         }
  29.                         if(PINB &(1<<PINB0)==1){
  30.                                 pwm_writeL(255);
  31.                         }
  32.        
  33.                        
  34.                  if((PINB &(1<<PINB3))==0){
  35.                                 _delay_ms(5);
  36.                                 pwm_writeR(val);       
  37.                                
  38.                         }
  39.                         if(PINB &(1<<PINB3)==1){
  40.                                 pwm_writeR(255);
  41.                         }
  42.                
  43.                
  44.                
  45.         }
  46. }


De ilyenkor a PB4 csak villog ha a PB3 aktiv.
(#) Milligram hozzászólása Feb 11, 2020 /
 
Sikerült megoldani az alábbi módon.

  1. while (1) {
  2.                
  3.                 val = adc_read();
  4.                        
  5.                                                                
  6.                         if((PINB &(1<<PINB0))==0){
  7.                         _delay_ms(5);
  8.                         pwm_writeL(val);                       
  9.                         }
  10.                         if((PINB &(1<<PINB0))==1){
  11.                                 _delay_ms(5);
  12.                                 pwm_writeL(255);
  13.                         }
  14.        
  15.                        
  16.                  if((PINB &(1<<PINB3))==0){
  17.                                 _delay_ms(5);
  18.                                 pwm_writeR(val);       
  19.                                
  20.                         }
  21.                         if((PINB &(1<<PINB3))==1){
  22.                                 _delay_ms(5);
  23.                                 pwm_writeR(255);
  24.                         }
  25.                
  26.                
  27.                
  28.         }


Beraktam egy delay-t és így nem villog a PB4 és csak akkor aktív ha van bemenet .
(#) jacoka hozzászólása Feb 20, 2020 /
 
Tiny13-hoz remek forrásanyag 100+ projekt attiny13-hoz.

UART library tiny13-hoz, viszont egy minimális korrekcióval remekül használható 25/45/85-nél is a klasszikus 1000000/8000000/16000000 órajeleken.
  1. #if defined F_CPU
  2. #define UART_BAUDRATE (9600 * (F_CPU / 1000000))
  3. #endif


Természetesen putty-ban ennek megfelelően kell beállítani a baud rate-et.
A hozzászólás módosítva: Feb 20, 2020
(#) jacoka válasza jacoka hozzászólására (») Feb 20, 2020 /
 
Az általam kicsit módosított UART library (header-ként).
Tiny 13/25/45/85 WinAVR és AvrDude környezet (windows/linux/valamint raspberry pi raspbian környezetben használva)

  1. #ifndef __serial_h
  2. #define __serial_h
  3.  
  4. #define UART_RX_ENABLED  (0)
  5. #define UART_TX_ENABLED  (1)
  6.  
  7. #ifndef F_CPU
  8. # define F_CPU (1000000UL)
  9. #endif
  10.  
  11. #if defined(UART_TX_ENABLED) && !defined(UART_TX)
  12. # define UART_TX PB3
  13. #endif
  14.  
  15. #if defined(UART_RX_ENABLED) && !defined(UART_RX)
  16. # define UART_RX PB4
  17. #endif
  18.  
  19. #if (defined(UART_TX_ENABLED) || defined(UART_RX_ENABLED)) && !defined(UART_BAUDRATE)
  20. # define UART_BAUDRATE (9600)
  21. #endif
  22.  
  23. #define TXDELAY   (int)(((F_CPU / UART_BAUDRATE) - 7 + 1.5) / 3)
  24. #define RXDELAY   (int)(((F_CPU / UART_BAUDRATE) - 5 + 1.5) / 3)
  25. #define RXDELAY2  (int)((RXDELAY * 1.5) - 2.5)
  26. #define RXROUNDED (((F_CPU/UART_BAUDRATE)- 5 + 2) / 3)
  27.  
  28. #if RXROUNDED > 127
  29. # error Low baud rates are not supported - use higher, UART_BAUDRATE
  30. #endif
  31.  
  32. #define MAXCHAR (10)
  33.  
  34. #include <avr/interrupt.h>
  35.  
  36. uint8_t uart_getc(void) {
  37. #ifdef  UART_RX_ENABLED
  38.         char    c;
  39.         uint8_t sreg;
  40.  
  41.         sreg = SREG;
  42.         cli( );
  43.         PORTB &= ~(1 << UART_RX);
  44.         DDRB  &= ~(1 << UART_RX);
  45.        
  46.         __asm volatile(
  47.                 " ldi r18, %[rxdelay2] \n\t"
  48.                 " ldi %0, 0x80 \n\t"
  49.                 "WaitStart: \n\t"
  50.                 " sbic %[uart_port]-2, %[uart_pin] \n\t"
  51.                 " rjmp WaitStart \n\t"
  52.                 "RxBit: \n\t"
  53.                 " subi r18, 1 \n\t"
  54.                 " brne RxBit \n\t"
  55.                 " ldi r18, %[rxdelay] \n\t"
  56.                 " sbic %[uart_port]-2, %[uart_pin] \n\t"
  57.                 " sec \n\t"
  58.                 " ror %0 \n\t"
  59.                 " brcc RxBit \n\t"
  60.                 "StopBit: \n\t"
  61.                 " dec r18 \n\t"
  62.                 " brne StopBit \n\t"
  63.                 : "=r" (c)
  64.                 : [uart_port] "I" (_SFR_IO_ADDR(PORTB)),
  65.                 [uart_pin] "I" (UART_RX),
  66.                 [rxdelay ] "I" (RXDELAY),
  67.                 [rxdelay2] "I" (RXDELAY2)
  68.                 : "r0","r18","r19"
  69.         );
  70.         SREG = sreg;
  71.         return c;
  72. #else
  73.         return (-1);
  74. #endif
  75. }
  76.  
  77. void uart_putc(uint8_t c) {
  78. #ifdef  UART_TX_ENABLED
  79.         uint8_t sreg;
  80.  
  81.         sreg = SREG;
  82.         cli( );
  83.         PORTB |= 1 << UART_TX;
  84.         DDRB  |= 1 << UART_TX;
  85.        
  86.         __asm volatile(
  87.                 " cbi %[uart_port], %[uart_pin] \n\t"
  88.                 " in r0, %[uart_port] \n\t"
  89.                 " ldi r30, 3 \n\t"
  90.                 " ldi r28, %[txdelay] \n\t"
  91.                 "TxLoop: \n\t"
  92.                 " mov r29, r28 \n\t"
  93.                 "TxDelay: \n\t"
  94.                 " dec r29 \n\t"
  95.                 " brne TxDelay \n\t"
  96.                 " bst %[ch], 0 \n\t"
  97.                 " bld r0, %[uart_pin] \n\t"
  98.                 " lsr r30 \n\t"
  99.                 " ror %[ch] \n\t"
  100.                 " out %[uart_port], r0 \n\t"
  101.                 " brne TxLoop \n\t"
  102.                 :
  103.                 : [uart_port] "I" (_SFR_IO_ADDR(PORTB)),
  104.                 [uart_pin] "I" (UART_TX),
  105.                 [txdelay ] "I" (TXDELAY),
  106.                 [ch] "r" (c)
  107.                 : "r0","r28","r29","r30"
  108.         );
  109.         SREG = sreg;
  110. #endif
  111. }
  112.  
  113. void serial_printc(const uint8_t c) {
  114.         uart_putc(c);
  115. }
  116.  
  117. void serial_prints(const char *s) {
  118.         while(*s) uart_putc(*(s++));
  119. }
  120. /*
  121. *
  122. *      print integer number
  123. *      1 param : integer
  124. *      2 param : clear digit (param length) if param greater than zero
  125. *
  126. */
  127. void serial_printi(int i, uint8_t d) {
  128.         int  j;
  129.         char s[MAXCHAR] = {0x00};
  130.  
  131.         if(i < 0) {
  132.                 uart_putc('-');
  133.                 i = -i;
  134.         }
  135.  
  136.         if(i == 0) {
  137.                 uart_putc('0')
  138.                 if(d) d--;
  139.                 while(d && d--) uart_putc(' ');
  140.         }
  141.         else {
  142.                 for(j = 0; i > 0 && j < MAXCHAR; i /= 10, j++) {
  143.                         s[j] = (i % 10) + '0';
  144.                 }
  145.        
  146.                 j -= 1;
  147.        
  148.                 for(; j >= 0; j--) {
  149.                         uart_putc(s[j]);
  150.                         if(d) d--;
  151.                 }
  152.  
  153.                 while(d && d--) uart_putc(' ');
  154.         }
  155. }
  156.  
  157. #endif  /* __serial_h */
A hozzászólás módosítva: Feb 20, 2020
(#) jacoka hozzászólása Feb 20, 2020 /
 
Attiny 13/25/45/85 családhoz használható HD44780/KS7066 kompatibilis 4/8bites parallel kijelzőhöz 2x16 LCD készítettem shiftregiszteres meghajtót + saját library-t (2 vezetékes, nem i2c és nem SPI). Ha valakit komolyabban érdekelne megosztom a nyák illetve a library forrásokat.
A hozzászólás módosítva: Feb 20, 2020
(#) zombee hozzászólása Csü, 8:36 /
 
Sziasztok!
T0,T1,T2 (időzítő bemenetek) beállíthatók-e közvetlen interrupt generáláshoz fel-VAGY lefutó élre úgy, mint az INT lábak? Időzítő CTC mód, OCRn(A)=1, órajel forrás Tn fel-vagy lefutó élen, megszakítás engedélyezve komparálásra. A többi alternatíva (ICP1, AIN1) már foglalt, hasonló célra.
Fontos, hogy csak az egyik élen generálhat megszakítást, így a PCINT ki van zárva.
(#) exup74 hozzászólása Csü, 22:11 /
 
Sziasztok.

Nem kezdtem az elejétől olvasgatni a topic-ot, lehet nem is ide kéne kérdeznem ez ügyben. Nagyon kezdő vagyok a programozásban, igazából meglévő példákat alakítgatok és módosítok a saját feladatomhoz. Gondolom volt is ilyenről szó, valószínűleg beállítási gondjaim vannak. A lényeg, hogy atmega8, de 328-al is ez van. Modbus kommunikációm csak akkor üzemel, ha belső 1MHZ óra van használva. Ha belső 8 vagy külső 12, 16, akkor eldobálja a kommunikációt. bootloaderben kiválasztom a "megfelelőt" az arduino ide progiban is a megfelelő board-ot. Mégis csak default belső 1MHZ beállítással üzemel a modbus.

Előre is köszi minden okosságot
Következő: »»   812 / 812
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu