Forum: Mikrocontroller und Digitale Elektronik PIC24 UART Rx Interrupt


von Moot S. (mootseeker)


Lesenswert?

Hallo Zusammen,

ich arbeite mit einem PIC24FJ256GA106 Chip. Ich versuche ein char bzw. 
einen String über UART zu empfangen. Da ich mich noch nicht so gut 
auskenne, wollte ich dies mit dem MCC Configurator versuchen. So erhielt 
ich folgenden Code fürs Header:
1
#ifndef UART1_H
2
#define UART1_H
3
4
/**
5
 Section: Included Files
6
*/
7
8
#include <xc.h>
9
#include <stdbool.h>
10
#include <stdint.h>
11
#include <stdlib.h>
12
#include <stdio.h>
13
14
#define PPS_DISABLE_IOLOCK {  __builtin_write_OSCCONL( OSCCON & 0xbf ); } 
15
#define PPS_ENABLE_IOLOCK { __builtin_write_OSCCONL( OSCCON | 0x40 ); }
16
17
#ifdef __cplusplus  // Provide C++ Compatibility
18
19
    extern "C" {
20
21
#endif
22
        
23
/**
24
  Section: Data Types
25
*/
26
27
/** UART1 Driver Hardware Flags
28
29
  @Summary
30
    Specifies the status of the hardware receive or transmit
31
32
  @Description
33
    This type specifies the status of the hardware receive or transmit.
34
    More than one of these values may be OR'd together to create a complete
35
    status value.  To test a value of this type, the bit of interest must be
36
    AND'ed with value and checked to see if the result is non-zero.
37
*/
38
39
typedef enum
40
{
41
    /* Indicates that Receive buffer has data, at least one more character can be read */
42
    UART1_RX_DATA_AVAILABLE
43
        /*DOM-IGNORE-BEGIN*/  = (1 << 0) /*DOM-IGNORE-END*/,
44
    
45
    /* Indicates that Receive buffer has overflowed */
46
    UART1_RX_OVERRUN_ERROR
47
        /*DOM-IGNORE-BEGIN*/  = (1 << 1) /*DOM-IGNORE-END*/,
48
49
    /* Indicates that Framing error has been detected for the current character */
50
    UART1_FRAMING_ERROR
51
        /*DOM-IGNORE-BEGIN*/  = (1 << 2) /*DOM-IGNORE-END*/,
52
53
    /* Indicates that Parity error has been detected for the current character */
54
    UART1_PARITY_ERROR
55
        /*DOM-IGNORE-BEGIN*/  = (1 << 3) /*DOM-IGNORE-END*/,
56
57
    /* Indicates that Receiver is Idle */
58
    UART1_RECEIVER_IDLE
59
        /*DOM-IGNORE-BEGIN*/  = (1 << 4) /*DOM-IGNORE-END*/,
60
61
    /* Indicates that the last transmission has completed */
62
    UART1_TX_COMPLETE
63
        /*DOM-IGNORE-BEGIN*/  = (1 << 8) /*DOM-IGNORE-END*/,
64
65
    /* Indicates that Transmit buffer is full */
66
    UART1_TX_FULL
67
        /*DOM-IGNORE-BEGIN*/  = (1 << 9) /*DOM-IGNORE-END*/
68
69
} UART1_STATUS;
70
71
/** UART1 Driver Transfer Flags
72
73
  @Summary
74
    Specifies the status of the receive or transmit
75
76
  @Description
77
    This type specifies the status of the receive or transmit operation.
78
    More than one of these values may be OR'd together to create a complete
79
    status value.  To test a value of this type, the bit of interest must be
80
    AND'ed with value and checked to see if the result is non-zero.
81
*/
82
83
typedef enum
84
{
85
    /* Indicates that the core driver buffer is full */
86
    UART1_TRANSFER_STATUS_RX_FULL
87
        /*DOM-IGNORE-BEGIN*/  = (1 << 0) /*DOM-IGNORE-END*/,
88
89
    /* Indicates that at least one byte of Data has been received */
90
    UART1_TRANSFER_STATUS_RX_DATA_PRESENT
91
        /*DOM-IGNORE-BEGIN*/  = (1 << 1) /*DOM-IGNORE-END*/,
92
93
    /* Indicates that the core driver receiver buffer is empty */
94
    UART1_TRANSFER_STATUS_RX_EMPTY
95
        /*DOM-IGNORE-BEGIN*/  = (1 << 2) /*DOM-IGNORE-END*/,
96
97
    /* Indicates that the core driver transmitter buffer is full */
98
    UART1_TRANSFER_STATUS_TX_FULL
99
        /*DOM-IGNORE-BEGIN*/  = (1 << 3) /*DOM-IGNORE-END*/,
100
101
    /* Indicates that the core driver transmitter buffer is empty */
102
    UART1_TRANSFER_STATUS_TX_EMPTY
103
        /*DOM-IGNORE-BEGIN*/  = (1 << 4) /*DOM-IGNORE-END*/
104
105
} UART1_TRANSFER_STATUS;
106
107
/**
108
  Section: UART1 Driver Routines
109
*/
110
111
/**
112
  @Summary
113
    Initializes the UART instance : 1
114
115
  @Description
116
    This routine initializes the UART driver instance for : 1
117
    index.
118
    This routine must be called before any other UART routine is called.
119
    
120
  @Preconditions
121
    None.
122
123
  @Returns
124
    None.
125
126
  @Param
127
    None.
128
129
  @Comment
130
    
131
 
132
  @Example
133
    <code>
134
        const uint8_t writeBuffer[35] = "1234567890ABCDEFGHIJKLMNOP\r\n" ;
135
        unsigned int numBytes = 0;
136
        int  writebufferLen = strlen((char *)writeBuffer);
137
        UART1_Initialize();
138
  
139
        while(numBytes < writebufferLen)
140
        {    
141
            int bytesToWrite = UART1_TransmitBufferSizeGet();
142
            numBytes += UART1_WriteBuffer ( writeBuffer+numBytes, bytesToWrite)  ;
143
        }
144
    </code>
145
146
*/
147
148
void UART1_Initialize(void);
149
150
/**
151
  @Summary
152
    Allows setting of a the enable bit for the UART1 mode
153
154
  @Description
155
    This routine is used to enable the UART1
156
  
157
  @Preconditions
158
    UART1_Initialize() function should have been 
159
    called before calling this function.
160
 
161
  @Returns
162
    None
163
164
  @Param
165
    None
166
  
167
  @Example
168
    Refer to UART1_Initialize(); for an example
169
*/
170
171
void UART1_Enable(void);
172
173
/**
174
  @Summary
175
    Allows setting of a the disable bit for the UART1 mode
176
177
  @Description
178
    This routine is used to disable the UART1
179
  
180
  @Preconditions
181
    UART1_Initialize() function should have been 
182
    called before calling this function.
183
 
184
  @Returns
185
    None
186
187
  @Param
188
    None
189
  
190
  @Example
191
    Refer to UART1_Initialize(); for an example
192
*/
193
194
void UART1_Disable(void);
195
196
/**
197
  @Summary
198
    Read a byte of data from the UART1
199
200
  @Description
201
    This routine reads a byte of data from the UART1.
202
203
  @Preconditions
204
    UART1_Initialize function should have been called 
205
    before calling this function. The transfer status should be checked to see 
206
    if the receiver is not empty before calling this function.
207
208
  @Param
209
    None.
210
211
  @Returns
212
    A data byte received by the driver.
213
214
  @Example
215
    <code>
216
    uint8_t myBuffer[MY_BUFFER_SIZE];
217
    unsigned int numBytes = 0;
218
219
    // Pre-initialize myBuffer with MY_BUFFER_SIZE bytes of valid data.
220
    
221
    do
222
    {
223
        if( UART1_TRANSFER_STATUS_RX_DATA_PRESENT & UART1_TransferStatusGet() )
224
        {
225
            myBuffer[numBytes++] = UART1_Read();
226
        }
227
228
        // Do something else...
229
230
    } while( numBytes < MY_BUFFER_SIZE);
231
    </code>
232
*/
233
234
uint8_t UART1_Read( void);
235
236
/**
237
  @Summary
238
    Returns the number of bytes read by the UART1 peripheral
239
240
  @Description
241
    This routine returns the number of bytes read by the Peripheral and fills the
242
    application read buffer with the read data.
243
244
  @Preconditions
245
    UART1_Initialize function should have been called 
246
    before calling this function
247
248
  @Param
249
    buffer       - Buffer into which the data read from the UART1
250
251
  @Param
252
    numbytes     - Total number of bytes that need to be read from the UART1
253
                   (must be equal to or less than the size of the buffer)
254
255
  @Returns
256
    Number of bytes actually copied into the caller's buffer or -1 if there
257
    is an error.
258
259
  @Example
260
    <code>
261
    uint8_t readBuffer[MY_BUFFER_SIZE];
262
    unsigned int status, numBytes = 0;
263
    
264
    // Pre-initialize readBuffer with MY_BUFFER_SIZE bytes of valid data.
265
    
266
    while (numBytes < MY_BUFFER_SIZE);
267
    {
268
        status = UART1_TransferStatusGet();
269
        if (status & UART1_TRANSFER_STATUS_RX_FULL) {
270
            numBytes += UART1_ReadBuffer(readBuffer + numBytes, MY_BUFFER_SIZE - numBytes);
271
        }
272
273
        // Do something else...
274
    }
275
    </code>
276
*/
277
278
unsigned int UART1_ReadBuffer( uint8_t *buffer ,  const unsigned int numbytes);
279
280
/**
281
  @Summary
282
    Writes a byte of data to the UART1
283
284
  @Description
285
    This routine writes a byte of data to the UART1.
286
287
  @Preconditions
288
    UART1_Initialize function should have been called 
289
    before calling this function. The transfer status should be checked to see if
290
    transmitter is not full before calling this function.
291
292
  @Param
293
    byte         - Data byte to write to the UART1
294
295
  @Returns
296
    None.
297
298
  @Example
299
    <code>
300
    uint8_t myBuffer[MY_BUFFER_SIZE];
301
    unsigned int numBytes = 0;
302
303
    // Pre-initialize myBuffer with MY_BUFFER_SIZE bytes of valid data.
304
305
    while (numBytes < MY_BUFFER_SIZE);
306
    {
307
        if (!(UART1_TRANSFER_STATUS_TX_FULL & UART1_TransferStatusGet())) {
308
            UART1_Write(myBuffer[numBytes++]);
309
        }
310
311
        // Do something else...
312
    }
313
    </code>
314
*/
315
316
void UART1_Write( const uint8_t byte);
317
318
/**
319
  @Summary
320
    Returns the number of bytes written into the internal buffer
321
322
  @Description
323
    This API transfers the data from application buffer to internal buffer and 
324
    returns the number of bytes added in that queue
325
326
  @Preconditions
327
    UART1_Initialize function should have been called 
328
    before calling this function
329
330
  @Example
331
    <code>
332
    uint8_t myBuffer[MY_BUFFER_SIZE];
333
    unsigned int numBytes = 0;
334
    UART1_TRANSFER_STATUS status;
335
336
    // Pre-initialize myBuffer with MY_BUFFER_SIZE bytes of valid data.
337
338
    while (numBytes < MY_BUFFER_SIZE);
339
    {
340
        status = UART1_TransferStatusGet();
341
        if (status & UART1_TRANSFER_STATUS_TX_EMPTY) {
342
            numBytes += UART1_WriteBuffer(myBuffer + numBytes, MY_BUFFER_SIZE - numBytes);
343
344
        }
345
        // Do something else...
346
    }
347
    </code>
348
*/
349
350
unsigned int UART1_WriteBuffer( const uint8_t *buffer , const unsigned int numbytes );
351
352
/**
353
  @Summary
354
    Returns the transmitter and receiver transfer status
355
356
  @Description
357
    This returns the transmitter and receiver transfer status.The returned status 
358
    may contain a value with more than one of the bits
359
    specified in the UART1_TRANSFER_STATUS enumeration set.  
360
    The caller should perform an "AND" with the bit of interest and verify if the
361
    result is non-zero (as shown in the example) to verify the desired status
362
    bit.
363
364
  @Preconditions
365
    UART1_Initialize function should have been called 
366
    before calling this function
367
368
  @Param
369
    None.
370
371
  @Returns
372
    A UART1_TRANSFER_STATUS value describing the current status 
373
    of the transfer.
374
375
  @Example
376
    Refer to UART1_ReadBuffer and UART1_WriteBuffer for example
377
378
*/
379
380
UART1_TRANSFER_STATUS UART1_TransferStatusGet (void );
381
382
/**
383
  @Summary
384
    Returns the character in the read sequence at the offset provided, without
385
    extracting it
386
387
  @Description
388
    This routine returns the character in the read sequence at the offset provided,
389
    without extracting it
390
 
391
  @Param
392
    None.
393
    
394
  @Example 
395
    <code>
396
    uint8_t readBuffer[5];
397
    unsigned int data, numBytes = 0;
398
    unsigned int readbufferLen = sizeof (readBuffer);
399
    UART1_Initialize();
400
401
    while (numBytes < readbufferLen) {
402
        //Check for data at a particular place in the buffer
403
        data = UART1_Peek(3);
404
        if (data == 5) {
405
            //discard all other data if byte that is wanted is received.    
406
            //continue other operation
407
            numBytes += UART1_ReadBuffer(readBuffer + numBytes, readbufferLen);
408
        } else {
409
            break;
410
        }
411
    }
412
    </code>
413
 
414
*/
415
416
uint8_t UART1_Peek(uint16_t offset);
417
418
/**
419
  @Summary
420
    Validates the offset input and get the character in the read sequence at the 
421
    offset provided, without extracting it
422
423
  @Description
424
    This routine validates the offset input and get the character in the read 
425
    sequence at the offset provided, without extracting it. 
426
 
427
  @Param
428
    dataByte     - Data byte to be read from UART1 RX buffer based on offset position.
429
    offset       - UART1 RX buffer peek position. Offset input range is should be
430
                   0 to (UART1_CONFIG_RX_BYTEQ_LENGTH - 1).
431
432
  @Return   
433
    false        - If the UART1 RX buffer is empty or dataByte is NULL or UART1 RX 
434
                   buffer is empty.
435
    true         - Valid offset input position.
436
 
437
  @Example 
438
    <code>
439
    uint8_t readBuffer[MY_BUFFER_SIZE], data;
440
    unsigned int numBytes = 0;
441
    UART1_Initialize();
442
443
    // Pre-initialize readBuffer with MY_BUFFER_SIZE bytes of valid data.
444
445
    while (numBytes < MY_BUFFER_SIZE) {
446
        //Check for data at a particular place in the buffer
447
        if (UART1_PeekSafe(&data, 3)) {
448
            if (data == 5) {
449
                //discard all other data if byte that is wanted is received.    
450
                //continue other operation
451
                numBytes += UART1_ReadBuffer(readBuffer + numBytes, MY_BUFFER_SIZE - numBytes);
452
            } else {
453
                break;
454
            }
455
        }
456
    }
457
    </code>
458
 
459
*/
460
461
bool UART1_PeekSafe(uint8_t *dataByte, uint16_t offset);
462
463
/**
464
  @Summary
465
    Returns the number of bytes remaining in the receive buffer
466
467
  @Description
468
    This routine returns the number of bytes remaining in the receive buffer.
469
470
  @Param
471
    None.
472
473
  @Returns
474
    Remaining size of receive buffer.
475
    
476
  @Example 
477
    <code>
478
    uint8_t readBuffer[MY_BUFFER_SIZE];
479
    unsigned int size, numBytes = 0;
480
    UART1_Initialize();
481
482
    // Pre-initialize readBuffer with MY_BUFFER_SIZE bytes of valid data.
483
    
484
    while (size < MY_BUFFER_SIZE) {
485
        size = UART1_ReceiveBufferSizeGet();
486
    }
487
    numBytes = UART1_ReadBuffer(readBuffer, MY_BUFFER_SIZE);
488
    </code>
489
 
490
*/
491
492
unsigned int UART1_ReceiveBufferSizeGet(void);
493
494
/**
495
  @Summary
496
    Returns the number of bytes remaining in the transmit buffer.
497
498
  @Description
499
    This routine returns the number of bytes remaining in the transmit buffer.
500
501
 @Param
502
    None.
503
 
504
 @Returns
505
    Remaining size of transmit buffer.
506
507
 @Example
508
    Refer to UART1_Initialize(); for example.
509
*/
510
511
unsigned int UART1_TransmitBufferSizeGet(void);
512
513
/**
514
  @Summary
515
    Returns the status of the receive buffer
516
517
  @Description
518
    This routine returns if the receive buffer is empty or not.
519
520
  @Param
521
    None.
522
 
523
  @Returns
524
    True if the receive buffer is empty
525
    False if the receive buffer is not empty
526
    
527
  @Example
528
    <code>
529
    uint8_t myBuffer[MY_BUFFER_SIZE];
530
    unsigned int numBytes;
531
    UART1_TRANSFER_STATUS status;
532
533
    // Pre-initialize myBuffer with MY_BUFFER_SIZE bytes of valid data.
534
535
    numBytes = 0;
536
    while (numBytes < MY_BUFFER_SIZE);
537
    {
538
        status = UART1_TransferStatusGet();
539
        if (!UART1_ReceiveBufferIsEmpty()) {
540
            numBytes += UART1_ReadBuffer(myBuffer + numBytes, MY_BUFFER_SIZE - numBytes);
541
        }
542
        // Do something else...
543
    }
544
    </code>
545
 
546
*/
547
548
bool UART1_ReceiveBufferIsEmpty (void);
549
550
/**
551
  @Summary
552
    Returns the status of the transmit buffer
553
554
  @Description
555
    This routine returns if the transmit buffer is full or not.
556
557
 @Param
558
    None.
559
 
560
 @Returns
561
    True if the transmit buffer is full
562
    False if the transmit buffer is not full
563
564
 @Example
565
    Refer to UART1_Initialize() for example.
566
 
567
*/
568
569
bool UART1_TransmitBufferIsFull (void);
570
571
/**
572
  @Summary
573
    Returns the transmitter and receiver status
574
575
  @Description
576
    This returns the transmitter and receiver status. The returned status 
577
    contains a 16 bit value. 
578
    The caller should perform an "AND" with the bit of interest and verify if the
579
    result is non-zero (as shown in the example) to verify the desired status
580
    bit.
581
582
  @Preconditions
583
    UART1_Initialize function should have been called 
584
    before calling this function
585
586
  @Param
587
    None.
588
589
  @Returns
590
    16 bit value describing the current status of the transfer.
591
592
  @Example
593
    <code>
594
        while(!(UART1_StatusGet() & UART1_TX_COMPLETE ))
595
        {
596
           // Wait for the tranmission to complete
597
        }
598
    </code>
599
*/
600
601
uint16_t UART1_StatusGet (void );
602
603
#ifdef __cplusplus  // Provide C++ Compatibility
604
605
    }
