Forum: Mikrocontroller und Digitale Elektronik pic30f c30 - seltsames UART verhalten


von Camel C. (camelcoder)


Lesenswert?

n'abend,

nach ca. 12 stunden (gefühlt 120 stunden) fließt mir langsam das hirn zu 
den ohren raus...
mein uart macht FAST was er soll, aber seit stunden immer nur FAST!!! 
aahhh

wie folgt:

ich schicke mit dem befehl
U1TXREG = data & 0xFF; (aus der microchip uart lib) folgendes:
0x18 0x18 0x18
und lese das ergebnis mit hTerm:
0xcf 0xcf 0xcf 0xFF

das ganze binär:
gesendet:
00011000 00011000 00011000
empfangen:
11001111 11001111 11001111 11111111

es werden immer genau so viele bytes empfangen wie gesendet (und 
zusätzlich 0xff am ende, warum auch immer)
die empfangen bytes scheinen invertiert zu sein (halb so wild), um 1 
nach links verschoben, und die rechte stelle mit ner 1 aufgefüllt.

will ich jetzt zumindest mal die invertierung ausgleichen mit
U1TXREG = 0xff - (data & 0xFF);
dann liest hTerm:
00110001 00110001 00110001 11111111
d.h. meine datenbytes richtig rum, aber immer noch verschoben, und die 1 
hinten dran (und das 0xff byte am ende)

und jetzt kommt der knüller:

meine sendeeinstellung ist:
8bit, parity even, 1 stopbit

wenn ich am empfänger (hTerm) die gleichen einstellungen vornehme, dann 
sind die ganzen empfangenen bytes rot (fehler)

stelle ich jetzt aber den empfänger so ein:
8bit, parity ODD, 1 stopbit
dann zeigt er KEINE fehler an. (die empfangen bytes sehen genauso dumm 
aus)

(bei anderen gesendeten bytes wie z.b. 1c bekomm ich in jedem fall 
fehler)

hier ein bisschen code
1
#define FCY 14745600ul //7,3728 * 10^6 * 8 (pll8)
2
#define BAUD 38400ul
3
#define UBRG_VAL ((FCY+BAUD*8)/(BAUD*16)-1)
4
#define BAUD_REAL (FCY/(16*(UBRG_VAL+1)))
5
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
6
7
/*dank der frequenz ergibt das immer subergerade UBRG_VAL werte*/
8
9
_FOSC(CSW_FSCM_OFF & XT_PLL8);  /* external 7,3728MHz, PLL8  */
10
_FWDT(WDT_OFF);                 /* Watch dog Timer OFF  */
11
_FBORPOR(PBOR_OFF & MCLR_EN);   /* Brown Out OFF, MCLR Enabled  */
12
_FGS(CODE_PROT_OFF);            /* Code Protect OFF  */
13
14
15
int main(void){
16
17
    U1MODE  =  0x8082;    /* operation settings */
18
    U1STA  =  0x510;    /* TX & RX interrupt modes */
19
    U1BRG  =  UBRG_VAL;  /* baud rate */
20
    
21
22
    for(i=0;i<3;i++){
23
  while(U1STAbits.TRMT!=1);
24
  WriteUART1(0x18);
25
    }
26
27
    while(U1STAbits.TRMT!=1);
28
    U1MODEbits.UARTEN = 0;
29
30
}
31
32
void WriteUART1(unsigned int data){
33
34
  U1TXREG = 0xff - (data & 0xFF); 
35
/*zahl & 0xff ist doch immer die zahl selbst?*/
36
37
}

weiß irgendjemand rat?

danke!

nochwas:

ich kann sogar mit gewalt meine zahl richtig hinschieben:
U1TXREG = (0xff - (data & 0xFF)) >> 1;
dann sind die bits an der richtigen position, aber die 1 rechts geht 
nicht weg...
(also bei z.B. 00011100 kommt 00011101 an ...)

von Ohforf S. (ohforf)


Lesenswert?

Ich würds der Einfachheit halber erstmal ohne parity versuchen.
U1TXREG = data; // sollte eigentlich reichen.
Die Daten kommen normal invertiert aus dem PIC und werden dann vom 
Max232 nochmal invertiert. (irgenwo ist ein Flag mit dem man das 
umstellen kann... glaub ich)
Wenn das alles stimmt, sollte auch parity gehen.

