No puedo encontrar una solución por la cual el reloj STM32F427ZIT6 cambia durante la operación. Estoy usando un cristal externo de 8 Mhz.
¿Debo buscar un error en el software o hardware?
Tengo un pequeño código, que solo alterna los LED en el tablero con GPIO. A veces se alternan con la velocidad correcta, como se define en el software. He visto 3 velocidades diferentes, 2 de ellas están en el video de abajo y la tercera velocidad está entre ellas. Realmente está en mal estado. Y sucederá en momentos aleatorios. A veces es rápido cuando está encendido, a veces lento ...
Parámetros en este momento para sysclock:
#define HSE_VALUE ((uint32_t)8000000)
#define PLL_M 8
#define PLL_N 360
#define PLL_P 2
También intenté poner PLL_P en 4 para reducir el reloj. Sigue igual.
EDITAR: Medí CAN con un analizador lógico y al principio envía datos con 1 Mbits según sea necesario, pero luego cae a 113 kbits cuando los LED comienzan a parpadear más lentamente. CAN es impulsado por el reloj APB1.
EDIT2: Creo que he encontrado la causa del problema: el cristal. No hice ningún cambio en el código. Desoldé el cristal de 8 Mhz y medí CAN y SPI con un analizador lógico usando un reloj interno. Todas las mediciones parecieron estar bien para muchas pruebas, así que soldé un nuevo cristal de 8 Mhz en el tablero. Hasta ahora tan bueno. No he visto ningún comportamiento extraño desde entonces.
Código completo:
pastebin.com/6jwYFVPB - main.c
/* Includes */
#include "stm32f4xx.h"
#include "gpio.h"
#include "uart.h"
#include "can.h"
UART debug;
/* Private macro */
/* Private variables */
/* Private function prototypes */
/* Private functions */
/**
**===========================================================================
**
** Abstract: main program
**
**===========================================================================
*/
int main(void)
{
gpio_initialize();
//UART_init(&debug, USART1_PA9_PA10, 9600, 64, 2048); //UART variable is defined in debug.h to make it global.
//uart_putline(&debug, "BMS has started.");
CAN_init(CAN_PINS_GPIOA);
int i = 0;
//char msg2[512];
/**
* IMPORTANT NOTE!
* The symbol VECT_TAB_SRAM needs to be defined when building the project
* if code has been located to RAM and interrupts are used.
* Otherwise the interrupt table located in flash will be used.
* See also the <system_*.c> file and how the SystemInit() function updates
* SCB->VTOR register.
* E.g. SCB->VTOR = 0x20000000;
*/
/* TODO - Add your application code here */
/* Infinite loop */
//uart_putline(&debug, "Entering loop:");
CAN_message msg;
msg.id = 0x303;
msg.data_or_request = CAN_RTR_DATA_FRAME;
msg.standard_or_extended = CAN_IDE_STANDARD;
msg.length = 8;
msg.data[0] = 0x00;
msg.data[1] = 0x01;
msg.data[2] = 0x02;
msg.data[3] = 0x03;
msg.data[4] = 0x04;
msg.data[5] = 0x05;
msg.data[6] = 0x06;
msg.data[7] = 0x07;
while (1)
{
// if (uart_inbox_count(&debug) > 0) {
// uart_getstr(&debug, msg2);
// //echo that message back
// uart_putline(&debug, msg2);
// }
for (i=0;i<500000;i++);
//gpio_toggle_output(GPIO_MCU_OK);
CAN_transmit(msg);
gpio_toggle_output(GPIO_BMS_ERR_LED);
gpio_toggle_output(GPIO_CUR_OK);
gpio_toggle_output(GPIO_UART_OK);
}
}
pastebin.com/sf1FM9T7 - gpio.h
pastebin.com/rqiBTQ4c - gpio.c
pastebin.com/xE6zcPEg - can.h
pastebin.com/DSTHMRcz - can.c