Tengo un PIC32MX795F512l
y porque XC32
no proporciona una función de retraso incorporada, estoy usando Timer1
para generar un retraso de 1 segundo pero hay un problema porque está generando más de 1 segundo de retraso. ¿Alguien puede ayudar a obtener un retraso exacto de 1 segundo en PIC32?
CÓDIGO:
#define SYSTEM_FREQUENCY 72000000L
void Delayms(unsigned t)
{
OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
while(t--)
{
WriteTimer1(0);
while(ReadTimer1() < SYSTEM_FREQUENCY/256/1000);
}
CloseTimer1();
}
y usarlo en while(1)
int main()
{
SYSTEMConfigPerformance(SYSTEM_FREQUENCY);
while(1)
{
PORTDbits.RD0 = 1;
Delayms(1000);
PORTDbits.RD0 = 0;
Delayms(1000);
}
}
Finalmente diseñé una lógica usando temporizadores que me está dando un retraso de 1 ms:
#define FCY 72000000L
#define FPB 36000000L
#pragma config POSCMOD=XT, FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF
void Delayms( unsigned t)
{
T1CON = 0x8000;
while (t--)
{
TMR1 = 0;
while (TMR1 < FPB/1000);
}
}
No estoy familiarizado con los dispositivos PIC32 y la biblioteca proporcionada por microchip, pero por lo que leí en la guía de la biblioteca periférica, la llamada SYSTEMConfigPerformance(SYSTEM_FREQUENCY);
no establece los relojes reales en 72 MHz, sino que solo selecciona todas las demás características importantes para brindar el máximo rendimiento para 72 MHz ( por ejemplo, estados de espera, cachés, reloj periférico antes del divisor).
Entonces, en su código, la MCU se ejecutará con la configuración de reinicio predeterminada que es (si entiendo correctamente) un reloj FRC interno de 8MHz con un divisor de 2, por lo tanto, 4MHz. Puede intentar verificar esto si lo define SYSTEM_FREQUENCY
y 4000000L
ver si obtiene un retraso de 1 segundo. (actualmente debería ser 18 segundos en lugar de 1)
Si no me equivoco, y realmente desea que su dispositivo funcione a 72 MHz, primero debe configurar sus osciladores:
OSCConfig(OSC_FRC_PLL, OSC_PLL_MULT_18, OSC_PLL_POST_1, OSC_FRC_DIV_2);
Tenga en cuenta que la frecuencia de entrada del PLL no debe exceder los 5 MHz (si lo hice bien), por lo que usará el FRC de 8 MHz, divídalo por 2 ( OSC_FRC_DIV_2
), introdúzcalo en el PLL ( OSC_FRC_PLL
) y multiplíquelo por 18 ( OSC_PLL_MULT_18
) sin divisor posterior ( OSC_PLL_POST_1
). Con un resultado de 72MHz +/- 2% a 25°C (ya que el FRC está calibrado de esa manera).
Como realmente no estoy familiarizado, verifique dos veces esas cosas y no me haga responsable si mata su chip, la primera sugerencia (definir la frecuencia del sistema más baja) debería ser segura.
PLL input frequency should not exceed 5 MHz
que es correcto y la hoja de datos también describió que debería estar entre 4 MHz<FIN<5 MHz
, así que digamos que si tengo un oscilador de 11 MHz, sumergirlo en 2 dará 5.5
más de 5 MHz y si lo dividimos entre 3, dará 3.6
lo que está debajo que 4MHZ. Entonces, según usted, será una buena configuración para esto. Lo estoy buceando a las 3 y funciona bien, pero solo quiero confirmarlo.Espero que esto ayude.
#define CCLK (80000000L) // system clock
#define PBCLK (CCLK / 2) // peripheral bus clock
#define CCLK_MS (PBCLK / 1000) // used for millisecond delay
void delay_ms(const int32_t& wait_ms) {
auto startTime = ReadCoreTimer();
auto delayCount = wait_ms * CCLK_MS;
while (ReadCoreTimer() - startTime < delayCount)
;
}
Si no puede pagar llamadas de función a ReadCoreTimer(), use _CP0_GET_COUNT() en su lugar. Es una macro dentro de las bibliotecas plib.
No soy un programador de PIC, pero estoy seguro de que la demora se debe a:
Puedes hacer algunos experimentos (como hice en AVR o MCS-51):
Ejecute delay_s(1000). Usa tu cronómetro (muchos smartphones lo tienen) para medir la duración requerida en segundos. Registre esta duración como T. Para el primer experimento, T debe ser alrededor de 1000 (>1000) pero no exactamente 1000
Reemplace SYSTEM_FREQUENCY/256/1000 en su código con SYSTEM_FREQUENCY/256/T
Si el retraso total es un poco más de 1 segundo, es simplemente que el tiempo adicional se toma realizando el ciclo calculado 1000 veces. ¿No podrías calcular el número exacto de tics de reloj durante 1 segundo y tener un solo ciclo?
Después de que su actualización indique que está demorando más de 10 segundos, le sugiero que verifique que el reloj esté funcionando a la velocidad que cree.
Está calculando los ticks del reloj (después del prescaler) para 1 ms - SYSTEM_FREQUENCY/256/1000, multiplíquelo por 1000 para dar ticks de 1 s, entonces SYSTEM_FREQUENCY/256
Júnior
gbarry
Aeronave
Arsenal
Aeronave
Arsenal
Aeronave