Estoy escribiendo un programa en STM32F4 Discovery donde tengo que almacenar la dirección del registro CCR del temporizador en un puntero y luego cambiar el registro a través de este puntero, es decir,
volatile uint32_t* tim_ccr_reg = reinterpret_cast<uint32_t*>(TIM4_BASE + 0x34);
// 0x34 = offset of CCR1 register
*tim_ccr_reg = 1999; // Set CCR1 to 1999
Cuando pruebo esto solo en un "programa vacío", funciona, pero cuando uso todo mi programa (junto con todas las demás funciones que implementé) causa una falla en una de esas asignaciones. Ahora estoy averiguando si es mi otro código el que desplaza algo en la memoria o si estoy guardando la dirección de registro de manera incorrecta y solo se muestra cuando se carga un programa más complejo. En la documentación que leí
La forma más sencilla de implementar variables asignadas a la memoria es usar punteros para direcciones fijas.
#define PORTBASE 0x40000000
unsigned int volatile * const port = (unsigned int *) PORTBASE;
El puerto variable es un puntero constante a un volatile sin signo entero, por lo que podemos acceder al registro mapeado en memoria usando:
*port = value; /* write to port */
value = *port; /* read from port */
Este enfoque se puede usar para acceder a registros de 8, 16 o 32 bits, pero asegúrese de declarar la variable con el tipo apropiado para su tamaño, es decir, int sin signo para registros de 32 bits, sin signo corto para 16 bits, y sin firmar char para 8 bits. También debe asegurarse de que los registros asignados en memoria se encuentren en los límites de dirección apropiados, por ejemplo. o bien todos alineados por palabra, o alineados en sus límites de tamaño natural, es decir, los registros de 16 bits deben estar alineados en las direcciones de media palabra (pero tenga en cuenta que ARM recomienda que todos los registros, cualquiera sea su tamaño, estén alineados en los límites de palabra.
Luego fui a ver la documentación de los registros CCR para los temporizadores y dice
ahoranoestoyseguro,¿elregistrosiempreesde32bitsysoloseusan16bitsenalgunostemporizadoresoenalgunoscasosseregistrasolode16bitsytengoqueusarunpunterode16bitsparaescribir¿Qué?
Encualquiercaso,megustaríasabercuáleslaformacorrectadeguardarelregistroCCRdeltemporizadorenunavariable.SihagounsegundoclicenCCR1enelsiguientecomando
TIM4->CCR1=1999;
yhagaclicen"ir a definición" me lleva a un fragmento de código extraño
/** \brief ITM Send Character
This function transmits a character via the ITM channel 0.
It just returns when no debugger is connected that has booked the output.
It is blocking when a debugger is connected, but the previous character send is not transmitted.
\param [in] ch Character to transmit
\return Character to transmit
*/
static __INLINE uint32_t ITM_SendChar (uint32_t ch)
{
if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */
(ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
(ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */
{
while (ITM->PORT[0].u32 == 0);
ITM->PORT[0].u8 = (uint8_t) ch;
}
return (ch);
}
Estoy (muy) confundido.