606
607
#endif
608
    
609
#endif  // UART1_H

Dazu habe ich folgendes C File:
1
#include "uart1.h"
2
3
/**
4
  Section: Data Type Definitions
5
*/
6
7
/** UART Driver Queue Status
8
9
  @Summary
10
    Defines the object required for the status of the queue.
11
*/
12
13
typedef union
14
{
15
    struct
16
    {
17
            uint8_t full:1;
18
            uint8_t empty:1;
19
            uint8_t reserved:6;
20
    }s;
21
    uint8_t status;
22
}
23
24
UART_BYTEQ_STATUS;
25
26
/** UART Driver Hardware Instance Object
27
28
  @Summary
29
    Defines the object required for the maintenance of the hardware instance.
30
31
*/
32
33
typedef struct
34
{
35
    /* RX Byte Q */
36
    uint8_t                                      *rxTail ;
37
38
    uint8_t                                      *rxHead ;
39
40
    /* TX Byte Q */
41
    uint8_t                                      *txTail ;
42
43
    uint8_t                                      *txHead ;
44
45
    UART_BYTEQ_STATUS                        rxStatus ;
46
47
    UART_BYTEQ_STATUS                        txStatus ;
48
49
} UART_OBJECT ;
50
51
static volatile UART_OBJECT uart1_obj ;
52
53
/** UART Driver Queue Length
54
55
  @Summary
56
    Defines the length of the Transmit and Receive Buffers
57
58
*/
59
60
#define UART1_CONFIG_TX_BYTEQ_LENGTH 8
61
#define UART1_CONFIG_RX_BYTEQ_LENGTH 8
62
63
/** UART Driver Queue
64
65
  @Summary
66
    Defines the Transmit and Receive Buffers
67
68
*/
69
70
static uint8_t uart1_txByteQ[UART1_CONFIG_TX_BYTEQ_LENGTH] ;
71
static uint8_t uart1_rxByteQ[UART1_CONFIG_RX_BYTEQ_LENGTH] ;
72
73
/**
74
  Section: Driver Interface
75
*/
76
77
void UART1_Initialize(void)
78
{
79
    PPS_DISABLE_IOLOCK;
80
    {
81
        RPINR18bits.U1RXR = 16; /* Assign UART1 Receive (U1RX) to RP16 pin */
82
        RPOR15bits.RP30R = 3; /* RP30 is tied to default port pin */
83
    }
84
    PPS_ENABLE_IOLOCK;
85
    
86
    // STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; RXINV disabled; UEN TX_RX; 
87
    // Data Bits = 8; Parity = None; Stop Bits = 1;
88
    U1MODE = (0x8008 & ~(1<<15));  // disabling UARTEN bit
89
    // UTXISEL0 TX_ONE_CHAR; UTXINV disabled; OERR NO_ERROR_cleared; URXISEL RX_ONE_CHAR; UTXBRK COMPLETED; UTXEN disabled; ADDEN disabled; 
90
    U1STA = 0x00;
91
  // BaudRate = 115200; Frequency = 16000000 Hz; BRG 34; 
92
    U1BRG = 0x22;
93
    
94
    IEC0bits.U1RXIE = 1;
95
    
96
    //Make sure to set LAT bit corresponding to TxPin as high before UART initialization
97
    
98
    UART1_Enable();  // enabling UARTEN bit
99
100
    uart1_obj.txHead = uart1_txByteQ;
101
    uart1_obj.txTail = uart1_txByteQ;
102
    uart1_obj.rxHead = uart1_rxByteQ;
103
    uart1_obj.rxTail = uart1_rxByteQ;
104
    uart1_obj.rxStatus.s.empty = true;
105
    uart1_obj.txStatus.s.empty = true;
106
    uart1_obj.txStatus.s.full = false;
107
    uart1_obj.rxStatus.s.full = false;
108
}
109
110
/**
111
    Maintains the driver's transmitter state machine and implements its ISR
112
*/
113
114
void __attribute__ ( ( interrupt, no_auto_psv ) ) _U1TXInterrupt ( void )
115
{ 
116
    if((uart1_obj.txHead == uart1_obj.txTail) && (uart1_obj.txStatus.s.full == false))
117
    {
118
        while(U1STAbits.TRMT == 0){}
119
        
120
        uart1_obj.txStatus.s.empty = true;
121
        IEC0bits.U1TXIE = 0;
122
        return;
123
    }
124
125
    IFS0bits.U1TXIF = 0;
126
127
    while(!(U1STAbits.UTXBF == 1))
128
    {
129
        U1TXREG = *uart1_obj.txHead;
130
131
        uart1_obj.txHead++;
132
133
        if(uart1_obj.txHead == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH))
134
        {
135
            uart1_obj.txHead = uart1_txByteQ;
136
        }
137
138
        uart1_obj.txStatus.s.full = false;
139
140
        if(uart1_obj.txHead == uart1_obj.txTail)
141
        {
142
            break;
143
        }
144
    }
