La función no funciona probablemente como se esperaba, utilizando MCU TM4C123

0

Estoy intentando generar un Reloj sincronizado con datos, donde la frecuencia del reloj debe ser el doble de la frecuencia de los datos. Escribí un código para este propósito y funciona bien para 32 bits de datos, algo más que 32 generará un montón de 1s. Esto es lo que obtuve para datos de 64 bits = (0XAAAAAAAAAAAAAAAA):

Aquí está el código que escribí:

  void DATA(unsigned long  int number, int iteration){   //number: data to be send serially
                                                       // iteration: number of bits to send
  unsigned long  int x=0;         //An integer to hold each bit from the data                      
  char even = (char)0x1; 
  TIMER1->ICR |= (1<<0);
  for(int y=0; y<=iteration;) {
     while((TIMER1->RIS & 0x00000001) != 1){}   //wait until Timer1 times out
      TIMER1->ICR |= (1<<0);     //Reset Timer1 flag
      odd ^= (char)0x1;         
      GPIOC->DATA ^= (1<<7);     //Toggle the clock at PC7
      if (odd) continue;        // data change every even cycle
      x = number & (0x01UL << y);      //Get each bit individually  
      if(x==(0x01UL<<y))           //If bit is 1
          GPIOC->DATA |= (1<<6); //Make C6 High 
      else if(x==0X0)            //If bit is 0
          GPIOC->DATA &= ~(1<<6);//Make C6 Low
      y++;
  }
  }

  int main(){ 
     DATA(0XAAAAAAAAAAAAAAAA,64);//
   }

Nota: He intentado hacer que el número en mi función sea largo int largo, y eso no resolvió el problema también. ¿Hay alguna explicación para obtener esos 1 después de los primeros 32 bits?

    

2 respuestas

2

Solo como referencia, así es como codificaría su función:

// number: data to be send serially
// iteration: number of bits to send
void DATA (unsigned long int number, int iteration)
{
  while (iteration--) {
    TIMER1->ICR |= (1<<0);       //Reset Timer1 flag
    while (!(TIMER1->RIS & 0x01)){} //wait until Timer1 times out
    GPIOC->DATA |= (1<<7);       //Toggle the clock at PC7 high

    if (number & 0x01)           //If bit is 1
      GPIOC->DATA |= (1<<6);     //Make C6 High 
    else                         //If bit is 0
      GPIOC->DATA &= ~(1<<6);    //Make C6 Low
    number >>= 1;

    TIMER1->ICR |= (1<<0);       //Reset Timer1 flag
    while (!(TIMER1->RIS & 0x01)){} //wait until Timer1 times out
    GPIOC->DATA &= ~(1<<7);      //Toggle the clock at PC7 low
  }
}

Tenga en cuenta que todas sus variables internas son completamente innecesarias. También he desenrollado el bucle para hacer explícita la polaridad de los bordes del reloj.

EDITAR: para poder enviar cantidades arbitrarias de datos, una función que acepte una matriz de bytes probablemente sería más útil:

// p: pointer to data to be sent serially
// n: number of bytes to send
void data_str (unsigned char *p, int n)
{
  while (n--) {
    char c = *p++;
    int i;

    for (i=0; i<8; ++i) {
      TIMER1->ICR |= (1<<0);       //Reset Timer1 flag
      while (!(TIMER1->RIS & 0x01)){} //wait until Timer1 times out
      GPIOC->DATA |= (1<<7);       //Toggle the clock at PC7 high

      if (c & 0x01)                //If bit is 1
        GPIOC->DATA |= (1<<6);     //Make C6 High 
      else                         //If bit is 0
        GPIOC->DATA &= ~(1<<6);    //Make C6 Low
      c >>= 1;

      TIMER1->ICR |= (1<<0);       //Reset Timer1 flag
      while (!(TIMER1->RIS & 0x01)){} //wait until Timer1 times out
      GPIOC->DATA &= ~(1<<7);      //Toggle the clock at PC7 low
    }
  }
}

// Send 128 bits (16 bytes) of data.
data_str ("\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", 16);

Ahora necesitamos dos variables temporales: c retiene los datos para que no modifiquemos realmente la matriz de la persona que llama, y i se usa como contador para el bucle interno. Tenga en cuenta que los bytes se envían de izquierda a derecha, pero cada byte se envía primero en LSB.

    
respondido por el Dave Tweed
1

Creo que el problema está en la línea

X = number & (0x01 << y);

El problema es que el resultado de 0x01 << y es un entero porque 0x01 cabe en uno. Cambia esto para leer

X = number & (0x01UL << y);

También debes cambiar cada long a un unsigned long para evitar problemas con los valores de 64 bits.

    
respondido por el DoxyLover

Lea otras preguntas en las etiquetas