Das  U1TXREG = 0xff - (data & 0xFF); // kapier ich überhaupt nicht.
Wozu die Subtraktion ?

von Camel C. (camelcoder)


Lesenswert?

habs jetzt ohne parity versucht ...
ging bei einigen zahlen, bei äußerst vielen aber nicht.

ich weiß echt nicht mehr weiter

das 0xff-zahl invertiert die zahl ...

noch irgendwelche tips?

von Ohforf S. (ohforf)


Lesenswert?

Hier wird schon UARTEN gesetzt (bit 15 in U1MODE)
 U1MODE  =  0x8082;    /* operation settings */

Laut Datenblatt soll man das bit erst setzen, wenn
U1MODE, U1STA und U1BRG eingestellt sind.
dann kommt UARTEN
dann UTXEN (wurde bei dir schon mit U1STA  =  0x510; gesetzt)

Vielleich klappts besser, wenn man strikt nach Datenblatt vorgeht ?

The following steps must be performed to transmit 8-bit
data:
1.Set up the UART:
First, the data length, parity and number of Stop
bits must be selected. Then, the transmit and
receive interrupt enable and priority bits are
setup in the UxMODE and UxSTA registers.
Also, the appropriate baud rate value must be
written to the UxBRG register.
2.Enable the UART by setting the UARTEN bit
(UxMODE<15>).
3.Set the UTXEN bit (UxSTA<10>), thereby
enabling a transmission.
4.Write the byte to be transmitted to the lower byte
of UxTXREG. The value will be transferred to the
Transmit Shift register (UxTSR) immediately
and the serial bit stream will start shifting out
during the next rising edge of the baud clock.
Alternatively, the data byte may be written while
UTXEN = 0, following which, the user may set
UTXEN. This will cause the serial bit stream to
begin immediately because the baud clock will
start from a cleared state.
5.A transmit interrupt will be generated,
depending on the value of the interrupt control
bit UTXISEL (UxSTA<15>).

von Camel C. (camelcoder)


Lesenswert?

ok, habs jetzt genau so eingestellt wie im datasheet:
1
U1MODE = 0x00;  //standard reset state
2
U1MODEbits.PDSEL=0; //8 bit data, no parity
3
  
4
U1STA = 0x110; //standard reset state
5
6
ConfigIntUART1(UART_RX_INT_DIS & UART_TX_INT_DIS); //interrupts disable
7
8
U1BRG = UBRG_VAL; //baudrate
9
10
11
U1MODEbits.UARTEN = 1; //enable UART
12
13
U1STAbits.UTXEN = 1; //enable transmitter
14
15
16
for(i=0;i<0xff;i++){
17
  while(U1STAbits.TRMT!=1);
18
  WriteUART1(i);
19
}
20
21
22
while(U1STAbits.TRMT!=1);
23
U1STAbits.UTXEN = 0;

und es kommt immer noch grütze raus.

momentan ist der transmitter-ausgang vom µC direkt mit der RS232 vom PC 
verbunden, kann es vielleicht daran liegen, dass nicht der richtige 
pegel ankommt? (mich wunderts, weil es kommen ja unterschiedliche pegel 
an (1/0))

von sigim (Gast)


Lesenswert?

sieht nach timing-Problem aus: Oszillator exakt eingestellt ? UART exakt 
eingestellt ?

von Ohforf S. (ohforf)


Lesenswert?

Camel Coder schrieb:
> momentan ist der transmitter-ausgang vom µC direkt mit der RS232 vom PC
> verbunden, kann es vielleicht daran liegen, dass nicht der richtige
> pegel ankommt? (mich wunderts, weil es kommen ja unterschiedliche pegel
> an (1/0))

Du hast keinen Max232 dazwischen ? Auweh !
Der muss unbedingt sein, sonst geht garnix und der arme PIC kriegt 
negative Spannung vom PC.
RS232 bringt Spannungen von -3V und +3V bis maximal -15V und +15V

von Dieter Werner (Gast)


Lesenswert?

> momentan ist der transmitter-ausgang vom µC direkt mit der RS232 vom
> PC verbunden, kann es vielleicht daran liegen, dass nicht der richtige
> pegel ankommt?

Der Pegel weniger, aber die Invertierung durch den RS232 Treiber fehlt.
Deshalb sind natürlich auch Start- und Stopbit invertiert und triggern 
den Empfänger zum falschen Zeitpunkt, das ergibt die Verschiebung um 1 
Bit.

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.