145
}
146
147
void __attribute__ ( ( interrupt, no_auto_psv ) ) _U1RXInterrupt( void )
148
{
149
150
    while((U1STAbits.URXDA == 1))
151
    {
152
        *uart1_obj.rxTail = U1RXREG;
153
154
        uart1_obj.rxTail++;
155
156
        if(uart1_obj.rxTail == (uart1_rxByteQ + UART1_CONFIG_RX_BYTEQ_LENGTH))
157
        {
158
            uart1_obj.rxTail = uart1_rxByteQ;
159
        }
160
161
        uart1_obj.rxStatus.s.empty = false;
162
        
163
        if(uart1_obj.rxTail == uart1_obj.rxHead)
164
        {
165
            //Sets the flag RX full
166
            uart1_obj.rxStatus.s.full = true;
167
            break;
168
        }
169
    }
170
171
    IFS0bits.U1RXIF = false;
172
}
173
174
void __attribute__ ( ( interrupt, no_auto_psv ) ) _U1ErrInterrupt( void )
175
{
176
    if ((U1STAbits.OERR == 1))
177
    {
178
        U1STAbits.OERR = 0;
179
    }
180
    
181
    IFS4bits.U1ERIF = false;
182
}
183
184
/**
185
  Section: UART Driver Client Routines
186
*/
187
188
uint8_t UART1_Read( void)
189
{
190
    uint8_t data = 0;
191
192
    data = *uart1_obj.rxHead;
193
194
    uart1_obj.rxHead++;
195
196
    if (uart1_obj.rxHead == (uart1_rxByteQ + UART1_CONFIG_RX_BYTEQ_LENGTH))
197
    {
198
        uart1_obj.rxHead = uart1_rxByteQ;
199
    }
200
201
    if (uart1_obj.rxHead == uart1_obj.rxTail)
202
    {
203
        uart1_obj.rxStatus.s.empty = true;
204
    }
205
206
    uart1_obj.rxStatus.s.full = false;
207
208
    return data;
209
}
210
211
unsigned int UART1_ReadBuffer( uint8_t *buffer, const unsigned int bufLen)
212
{
213
    unsigned int numBytesRead = 0 ;
214
    while ( numBytesRead < ( bufLen ))
215
    {
216
        if( uart1_obj.rxStatus.s.empty)
217
        {
218
            break;
219
        }
220
        else
221
        {
222
            buffer[numBytesRead++] = UART1_Read () ;
223
        }
224
    }
225
226
    return numBytesRead ;
227
}
228
229
void UART1_Write( const uint8_t byte)
230
{
231
    IEC0bits.U1TXIE = 0;
232
    
233
    *uart1_obj.txTail = byte;
234
235
    uart1_obj.txTail++;
236
    
237
    if (uart1_obj.txTail == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH))
