Forum: Mikrocontroller und Digitale Elektronik ADUc7061 Sendet nicht grundsätzlich


von Kahn P. (Gast)


Lesenswert?

Hallo lieber Leser,

erstmal vorweg kleines sorry für die riesen Codemasse, aber
so kann ich untermalen was ich genau meine.

Die Aufgabe:

An einem Mikroskop mit Handrad befindet sich ein optischer 
Inkrementalgeber, der je nach Drehgeschwindigkeit bis zu
10Khz TTL Pulse emitieren kann.

Im ADCU7061/60  liegt diese Flanke am IO an, zusätzlich
löst der Io Flankenwechsel einen IRQ aus, dabei wir der Timer0
Gestartet, wenn dieser bei unterlauf des Zählstandes X einen
selbst einen weiteren IRQ auslöst, und das Externe Signal noch immer 
steht zb. nach 800[ns], wird ein Zähler Inkrementiert, und der Timer 
abgeschaltet, so das sich das Spiel wiederholen kann.

Fazit: (jetzt kommts)
Am Serialport, sendet ein externer PC ein Commando (string), das den
Sollwert überträgt, bei welchem Inkrement ein anderer IO Output
für eine kurze Schwellzeit High geht, um eine Kamera zu triggern.
(Stichwort DeepFokusStacking)


Frage:
Wenn alles soweit funktioniert, warum scheint dann manchmal der
Empfang nicht zu funktionieren, oder der Serialport Sendet
gelegentlich nicht? Geht aber ein Ext. IO Interrupt ein(Handrad),
und der timer 0 wird wie oben gestartet, dann plötzlich sendet und 
empfängt der UART wieder gut.

"Der" bleibt also quasi hängen, und macht dann fröhlich weiter
wenn ein IRQ des Inkrementalgeber "mal" eintrifft, falls wer am Handrad 
dreht. Zu ca 11% ist es so, das ohne externe IRQs der Serial 
Empfang/Sendung erst wieder funktioniert wenn ein Ext.io. IRQ einläuft.

Ja sorry anders konnte ich die Umstände nicht Darstellen.

Vielen Dank für Hinweise
 Karsten Schulz

1
//initalize controller
2
void InitController(void)
3
{
4
  POWKEY1 = 0x1;
5
  POWCON0 = 0x78;                //Set core to max CPU speed of 10.24Mhz
6
  POWKEY2 = 0xF4;
7
8
    //uart config 115200 Baud
9
  GP1CON  = BIT0|BIT4;      //Select UART functionality for P1.0/P1.1
10
  COMCON0 = BIT7;              //Enable access to COMDIV registers
11
  COMDIV0 = 0x2;              //Set baud rate to 115200
12
  COMDIV1 = 0x00;
13
  COMDIV2 = 0x31C|BIT11|BIT15;    //Enable fractional divider for more accurate baud rate setting
14
  COMCON0 = BIT0|BIT1;          //Word length 8 bits, no Parity bit, one Stop bit
15
  COMIEN0 = BIT0;//|BIT|BIT3;      //Enable UART interrupts when Rx full and Tx buffer empty and Modem Status Interrupt
16
    FIQEN   = BIT11;            //set UART interrupt as fast
17
18
  //IO IRQ
19
  GP1DAT  = BIT29|BIT30;          //P1.5, P1.6 set as Output 
20
  IRQCONE = BIT5;                  //GPIO_IRQ2 trigger on Rising edge
21
  IRQEN   = BIT18|BIT13|BIT3;     //Enable Timer 0, IRQ0 & IRQ2 Interrupt
22
   
23
  //timer
24
  T0CON   =  BIT7|BIT10|BIT16|BIT17;// Enable Timer0  10.24MHz 
25
26
    //Flash Mem 
27
  FEEMOD = BIT3;              //Flashmem config bit 3 should be set to allow erase/write
28
  //Erase(0xE000);            //erase page 120
29
  //Erase(0xF000);            //erase page 120
30
  //Erase(0xF200);            //erase page 121
31
  //Erase(0xF400);            //erase page 122
32
  
33
  
34
  //Wait(100);     
35
}
36
37
//emit to UART
38
void Send(char *pStr)
39
{
40
  while(*pStr)
41
  {
42
      while ((COMSTA0&0x40) == 0x00);
43
    COMTX = *pStr++;
44
  }
45
}
1
#include <ADuC7060.H>
2
#include "global.h"
3
#include "functions.h"
4
5
#pragma pack(push,1)//byte alignment for flashmem
6
#pragma pack(pop)
7
8
#include "stdio.h"
9
#include "stdlib.h"
10
#include "string.h"
11
#include "float.h"
12
#include "math.h"
13
      
