C166: Using 2nd Serial Port (ASC1) on Infineon XC16X Devices
Information in this article applies to:
QUESTION
I want to use the second serial port (ASC1) on the Infineon XC167.
What must I do to use the ASC1 with my program?
ANSWER
Infineon has added the second serial port (ASC1) on some XC16x
devices. ASC1 is almost identical with the ASC0 but
its SFR's are at different addresses.
Therefore, the basic character input/output functions defined in
GETKEY.C and PUTCHAR.C must be modified to work for ASC1. These
functions are also used by printf, scanf, puts, and gets.
To modify GETKEY.C and PUTCHAR.C...
-
Copy the following code into new PUTCHAR.C and GETKEY.C source
files.
- Set USE_ASC to 1 for ASC1 in both files.
-
Include the new modified PUTCHAR.C and GETKEY.C files in your
project.
-
Initialize ASC1 in your main program. See HELLO.C example
below.
-
Re-build your project using the new GETKEY.C and PUTCHAR.C to
use ASC1.
PUTCHAR.C
/***********************************************************************/
/* This file is part of the C166 Compiler package */
/* Copyright KEIL ELEKTRONIK GmbH 1992-2003 */
/***********************************************************************/
/* */
/* PUTCHAR.C: This routine is the general character output of C166. */
/* You may add this file to a µVision project. */
/* */
/* To translate this file use C166 with the following invocation: */
/* */
/* C166 PUTCHAR.C memory model */
/* */
/* To link the modified PUTCHAR.OBJ file to your application use the */
/* following L166 invocation: */
/* */
/* L166 your object file list, PUTCHAR.OBJ controls */
/* */
/***********************************************************************/
#include
#define XON 0x11
#define XOFF 0x13
#define USE_ASC 1 // set to 0 to use ASC0 with XC161, XC164 and XC167
// set to 1 to use ASC1 with XC161 and XC167
#if (USE_ASC == 0)
#define ASCx_TBUF ASC0_TBUF
#define ASCx_RBUF ASC0_RBUF
#define ASCx_RIC_IR ASC0_RIC_IR
#define ASCx_TIC_IR ASC0_TIC_IR
#elif (USE_ASC == 1)
#define ASCx_TBUF ASC1_TBUF
#define ASCx_RBUF ASC1_RBUF
#define ASCx_RIC_IR ASC1_RIC_IR
#define ASCx_TIC_IR ASC1_TIC_IR
#else
#error "USE_ASC definition is wrong!"
#endif
/*
* putchar (full version): expands '\n' into CR LF and handles
* XON/XOFF (Ctrl+S/Ctrl+Q) protocol
*/
signed char putchar (signed char c) {
if (c == '\n') {
if (ASCx_RIC_IR) {
if (ASCx_RBUF == XOFF) {
do {
ASCx_RIC_IR = 0;
while (!ASCx_RIC_IR);
}
while (ASCx_RBUF != XON);
ASCx_RIC_IR = 0;
}
}
while (!ASCx_TIC_IR);
ASCx_TIC_IR = 0;
ASCx_TBUF = 0x0d; /* output CR */
}
if (ASCx_RIC_IR) {
if (ASCx_RBUF == XOFF) {
do {
ASCx_RIC_IR = 0;
while (!ASCx_RIC_IR);
}
while (ASCx_RBUF != XON);
ASCx_RIC_IR = 0;
}
}
while (!ASCx_TIC_IR);
ASCx_TIC_IR = 0;
return (ASCx_TBUF = c);
}
#if 0 // comment out versions below
/*
* putchar (basic version): expands '\n' into CR LF
*/
char putchar (char c) {
if (c == '\n') {
while (!ASCx_TIC_IR);
ASCx_TIC_IR = 0;
ASCx_TBUF = 0x0d; /* output CR */
}
while (!ASCx_TIC_IR);
ASCx_TIC_IR = 0;
return (ASCx_TBUF = c);
}
/*
* putchar (mini version): outputs charcter only
*/
char putchar (char c) {
while (!ASCx_TIC_IR);
ASCx_TIC_IR = 0;
return (ASCx_TBUF = c);
}
#endif
GETKEY.C
/***********************************************************************/
/* This file is part of the C166 Compiler package */
/* Copyright KEIL ELEKTRONIK GmbH 1992-2003 */
/***********************************************************************/
/* */
/* GETKEY.C: This routine is the general character input of C166. */
/* You may add this file to a µVision project. */
/* */
/* To translate this file use C166 with the following invocation: */
/* */
/* C166 GETKEY.C memory model */
/* */
/* To link the modified GETKEY.OBJ file to your application use the */
/* following L166 invocation: */
/* */
/* L166 your object file list, GETKEY.OBJ controls */
/* */
/***********************************************************************/
#include
#define USE_ASC 1 // set to 0 to use ASC0 with XC161, XC164 and XC167
// set to 1 to use ASC1 with XC161 and XC167
#if (USE_ASC == 0)
#define ASCx_TBUF ASC0_TBUF
#define ASCx_RBUF ASC0_RBUF
#define ASCx_RIC_IR ASC0_RIC_IR
#define ASCx_TIC_IR ASC0_TIC_IR
#elif (USE_ASC == 1)
#define ASCx_TBUF ASC1_TBUF
#define ASCx_RBUF ASC1_RBUF
#define ASCx_RIC_IR ASC1_RIC_IR
#define ASCx_TIC_IR ASC1_TIC_IR
#else
#error "USE_ASC definition is wrong!"
#endif
signed char _getkey (void) {
char c;
while (!ASCx_RIC_IR);
c = (char) ASCx_RBUF;
ASCx_RIC_IR = 0;
return (c);
}
HELLO.C
/*-------------------------------------------------------------------------
HELLO.C: adapted for Infineon XC16x devices
Copyright 1995-2003 Keil Software, Inc.
-------------------------------------------------------------------------*/
#include /* standard I/O .h-file */
#include /* special function register XC161 */
#include
#define USE_ASC 1 /* set to 0 to use ASC0 */
/* set to 1 to use ASC1 */
/****************/
/* main program */
/****************/
void main (void) { /* execution starts here */
/* initialize the serial interface */
#ifndef Monitor /* do not initialize if you use Monitor-166 */
#if (USE_ASC == 0)
P3 |= 0x0400; /* SET PORT 3.10 OUTPUT LATCH (TXD) */
DP3 |= 0x0400; /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT) */
DP3 &= 0xF7FF; /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */
ASC0_TIC = 0x80; /* SET TRANSMIT INTERRUPT FLAG */
ASC0_RIC = 0x00; /* DELETE RECEIVE INTERRUPT FLAG */
ASC0_BG = 0x40; /* SET BAUDRATE TO 9600 BAUD @ 20MHz */
ASC0_CON = 0x8011; /* SET SERIAL MODE */
ALTSEL0P3 |= 0x0C00; /* Configure port pins for serial interface 0 */
#else
P3 |= 0x0001; /* SET PORT 3.0 OUTPUT LATCH (TXD) */
DP3 |= 0x0001; /* SET PORT 3.0 DIRECTION CONTROL (TXD OUTPUT) */
DP3 &= 0xFFFD; /* RESET PORT 3.1 DIRECTION CONTROL (RXD INPUT) */
ASC1_TIC = 0x80; /* SET TRANSMIT INTERRUPT FLAG */
ASC1_RIC = 0x00; /* DELETE RECEIVE INTERRUPT FLAG */
ASC1_BG = 0x40; /* SET BAUDRATE TO 9600 BAUD @ 20MHz */
ASC1_CON = 0x8011; /* SET SERIAL MODE */
ALTSEL0P3 |= 0x0003; /* Configure port pins for serial interface 1 */
#endif
#endif
printf ("Hello World\n"); /* the 'printf' function call */
while (1) { /* An embedded program does not stop and */
; /* ... */ /* never returns. We've used an endless */
} /* loop. You may wish to put in your own */
} /* code were we've printed the dots (...). */
-
Refer to Basic
I/O in the C166 User's Guide.
- Refer to the Infineon C161CS Data Sheet.
SEE ALSO
Last Reviewed: Thursday, February 25, 2021