Estoy usando un ATtiny1634 para Mi proyecto y yo queríamos asegurarnos de que el cristal externo de 8MHz se soldara correctamente antes de configurar el fusible para seleccionarlo en el arranque. Así que aquí está mi código de lo que encontré en la hoja de datos:
void setup()
{
// Select external 8MHz crystal
CCP = 0xD8; // ATtiny1634 Signature
CLKSR = 0b1101 | _BV(CSTR);
loop_until_bit_is_set(CLKSR, OSCRDY);
// Set prescaler to unity
CCP = 0xD8; // ATtiny1634 Signature
CLKPR = 0;
loop_until_bit_is_set(CLKSR, OSCRDY);
}
Esta es solo la función de configuración que me interesa aquí. En una función de bucle, alterno el estado de una salida que está conectada a un zumbador (sin un oscilador interno) para poder escuchar el tono resultante. Por supuesto, introduje un poco de retraso para hacer que el sonido sea audible.
Hay 2 cosas que noté. Primero, el prescaler no parece cambiar. Debería escuchar un sonido 8 veces más alto, pero sigue siendo el mismo. A continuación, el microcontrolador a veces parece detenerse, luego escucho un ruido de silbido proveniente del búfer y la frecuencia aumenta lentamente hasta el tono esperado . El tono es estable después de, digamos, 8-10 segundos.
¿Esto es normal? ¿O me he perdido algo?
Por extraño que parezca, el zumbador hace un ruido sordo cuando toco las almohadillas XTAL pins (en las que el cristal está soldado) con mi sonda de alcance. Eso sugiere que el cristal realmente está funcionando ... ¿verdad? Ese [aumento lento del reloj] no ocurre si comento la selección del reloj. Y no importa si utilizo la configuración de la sonda de rango 10x o no. También utilicé dos 15pF con el cristal, como se indica en la hoja de datos (entre 12 y 22pF).
EDIT : Resulta que el primer problema fue un PEBCAK. Para una prueba, compilé el programa y configuré F_CPU
a 1MHz en la línea de comandos (con el valor predeterminado de preescala, también conocido como 8 ). Para la segunda prueba, preescala programada en 1, había usado el valor F_CPU
predeterminado de mi archivo make, que es 8MHz . Por lo tanto, es absolutamente normal que no haya una diferencia en el tono generado.
Acabo de olvidar que el problema restante es el del cristal externo. Todavía no puedo descartar una unión de soldadura defectuosa, por eso quise seleccionar el reloj dinámicamente.
EDIT : a continuación se muestra una vista del cristal y las pistas.
Coloqué el cristal y las tapas lo más cerca posible del MCU. Ya he usado este diseño para un ATmega64M1 sin ningún problema.
EDIT : A continuación se encuentra el código de ensamblaje (para fines de prueba), ahora con los nombres de registro adecuados.
main: format de fichier elf32-avr
Déassemblage de la section .text :
00000000 <__vectors>:
0: 37 c0 rjmp .+110 ; 0x70 <__ctors_end>
4: 49 c0 rjmp .+146 ; 0x98 <__bad_interrupt>
8: 47 c0 rjmp .+142 ; 0x98 <__bad_interrupt>
c: 45 c0 rjmp .+138 ; 0x98 <__bad_interrupt>
10: 43 c0 rjmp .+134 ; 0x98 <__bad_interrupt>
14: 41 c0 rjmp .+130 ; 0x98 <__bad_interrupt>
18: 3f c0 rjmp .+126 ; 0x98 <__bad_interrupt>
1c: 3d c0 rjmp .+122 ; 0x98 <__bad_interrupt>
20: 3b c0 rjmp .+118 ; 0x98 <__bad_interrupt>
24: 39 c0 rjmp .+114 ; 0x98 <__bad_interrupt>
28: 37 c0 rjmp .+110 ; 0x98 <__bad_interrupt>
2c: 35 c0 rjmp .+106 ; 0x98 <__bad_interrupt>
30: 33 c0 rjmp .+102 ; 0x98 <__bad_interrupt>
34: 31 c0 rjmp .+98 ; 0x98 <__bad_interrupt>
38: 2f c0 rjmp .+94 ; 0x98 <__bad_interrupt>
3c: 2d c0 rjmp .+90 ; 0x98 <__bad_interrupt>
40: 2b c0 rjmp .+86 ; 0x98 <__bad_interrupt>
44: 29 c0 rjmp .+82 ; 0x98 <__bad_interrupt>
48: 27 c0 rjmp .+78 ; 0x98 <__bad_interrupt>
4c: 25 c0 rjmp .+74 ; 0x98 <__bad_interrupt>
50: 23 c0 rjmp .+70 ; 0x98 <__bad_interrupt>
54: 21 c0 rjmp .+66 ; 0x98 <__bad_interrupt>
58: 1f c0 rjmp .+62 ; 0x98 <__bad_interrupt>
5c: 1d c0 rjmp .+58 ; 0x98 <__bad_interrupt>
60: 1b c0 rjmp .+54 ; 0x98 <__bad_interrupt>
64: 19 c0 rjmp .+50 ; 0x98 <__bad_interrupt>
68: 17 c0 rjmp .+46 ; 0x98 <__bad_interrupt>
6c: 15 c0 rjmp .+42 ; 0x98 <__bad_interrupt>
...
00000070 <__ctors_end>:
70: 11 24 eor r1, r1
72: 1f be out SREG, r1 ; 63
74: cf ef ldi r28, 0xFF ; 255
76: d4 e0 ldi r29, 0x04 ; 4
78: de bf out SPH, r29 ; 62
7a: cd bf out SPL, r28 ; 61
0000007c <setup>:
#define SELECT C,2
#define BUZZER A,6
void setup()
{
// Wait for clock to be stable (probably useless here but...)
7c: 02 b6 in r0, CLKSR ; 50
7e: 07 fe sbrs r0, 7
80: fd cf rjmp .-6 ; 0x7c <setup>
CCP = CCPSIG;
CLKSR = 0b1101 | _BV(CSTR); // Select 8MHz external crystal
loop_until_bit_is_set(CLKSR, OSCRDY);
#endif
// Change clock prescaler to unity
82: 88 ed ldi r24, 0xD8 ; 216
84: 8f bd out CCP, r24 ; 47
clock_prescale_set(clock_div_1);
86: 13 be out CLKPR, r1 ; 51
//~ CCP = CCPSIG;
88: 02 b6 in r0, CLKSR ; 50
8a: 07 fe sbrs r0, 7
8c: fd cf rjmp .-6 ; 0x88 <setup+0xc>
//~ CLKPR = 0;
loop_until_bit_is_set(CLKSR, OSCRDY);
8e: 42 9a sbi DDRC, 2 ; 8
// Setup pins
90: 86 9a sbi DDRA, 6 ; 16
set_output(SELECT);
92: 4a 9a sbi PORTC, 2 ; 9
set_output(BUZZER);
94: 0b d0 rcall .+22 ; 0xac <main>
96: 0c c0 rjmp .+24 ; 0xb0 <_exit>
00000098 <__bad_interrupt>:
98: b3 cf rjmp .-154 ; 0x0 <__vectors>
0000009a <loop>:
set_pin(SELECT);
}
void loop()
9a: 91 b3 in r25, PORTA ; 17
9c: 80 e4 ldi r24, 0x40 ; 64
9e: 89 27 eor r24, r25
a0: 81 bb out PORTA, r24 ; 17
milliseconds can be achieved.
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
a2: 84 ef ldi r24, 0xF4 ; 244
a4: 91 e0 ldi r25, 0x01 ; 1
a6: 01 97 sbiw r24, 0x01 ; 1
a8: f1 f7 brne .-4 ; 0xa6 <loop+0xc>
aa: 08 95 ret
000000ac <main>:
{
toggle_pin(BUZZER);
_delay_us(250);
}
ac: f6 df rcall .-20 ; 0x9a <loop>
ae: fe cf rjmp .-4 ; 0xac <main>
000000b0 <_exit>:
b0: f8 94 cli
000000b2 <__stop_program>:
b2: ff cf rjmp .-2 ; 0xb2 <__stop_program>