238
    {
239
        uart1_obj.txTail = uart1_txByteQ;
240
    }
241
242
    uart1_obj.txStatus.s.empty = false;
243
244
    if (uart1_obj.txHead == uart1_obj.txTail)
245
    {
246
        uart1_obj.txStatus.s.full = true;
247
    }
248
249
    IEC0bits.U1TXIE = 1 ;
250
}
251
252
unsigned int UART1_WriteBuffer( const uint8_t *buffer , const unsigned int bufLen )
253
{
254
    unsigned int numBytesWritten = 0 ;
255
256
    while ( numBytesWritten < ( bufLen ))
257
    {
258
        if((uart1_obj.txStatus.s.full))
259
        {
260
            break;
261
        }
262
        else
263
        {
264
            UART1_Write (buffer[numBytesWritten++] ) ;
265
        }
266
    }
267
268
    return numBytesWritten ;
269
}
270
271
UART1_TRANSFER_STATUS UART1_TransferStatusGet (void )
272
{
273
    UART1_TRANSFER_STATUS status = 0;
274
275
    /* The TX empty must be checked before the full in order to prevent a race
276
     * condition where a TX transmission could start between these two checks
277
     * resulting in both full and empty set at the same time.
278
     */
279
    if(uart1_obj.txStatus.s.empty)
280
    {
281
        status |= UART1_TRANSFER_STATUS_TX_EMPTY;
282
    }
283
284
    if(uart1_obj.txStatus.s.full)
285
    {
286
        status |= UART1_TRANSFER_STATUS_TX_FULL;
287
    }
288
289
    /* The RX full must be checked before the empty in order to prevent a race
290
     * condition where a RX reception could start between these two checks
291
     * resulting in both empty and full set at the same time.
292
     */
293
    if(uart1_obj.rxStatus.s.full)
294
    {
295
        status |= UART1_TRANSFER_STATUS_RX_FULL;
296
    }
297
298
    if(uart1_obj.rxStatus.s.empty)
299
    {
300
        status |= UART1_TRANSFER_STATUS_RX_EMPTY;
301
    }
302
    else
303
    {
304
        status |= UART1_TRANSFER_STATUS_RX_DATA_PRESENT;
305
    }
306
    return status;
307
}
308
309
/*
310
    Uart Peek function returns the character in the read sequence with
311
    the provided offset, without extracting it.
312
*/
313
uint8_t UART1_Peek(uint16_t offset)
314
{
315
    if( (uart1_obj.rxHead + offset) >= (uart1_rxByteQ + UART1_CONFIG_RX_BYTEQ_LENGTH))
316
    {
317
      return uart1_rxByteQ[offset - (uart1_rxByteQ + UART1_CONFIG_RX_BYTEQ_LENGTH - uart1_obj.rxHead)];
318
    }
319
    else
320
    {
321
      return *(uart1_obj.rxHead + offset);
322
    }
323
}
324
325
/*
326
    Uart PeekSafe function validates all the possible conditions and get the character  
327
    in the read sequence with the provided offset, without extracting it.
328
*/
329
bool UART1_PeekSafe(uint8_t *dataByte, uint16_t offset)
330
{
331
    uint16_t index = 0;
332
    bool status = true;
333
    
334
    if((offset >= UART1_CONFIG_RX_BYTEQ_LENGTH) || (uart1_obj.rxStatus.s.empty) || (!dataByte))
335
    {
336
        status = false;
337
    }
338
    else
339
    {    
340
        //Compute the offset buffer overflow range
341
        index = ((uart1_obj.rxHead - uart1_rxByteQ) + offset) % UART1_CONFIG_RX_BYTEQ_LENGTH;
342
    
343
        /**
344
         * Check for offset input value range is valid or invalid. If the range 
345
         * is invalid, then status set to false else true.
346
         */
347
        if(uart1_obj.rxHead < uart1_obj.rxTail) 
348
        {
349
            if((uart1_obj.rxHead + offset) > (uart1_obj.rxTail - 1))
350
            {
351
                status = false;
352
            }
353
        }
354
        else if(uart1_obj.rxHead > uart1_obj.rxTail)
355
        {
356
            if((uart1_rxByteQ + index) < uart1_obj.rxHead)
357
            {
358
                if( (uart1_rxByteQ + index) >= uart1_obj.rxTail )
359
                {
360
                    status = false;
361
                }
362
            } 
363
        }
364
365
        if(status == true)
366
        {
367
            *dataByte = UART1_Peek(offset);
368
        }
369
    }
370
    return status;
371
}
372
373
unsigned int UART1_ReceiveBufferSizeGet(void)
374
{
375
    if(!uart1_obj.rxStatus.s.full)
376
    {
377
        if(uart1_obj.rxHead > uart1_obj.rxTail)
378
        {
379
            return(uart1_obj.rxHead - uart1_obj.rxTail);
380
        }
381
        else
382
        {
383
            return(UART1_CONFIG_RX_BYTEQ_LENGTH - (uart1_obj.rxTail - uart1_obj.rxHead));
384
        } 
385
    }
386
    return 0;
387
}
388
389
unsigned int UART1_TransmitBufferSizeGet(void)
390
{
391
    if(!uart1_obj.txStatus.s.full)
392
    { 
393
        if(uart1_obj.txHead > uart1_obj.txTail)
394
        {
395
            return(uart1_obj.txHead - uart1_obj.txTail);
396
        }
397
        else
398
        {
399
            return(UART1_CONFIG_TX_BYTEQ_LENGTH - (uart1_obj.txTail - uart1_obj.txHead));
400
        }
401
    }
402
    return 0;
403
}
404
405
bool UART1_ReceiveBufferIsEmpty (void)
406
{
407
    return(uart1_obj.rxStatus.s.empty);
408
}
409
410
bool UART1_TransmitBufferIsFull(void)
411
{
412
    return(uart1_obj.txStatus.s.full);
413
}
414
415
uint16_t UART1_StatusGet (void)
416
{
417
    return U1STA;
418
}
419
420
void UART1_Enable(void)
421
{
422
    U1MODEbits.UARTEN = 1;
423
    U1STAbits.UTXEN = 1;
424
}
425
426
void UART1_Disable(void)
427
{
428
    U1MODEbits.UARTEN = 0;
429
    U1STAbits.UTXEN = 0;
430
}

