www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR + 74HC165 + UART


Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin, ich habe mal ein bisschen was zusammengetipselt und habe nun das 
Problem, daß ich über UART nur was empfange, wenn ich den Schalter (mit 
Pull UP) am D7 des SR verändere.
Alle anderen Schalter ergeben keine Reaktion.
Ich habe zum testen mal nur ein SR angehängt, dessen Serial In mit Masse 
verbunden.
Wenn ich jetzt Schalter 7 umstelle, dann wird der gesamte 16-Byte-Satz 
den ich empfange komplett 1 oder komplett 0.
Ich schätze daß irgendwas am umschalten Shift/Load oder so nicht 
hinhaut.
Vllt hat da jemand den Durchblick und schaut sich das kurz an?
LG
unsigned char   Data_to_send[17], 
        Data_to_send_old[17], 
        Data_output[16],
        Data_output_old[16],
        Data_received[16], 
        Number_of_bytes_RXD=0, 
        Type_of_bytes_RXD=0, 
        receive_type=0,
        receive_count=0;

#define Pin_Input       ((PINC & (1<<PINC0)) != 0 ? 1 : 0) //PIN C0 ist der Input Pin für das Input-Schieberegister
#define Input_Clock     1      //PIN C1 als Clock am Input Register
#define Input_Load_Shift   2      //PIN C2 als Load-Shift Wähler
#define Pin_Output      3      //PIN C3 als Output Pin für das Output Schieberegister
#define Output_Clock    4      //PIN C4 als Clock am Output Register
#define Output_Shift_Load  5      //PIN C5 als Shift-Load Wähler


//*******************************************//
//****************Hauptschleife**************//
//*******************************************//

int main(void)    
{
wdt_disable();  //Watchdog timer sicherheitshalber nach einem WDT-reset wieder deaktivieren
DDRC |= (1<<Input_Clock) | (1<<Input_Load_Shift) | (1<<Pin_Output) | (1<<Output_Clock) | (1<<Output_Shift_Load);//DDRC Setzen
sei();      //Interrupts Global zulassen
USART_Init(MYUBRR); //UASRT initialisieren (mit 9200 baud, 2 Stop)
UCSRB |=(1<<RXCIE); //Das UART_RXD_Complete Complete Interrupt zulassen
receive_count=0;

USART_Transmit('S');//S für Startup senden

for(;;)
  {
  Read_Inputs();
  if (memcmp(Data_to_send,Data_to_send_old,17))      //Vergleichen, ob sich was geändert hat
      {
        Send_To_PC(Data_to_send);          //wenn ja, dann an PC senden
        memcpy(Data_to_send_old, Data_to_send, 17);  //Und als "gesendet" ablegen
        Data_to_send_old[17]=0x00;          //Das "Mogelbyte" zurücksetzen
        Data_to_send[17]=0x00;            //hier auch
      }

// if (memcmp(Data_output,Data_output_old,16))
//    {
//       Write_Outputs();  //wenn neue output-daten, dann erneuern
//       memcpy(Data_output_old, Data_output, 16);//Output_old setzen
//    }
  }
}

//*******************************************//
//****************Deklarationen**************//
//*******************************************//


//********************************************//
//**Daten vom Input-Schieberegister einlesen**//
//********************************************//

//PORT C steuert das Schieberegister:
//PIN C0 als Input an Serial out QH
//PIN C1 als Clock
//PIN C2 als Parallel Load/Shift schalter am Register (0=Load, 1=Schieben) 

int Read_Inputs(void)
        
  {
    int i=0;
    int a=0;
    PORTC &= ~(1<<Input_Load_Shift);  //Low setzen damit geladen wird
    PORTC |= (1<<Input_Load_Shift);    //und wieder High


    while (a <16)
      {
        while(i<8)
        {  
          Data_to_send[a] &= ~(1<<i);      //BIr erst löschen
          Data_to_send[a] |= ((Pin_Input)<<i);//und 1 oder 0 setzen
          PORTC |= (1<<Input_Clock);       // Clock Flanke erzeugen um Register um eine Stelle zu schieben
          PORTC &= (0<<Input_Clock);       //Clock wieder löschen
          i++;                   //i erhöhen
        }
        i=0;                  //i löschen
        a++;                  //a erhöhen
      }

  }





//*******************************************//
//***********Daten an PC senden**************//
//*******************************************//

int Send_To_PC(unsigned char data[])
  {
    int i=0;
    while(i<16)              //bis alle Inhalte gesendet sind
    {
      USART_Transmit(data[i]);    //schickte je einen array-inhalt raus
      i++;              //erhöhe i
    }

  }

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Phillip Hommel wrote:

