Hallo,
Fuer Testzwecke moechte ich einfach einen String von 1 und 0 auf einem
I/O Port meines MSP430 ausgeben. Jedes Bit soll 10us lang sein.
Zuerst setze ich die clock frequency auf 16 MHz:
1 | DIRECT_SET_BIT(CSCTL0_H, CSKEY >> 8);
|
2 | DIRECT_SET_BIT(CSCTL1, DCOFSEL_4 | DCORSEL);
|
3 | DIRECT_SET_BIT(CSCTL2, SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK);
|
4 | DIRECT_SET_BIT(CSCTL3, DIVA__1 | DIVS__1 | DIVM__1);
|
5 | CLR_BIT(CSCTL6, MODCLKREQEN | SMCLKREQEN | MCLKREQEN);
|
6 | SET_BIT(CSCTL6, ACLKREQEN);
|
Danach setze ich meinen I/O port auf Ausgang und definiere statisch
bits:
1 | #define BIT_0 CLR_BIT(PIN_TX_OUT, PIN_TX);\
|
2 | NOPx40;\
|
3 | NOPx40;\
|
4 | NOPx40;\
|
5 | NOPx35;
|
6 |
|
7 | #define BIT_1 SET_BIT(PIN_TX_OUT, PIN_TX);\
|
8 | NOPx40;\
|
9 | NOPx40;\
|
10 | NOPx40;\
|
11 | NOPx35;
|
12 |
|
13 | SET_BIT(PIN_TX_DIR, PIN_TX);
|
Die NOP Makros sind einfach rekursiv definiert mit:
1 | #define NOP __asm("NOP")
|
2 | #define NOPx2\
|
3 | NOP;\
|
4 | NOP;
|
5 | #define NOPx4\
|
6 | NOPx2;\
|
7 | NOPx2;
|
8 | #define NOPx6\
|
9 | NOPx5;\
|
10 | NOP;
|
11 | // etc.
|
Schliesslich gebe ich 16x Einser aus mit 15 Nuller dazwischen:
1 | BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;
|
2 | BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;
|
3 | BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;
|
4 | BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;BIT_1;BIT_0;
|
Das uebersetzt 1:1 in Assembler. Der Portzugriff BIS.B<->#-128, &PAOUT_H
und AND.B<->#127, &PAOUT_H hat lt. Handbuch 5 Cycles. 10us mit 16MHz
sind 160 Cycles. Deswegen habe ich 3x40 und 1x35 NOPs hinzugefuegt. Denn
ein NOP sollte einen Cycle benoetigen oder? Also muessten die Bits nach
meinem Verstaendnis mit exakt 10us Laenge ausgegeben werden.
Laut Messungen ist der Block vom ersten zum letzten 1 (also 31 bits)
aber 388.15us lang, d.h. pro bit 12.51us.
Wo mache ich den Fehler?