14
#define FLKLEN 200
15
#define TINTERV(ms) ((32768.0/1000.0) * ms)
16
17
#pragma pack(push,1)//byte alignment for flashmem
18
typedef struct prcdat
19
{
20
DWORD   dwCount;
21
DWORD   dwMaxCnt;
22
DWORD   dwTrigger;
23
DWORD   na;
24
}PRCDAT;
25
#pragma pack(pop)
26
27
PRCDAT  g_dat = {0,10,0};
28
29
//UART data
30
BYTE    g_bRxBuffLen    = 0; 
31
BYTE    g_bRx           = 0;  
32
char    g_cRxBuff[256];  
33
34
void HandleUserInput(char *pRxBuff);
35
36
char tempbuff[255];
1
int main(void)
2
{
3
    InitController();
4
5
  LoadFlash(ADR_PAGE2,&g_dat,sizeof(PRCDAT));
6
7
  sprintf(&tempbuff[0],"ADuC7061 Init Succs INTERVAL=%d\r\n",g_dat.dwMaxCnt); Send(&tempbuff[0]); 
8
9
  while(1)
10
  {  
11
      if(g_bRx) //Serial(irq) ready
12
    {    
13
       g_bRx = FALSE; 
14
         HandleUserInput(&g_cRxBuff[0]);//check user input and save to flash  
15
    }
16
17
18
    if(g_dat.dwCount >= g_dat.dwMaxCnt)
19
    {
20
      g_dat.dwCount   = 0;
21
      g_dat.dwTrigger = FLKLEN; //HighDownCounter
22
      GP1DAT |= (BIT21|BIT22); //LED ON 
23
24
      //sprintf(&tempbuff[0],"%d\r\n",g_dat.dwCount); Send(&tempbuff[0]);   
25
    }
26
27
    if(g_dat.dwTrigger > 0)
28
    {
29
      if(--g_dat.dwTrigger < 1)
30
      {
31
         GP1DAT &= ~(BIT21|BIT22); //LED OFF
32
      }
33
    }   
34
  }
35
}
1
   
2
void IRQ_Handler(void) __irq     
3
{
4
     DWORD irqsta = IRQSTA;
5
6
   if((irqsta & BIT13) == BIT13)  //External Interrupt0 source -IRQ  
7
   {     
8
        IRQCLRE = BIT13;       //reset irq  
9
    T0CLRI  = 0x00;          //reset timer
10
    T0LD    =  FLKLEN;       //set Timer0 count down
11
   }
12
13
   if((irqsta & BIT3) == BIT3) // Timer 0 underflow 
14
   {    
15
     IRQCLRE = BIT3;           //reset irq
16
     T0CLRI  = 0x00;            //reset timer     
17
     g_dat.dwCount++;
18
   }  
19
}
1
void FIQ_Handler(void) __irq
2
{
3
  DWORD ucFIQSTA  = FIQSTA;
4
  DWORD ucCOMIID0 = COMIID0;            //Read the UART IRQ ID register
5
  DWORD ucCOMSTA1 = COMSTA1;
6
7
  if ((ucFIQSTA & BIT11) == BIT11)    //UART interrupt source
8
  {
9
     if((ucCOMIID0 & 0x1) == 0x1)
10
         ;    //Receive buffer Full
11
 
12
    if((ucCOMIID0 & 0x2) == 0x2)
13
         ;    //Transmit buffer empty
14
15
    if((ucCOMIID0 & 0x4) == 0x4)  //recieve PC Command
16
    {
17
      char crx = toupper((char)COMRX);
18
 
19
      if(crx == '\r') //Enter found Command like: INTERVAL=10\r"
20
      {
21
       g_cRxBuff[g_bRxBuffLen] = 0,
22
       g_bRxBuffLen = 0,
23
       g_bRx = 1; //string after LF ready
24
      }else g_cRxBuff[g_bRxBuffLen++] = crx;                                                                                                                                                                                                                                                                                         COMRX;        // read COMRX register
25
    }
26
  }
27
}


[c]
void HandleUserInput(char *pRxBuff)
{
  //split string left and right part of operator equal
  if(pRxBuff && strlen(&pRxBuff[0]))
  {
    register char *left=strtok(pRxBuff,"="),*right=strtok(NULL,"=");
    if(left && right)
    {
     if(!strcmp(left,"INTERVAL"))
     {
       g_dat.dwCount  = 0;
       g_dat.dwMaxCnt = atol(right);

       SaveFlash(ADR_PAGE2,&g_dat,sizeof(PRCDAT));
     }
    }

    sprintf(&tempbuff[0],"INTERVAL=%u\r\n",g_dat.dwMaxCnt);
    Send(&tempbuff[0]);
  }
}
[\c]

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.