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]