Mein Problem ist, dass ich vom Rx-Interrupt beim Debuggen nichts 
empfange, habe ich etwas falsch eingestellt oder ist eine Funktion 
falsch aufgebaut?
Schreiben bzw. senden über UART funktioniert.

Hatte jemand schon ein ähnliches Problem?

von Edson (Gast)


Lesenswert?

Moot S. schrieb:
>
> Mein Problem ist, dass ich vom Rx-Interrupt beim Debuggen nichts
> empfange, habe ich etwas falsch eingestellt oder ist eine Funktion
> falsch aufgebaut?



> Schreiben bzw. senden über UART funktioniert.

Wie geprüft?

> Hatte jemand schon ein ähnliches Problem?

Da kannst Du aber sicher sein ;)
Trotzdem, ohne den Code, den Du geschrieben hast ist die Fehlersuche 
nicht sinnvoll. Hast Du denn den RX-Interrupt auch "enabled" und global 
freigegeben?

von Moot S. (mootseeker)


Lesenswert?

Hallo Edson,

vielen Dank für deine schnelle Antwort. Geprüft habe ich das "Senden" 
mit einem USB zu UART converter und Hterm.

Den UART1 Interrupt habe ich enabled, dies wird doch in der 
UART1_Initialize Funktion mit dieser zeile
1
 IEC0bits.U1RXIE = 1;
 enabled?

