Msp430 Launchpad usando el motor para controlar el motor

2

Puedo parpadear el led, pero el tiempo es de 1 segundo o 2 segundos. Intento aumentar pero no lo hice. Pero mi pregunta estoy usando el controlador del motor L293D para controlar los motores. Quiero que los motores Dc giren cuando botón cambió 15 segundos. Este es mi código, pero no puedo encontrar una solución. Le estoy preguntando cómo aumentar el tiempo

#include "io430.h"
void delay(unsigned long int d)
{
  d*=9999999999999999;
  for(;d>0;d--);
}
void main(void)
{

  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

P1DIR = BIT6 + BIT4  + BIT7 + BIT0;          // Toggle P1.0 using exclusive-OR
P1DIR &= ~BIT3;
if((P1IN&BIT3) == 0){ 
P1OUT |= BIT6 + BIT4  + BIT7;
}
else
{
 P1OUT |= BIT0;
delay(9000);
}
}
    
pregunta Cenk

3 respuestas

2

Mi sugerencia sería deshacerse de la función de retardo y utilizar la función incorporada si está utilizando IAR o CCS. "__ delay_cycles (ciclos);" El uso de los complementos integrados le dará más resultados predecibles y una mejor sincronización. Probablemente podría simplemente reemplazar su demora por la incorporada, para acercarse más a los resultados que está buscando.

personalmente, me ocuparía de todo esto utilizando interrupciones y temporizadores para arrancar todo y usar los periféricos que tiene el msp430. Yo sugeriría usar el WDT como un temporizador de intervalo, ya que esto dejaría el otro temporizador para el control de su motor. p1.3 se utiliza como pin de activación y p1.0 es el pin led.

código de ejemplo

volatile int counter;
void main(void) {
    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    P1DIR = 0x01;                             // P1.0 output, else input
    P1OUT =  BIT3;                            // P1.3 set, else reset
    P1REN |= BIT3;                            // P1.3 pullup
    P1IE |= BIT3;                             // P1.3 interrupt enabled
    P1IES |= BIT3;                            // P1.3 Hi/lo edge
    P1IFG &= ~BIT3;                           // P1.3 IFG cleared
    _BIS_SR(GIE);
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
    WDTCTL = WDT_MDLY_64; //enables intervals of 64mS
    IE1 |= WDTIE;  // set WDT interrupt
}
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
    ++counter;
    P1OUT |= BIT0;
    if (counter == 245) {  //245 x 64mS = 15.6 seconds
        P1OUT &= ~BIT0;
        WDTCTL = WDTPW + WDTHOLD; 
    }
}

No está completo ni se ha probado este código, pero debe encender el led durante 15 segundos cada vez que se presiona el botón P1.3.

    
respondido por el jsolarski
0

Ese "d * = 9999 ..." parece sospechoso. Esa cantidad de nueve veces 9000 es 0xE100 3B28 D927 DCD8 hex - 64 bits. No sé qué sizeof(unsigned long int) * CHAR_BIT evalúa en MSP430 pero en la mayoría de los sistemas es 32. En otras palabras, estaría desbordando la variable. Por lo tanto, si asumimos que un int largo sin firmar es de 32 bits, el valor que usa su código es D927 DCD8.

¿Está recibiendo una advertencia del compilador sobre el truncamiento?

Una buena forma de experimentar con los bucles de retardo es con una búsqueda binaria. Comience el valor en 0x1. Eso no funcionará (por supuesto), así que muévase a 0x2, 0x4, 0x6, 0x10 ... cada valor duplica el anterior. Si es demasiado lento, retroceda y comience a configurar los bits de orden inferior, pero de arriba a abajo. Una vez que alcanza 0x8000 0000 (nuevamente, suponiendo que tiene una longitud de 32 bits), solo se duplica una vez más si establece cada bit de orden inferior, por lo que, a menos que esté cerca, debe pensar en usar dos retardos (bucle anidado).

    
respondido por el John Lopez
0

Si está utilizando el oscilador incorporado, no necesita retrasar tanto tiempo durante 15 segundos. En un bucle for ajustado, creo que una demora de 15 segundos está más cerca de 1500000 bucles. Además, no puedes multiplicar por un número tan grande.

Creo que el otro problema es con su declaración if/else . Está usando | = en ambos casos, por lo que cuando presiona el botón, no está alternando los bits: BIT0, BIT4, BIT6 y BIT7 eventualmente serán altos. Si puede proporcionar más información sobre lo que está haciendo con todos los bits, y tal vez un diagrama de circuito, eso me ayudará a ayudarlo más.

EDITAR - Para abordar la parte de implementación de retraso de su pregunta, jsolarski ciertamente tiene la mejor solución para el temporizador. Lo examiné un poco más ya que no he usado los temporizadores con el MSP430, y terminé con algunas preguntas propias. Pondré mis hallazgos aquí solo por el bien de la discusión, y espero que jsolarski pueda agregar comentarios donde sea apropiado.

Tienes varias fuentes de reloj central, que incluyen LFXT1CLK, XT2CLK, DCOCLK y VLOCLK. Personalmente, usaré una fuente de reloj interna para mi aplicación y probaré VLOCLK primero.

Una vez que haya seleccionado una fuente de reloj, ahora tiene que determinar dónde se originarán otras tres fuentes de reloj generadas internamente. Estos otros tres relojes son ACLK, MCLK y SMCLK. Convenientemente, VLOCLK es una fuente de reloj válida para los tres. También puede establecer un preescalador para estos relojes, en caso de que no necesite una sincronización de alta velocidad.

Querrá configurar el WDT para usar el modo de intervalo a través de WDTTMSEL. Esto también requiere que establezca un bit WDTIE en IE1. También querrá configurar la fuente de su reloj a través de WDTSSEL y el prescaler a través de WDTISx.

No pude averiguar a qué equivale WDT_MDLY_64 , en función de sus números, pero se espera que no hayas especificado qué fuente de reloj pretendes usar.

Esperamos que esta edición a mi respuesta te haya dado más información sobre cómo configurar el WDT para intervalos, en caso de que decidas intentarlo. Sin embargo, creo que su problema es más fundamental como lo indicó mi respuesta original, con respecto a su uso de |= , y si usa un ciclo o intervalos ajustados de for , simplemente no funcionaría.

    
respondido por el Dave

Lea otras preguntas en las etiquetas