Tengo algunos problemas para entender esto, y podría ser un pequeño error en alguna parte, que sigo omitiendo... pero tal como está, estoy tratando de crear un "retraso" de hardware que pueda ejecutarse al mismo tiempo. se ejecuta el código.
Para fines de práctica, simplemente estoy tratando de hacer parpadear un LED en PD4 en un intervalo de 1 segundo.
He usado la siguiente fórmula para determinar el preescalador y el valor del Registro de comparación de salida A (OCR1A):
Usando un prescaler de 256, obtengo un valor para OCR1A de 62499:
Mirando los registros TCCR1A y TCCR1B en la hoja de datos, configuré los bits del modo de generación de forma de onda (WGM) para usar CTC y los bits de selección de reloj para usar el preescalador 256.
Ahora, en mi función principal, comienzo encendiendo el LED y luego llamo a mi función que debe iniciar el temporizador. Luego verifico si el indicador de desbordamiento se ha configurado en TIFR1 y, si es así, apago el LED y escribo un 1 lógico en TOV1 para restablecer el indicador de desbordamiento.
int main(void) {
DDRD = 0xFF;
PORTD = 0x00;
while (1) {
// Turn on LED at PD4
PORTD |= (1 << PD4);
oneSecondDelay();
// Checking to see if the overflow flag has been set
if (TOV1 == 1) {
// Turn off LED at PD4
PORTD &= ~(1 << PD4);
// Set 1 in the Output Compare A Flag to reset the overflow flag
TIFR1 = (1 << TOV1);
}
}
return 0;
}
En mi función, empiezo configurando OCR1A en el valor que calculé anteriormente. Luego configuro los bits en el registro TCCR1B que deben configurarse para usar el preescalador específico y el modo CTC, y luego creo un bucle mientras espero que ocurra el evento de desbordamiento; que imagino debería tomar un segundo.
void oneSecondDelay() {
// Set the target value to 62499
OCR1A = 0xF423;
// Set prescaler to 256 and start the timer
TCCR1B |= (1 << WGM12) | (1 << CS12);
// Waiting for the overflow event
while ((TIFR1 & (1 << OCF1A))) {
}
}
TLDR: Ahora, el problema es que no importa lo que pueda soñar, el LED está constantemente encendido, y no estoy seguro de si estoy configurando los valores incorrectos en los registros, o si solo estoy teniendo algunos pedos cerebrales.
void oneSecondDelay() {
la construcción de esa función no es terriblemente óptima. fácilmente podría haber hecho que tomara un parámetro para determinar la duración del retraso, sin mencionar otros problemas.
Una solución rápida sería algo como esto: todavía tiene problemas, pero al menos funciona.
//create a user-specified delay
//dly-duration in timer ticks
//timer1 presummed running, running at 256:1 prescaler
void myDelay(uint16_t dly) {
// Set the target value to 62499
OCR1A = TCNT1 + dly - 1; //0xF423;
// Set prescaler to 256 and start the timer
//TCCR1B |= (1 << WGM12) | (1 << CS12);
TCCR1B = (TCCR1B &~0x07) | (TMR1_PS256x & 0x07); //set timer1 prescaler to 256:1
// Waiting for the overflow event
while ((TIFR1 & (1 << OCF1A)) == 0) {
}
TIFR1 |= (1<<OCF1A); //clear the flag
}
ese fragmento de código en acción cuando se alimenta TMR1_PS100ms como parámetro:
el objetivo de escribir cualquier pieza de código es que no tengas que volver a escribirlo. De esa manera, cualquier cosa que escribas es una inversión, no un gasto.
G36
Bence Kaulics
miguel nissen
Andy
PORTD ^= 1 << PD4;
miguel nissen