>
>           PORTC &= (0<<Input_Clock);       //Clock wieder löschen
> 

Wat dat denn?


Peter


P.S.:
- Funktionen ohne Returnwert als void
- nicht unnötig Speicherplatz verschwenden (Zähler bis 16 müssen kein 
int sein, da reicht unsigned char).

Autor: helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe deine einlese Routine mal ein bisschen umgeschrieben.
Ist dadurch etwas kürzerer Code und etwas einfacher zu lesen.

Bitte probier es mal aus ob es klappt

Gruss Helmi

int Read_Inputs(void)
{
    int i;
    int a;

    PORTC &= ~(1<<Input_Load_Shift);  //Low setzen damit geladen wird
    PORTC |= (1<<Input_Load_Shift);    //und wieder High


  for(a=0;a<16;a++)
    for(i=0;i<8;i++)
    {
      Data_to_send[a] <<=1;
      if(PINC & (1<<PINC0)) Data_to_send[a] |= 1;
      PORTC |= (1<<Input_Clock);       // Clock Flanke erzeugen um 
Register um eine Stelle zu schieben
      PORTC &= (0<<Input_Clock);       //Clock wieder löschen
     }

}

Autor: helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korregierter Code

void Read_Inputs(void)
{
    unsigned char i,a;

    PORTC &= ~(1<<Input_Load_Shift);  //Low setzen damit geladen wird
    PORTC |= (1<<Input_Load_Shift);    //und wieder High


  for(a=0;a<16;a++)
    for(i=0;i<8;i++)
    {
      Data_to_send[a] <<=1;
      if(PINC & (1<<PINC0)) Data_to_send[a] |= 1;
      PORTC |= (1<<Input_Clock);       // Clock Flanke erzeugen um 
Register um eine Stelle zu schieben
      PORTC &= ~(1<<Input_Clock);       //Clock wieder löschen
     }

}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
helmi wrote:
> Ich habe deine einlese Routine mal ein bisschen umgeschrieben.

und den Fehler drin gelassen.


Peter


P.S.:
Mit Bitfeldern wär das nicht passiert:
Beitrag "Schieberegister-LCD vereinfachen"
15. Beitrag.

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit den Bitfeldern muß ich mir nochmal genauer zu Gemüte führen, ich 
verstehe es grade noch nicht.
Was aber den alten Text angeht: die PORTC &= (0<<Input_Clock);  war 
natürlich totaler Humbug, mit der Korrektur funzt es wunderbar...schön 
wenn Probleme so leicht gelöst werden können ;)

>Funktionen ohne Returnwert als void

Wie genau?
void Read_Inputs(void) 
{
(...)
}

gibt ne Fehlermeldung im Compiler...

Autor: Helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du must dem Compiler an anfang einen sogenannten Prototype deiner 
Funktion mitgeben.

Bevor du eine Funktion aufrufst in deinem Programm must dem Compiler 
bekannt sein wie die Funktion aussieht.

Dazu gibt es 2 Moeglichkeiten.

1. Du stellst deine Funktion im Source Code vor dem 1. Aufruf.
   also so:
   void Read_Inputs(void)
   {
      blabla;
   }
   void main(void)
   {
     Read_Inputs();
   }


2. oder du Definierst deine Funktion am Anfang deines Programms

   void Read_Inputs(void);

   void main(void)
   {
      Read_Inputs();
   }

   void Read_Inputs(void)
   {
     blabal;
   }

So weiss der Compiler vor dem 1. Aufruf der Funktion wie der 
Rueckgabewert uebergeben wird. Wenn du es nicht machst nimmt er als 
default wert den Rueckgabetype int an.

Normal wird die Methode 2 benutzt. Diese Prototype kannst du dann in 
einer Headerdatei legen und koennen dann auch in anderen Programmmodulen 
benutz werden.

Gruss Helmi

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aaaaah, so geht das, jetzt versteh ich auch manche Quelltexte bei denen 
ich genau das schon ein paar mal gesehen habe.
Mal ausprobieren wieviel Platz das spart.
Muß eigentlich in einer Headerdatei was bestimmtes drinstehen? 
Bestimmtes Format oder sowas? Oder durchsucht er diese Dateien einfach 
als wäre es ein Teil vom "Haupt-Quelltext"?

Autor: Helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein er durchsucht sie wie der Haupttext
wird ja auch nur ueber Include eingebunden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.