Los escenarios más probables son que el chip ha sufrido algún daño, cuyos efectos visibles incluyen escamosa de pull-up de comportamiento, o de lo que el código es para cualquiera que sea el motivo de la pullups a querer ser a veces habilitado y, a veces, movilidad. La última situación puede surgir si la principal línea de código hace algo como:
WIDGET_PIN_PORT->PULLUPS |= WIDGET_PIN_PULLUP_MASK;
y una interrupción hace algo como:
GADGET_PIN_PORT->PULLUPS |= GADGET_PIN_PULLUP_MASK;
donde WIDGET_PIN y GADGET_PIN son diferentes bits en el mismo puerto de e/S. La principal línea de código se va a traducir en algo así como
ldr r0,= [[address of port pullup register]]
ldr r1,[r0] ; ***1
orr r1,#WIDGET_PIN_PULLUP_MASK
str r1,[r0] ; ***2
Si una interrupción ocurre después de la ***1
pero antes de ***2
, luego GADGET_PIN la subida va a conseguir encendido por la interrupción, pero, a continuación, obtener erróneamente desactivado por la principal línea de código. Hay dos formas de evitar este problema:
(1) Hacer uso de hardware que puede permitir un poco de la de pull-up de registro de establecer mediante una única instrucción en lugar de una lectura-modificación-escritura de la secuencia. Creo que todos los Cortex-M3-controladores basados en proporcionar un "bit de bandas", característica que puede ser utilizada para este propósito, a pesar de que aún tengo que encontrar alguna manera agradable de usar desde el código escrito en C otros de forma manual la definición de los bits de bandas de direcciones. Algunos otros procesadores pueden tener de e/S-puerto-medios específicos para lograr una tarea similar.
(2) Deshabilitar las interrupciones durante el puerto de leer-modificar-escribir la secuencia. Por ejemplo, reemplazar el anterior código C con una llamada a un método
void set32(uint32_t volatile *dest, uint32_t value)
{
uint32_t old_int = __get_PRIMASK();
__disable_irq();
*dest = *dest | value;
__set_PRIMASK(old_int);
}
Este código hará que las interrupciones se discapacitados, muy brevemente (probablemente unos 5 instrucciones); que la breve suficiente para que no cause problemas incluso con relativamente de tiempo crítico interrupciones. Tenga en cuenta que compilar el método anterior como en línea puede reducir el tiempo necesario para llamar, pero podría aumentar la cantidad de tiempo en el que las interrupciones están deshabilitadas [por ejemplo, si el optimizador sucede a reorganizar el código para la instrucción en el que se carga la dirección de la dest
no ocurre hasta después de que __deshabilitar_irq()].
Dado que dicen que el pull-up comportamiento es intermitente, creo que un problema de código es más probable que un problema de hardware. Además, dañando a las condiciones que dañan a los de pull-up de circuito sería susceptible de causar otro daño en el chip, así como, algunos detectable y algunos no. Si cualquier tipo de demostrable de daños en el hardware se produce a un chip, casi siempre es mejor a la basura el chip y reemplazarlo con uno nuevo, que a la esperanza de que el daño observado es el "único" problema.