Wie meinst du Global freigegben, muss ich im main noch eine Funktion 
aufrufen?

mein Main sieht momentan so aus:
1
/**
2
  Section: Included Files
3
*/
4
#include <stdio.h>
5
#include <xc.h>
6
#include "mcc_generated_files/system.h"
7
#include "mcc_generated_files/traps.h"
8
9
#include "uart1.h"
10
11
12
#define FCY 16000000Ul
13
#include "libpic30.h"
14
15
UART_OBJECT newObj; 
16
17
char test;
18
19
/*
20
                         Main application
21
 */
22
int main(void)
23
{
24
  
25
  
26
    // initialize the device
27
    SYSTEM_Initialize();
28
    
29
    TRISEbits.TRISE0 = 0;   //Port = Output
30
    
31
    while (1)
32
    {
33
        LATEbits.LATE0 = ~LATEbits.LATE0;   //LED Toggeln
34
        
35
        printf("hallo Welt"); //String ausgeben auf UART1
36
        
37
        test = newObj.rxTail; //Von Variable einlesen
38
        
39
        printf(test);          //Eingelesene ausgeben
40
        
41
        __delay_ms(10); 
42
    }
43
44
    return 1;
45
}
46
/**
47
 End of File
48
*/

Findest du gerade einen Fehler oder habe ich etwas vergessen?

Gruss
MootSeeker

von Moot S. (mootseeker)


Lesenswert?

Hat jemand vielleicht ein Beispiel für mein Problem oder kennt einen 
Post wo dies schon mal aufgegriffen wurde?

Ich blicke noch nicht ganz durch was ich genau falsch mache.

Vielen Dank für eure Hilfe!

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.