Forum: Mikrocontroller und Digitale Elektronik UART Sample Programm M16C


von Thomas (Gast)


Lesenswert?

hallo zusammen,
Besitze ganz neu ein ZiggBee-Demo-Kit von Renesas RZB-CC16C-ZDK mit 
einem M16C Prozessor. Zum programmieren benutzte ich C++ im HEW4.
Ich möchte zum kennenlernen einfach nur ein Zeichen von dem Bord über 
die Schnittstelle senden.
Es gibt hier ein Sample-Programm, zur Verbindung mit dem Hyperterminal, 
was aber leider nicht fuktioniert.
Ich habe das Oszi angeschlossen und bekomme kein Signal.
Weiß jemand warum? und wie ich einfach nur ein Zeichen über das UART 
senden kann. Ich verzweile hier schon fast.


Gruß thomas


hier der Sample-Code:

/*====================================================================== 
===*    Description: main routine for SIO - UART mode
*   This program communicates from the M16C/28 to a terminal
*   program via UART0 and RS232.  UART0 configuration is:
*   19200 baud, 8-bit data, 1 stop bit, no parity, no flow control.
*   To see the data sent, use Hyperterminal configured as mentioned
*   above and connect a null modem cable between P1 and the PC's
*   com port.
*   Incrementing data (0 to 9) is sent to the Hyperterminal window.
*   To stop receiving data, press z on the keyboard. To resume,
*   press any key.
*   When running this demo on the SKP16C28 Board, it must be connected 
to
*   the COMMs expansion boardfor RS-232C connectivity. The COMMs board
*   has the RS-232C driver/receiver and DB9 D-Sub connector.
*======================================================================= 
===*/

#include "skp_bsp.h"  // include SKP board support package

void mcu_init(void);
void text_write (_far char * msg_string);
void uart_init(void);

#pragma INTERRUPT U0rec_ISR   // vector modified in 
sect30_28skp_uart.inc
void U0rec_ISR (void);     // Interrupt routine for UART0 Receive

#define BAUD_RATE  19200

char U0_in;       // declare UART0 receive variable

/* String constants used for screen output 
**********************************/
const char cmd_clr_scr[] = {27,'[','2','J',0};
const char cmd_cur_home[] = {27,'[','H',0};

/*********************************************************************** 
***
Description: This is the main program
************************************************************************ 
**/
void main(void) {

  int count;    // declare count variable
  int convert;    // declare ASCII variable
  unsigned int delay;  // declare delay variable
  int i;      // declare string pointer variable

  mcu_init();    // MCU initialization

    ENABLE_LEDS;

  uart_init();    // UART initialization

  text_write(cmd_clr_scr);     // clear screen
  text_write(cmd_cur_home);     // home cursor
  text_write("Renesas Technology America, Inc. \r\n");
  text_write("SKP16C28 UART demo. \r\n");
  text_write("Press z to stop, any key to continue. \r\n");

/************** MAIN PROGRAM LOOP ***********************/
  while (1){

  while (U0_in != 'z'){  // count as long as "z" wasn't pressed
  text_write("\r\n");  // send carriage return and line feed

  RED_LED = LED_OFF;
  GRN_LED = LED_ON;

  for (count=0;(count<=9)&&(U0_in!='z');count ++){  // count 0 to 9
  convert = count + 0x30;      // convert count data to ASCII
  while(ti_u0c1 == 0);   // wait for previous transmission to complete
  u0tb = convert;    // put ASCII data in transmit buffer
  for (delay=0x3fff; delay>0; delay--); // Count Delay
}
}
 _asm("NOP");          // Do nothing while stopped
  }
}

/*********************************************************************** 
***
Description: Interrupt routine for UART0 receive  Reads character 
received from keyboard and stores U0_in Variable
************************************************************************ 
**/
void U0rec_ISR(void){
  while(ri_u0c1 == 0);      // make sure receive is complete
  U0_in = (char)u0rb;    // read in received data
  if (U0_in == 'z'){      // If "z" was entered do the following:
    while(ti_u0c1 == 0);   //   wait for previous transmission to 
complete
    u0tb = 'z';      //   echo "z" to screen
    RED_LED = LED_ON;
    GRN_LED = LED_OFF;
  }
}

/*********************************************************************** 
***
Description: Uart0 initialization - 19200 baud, 8 data bits, 1 stop bit, 
no parity.
************************************************************************ 
**/
void uart_init(void) {

u0brg = (unsigned char)(((f1_CLK_SPEED/16)/BAUD_RATE)-1);
ucon = 0x00;   // UART transmit/receive control register 2

u0c0 = 0x10;   // UART0 transmit/receive control register 1

u0c1 = 0x00;   // UART0 transmit/receive control register 1

u0mr = 0x05;  // UART0 transmit/receive mode register

u0tb = u0rb;  // clear UART0 receive buffer by reading
u0tb = 0;    // clear UART0 transmit buffer

DISABLE_IRQ;  // disable irqs before setting irq registers
s0ric = 0x04;  // Enable UART0 receive interrupt, priority level 
ENABLE_IRQ;  // Enable all interrupts

u0c1 = 0x05;   // UART0 transmit/receive control register 1

}

/*********************************************************************** 
***
Description: The following sends a text string to the terminal program
************************************************************************ 
**/
void text_write ( _far char * msg_string)
{
char i;

for (i=0; msg_string[i]; i++){   // This loop reads in the text string 
and
while(ti_u0c1 == 0);        //  puts it in the UART 0 transmit buffer
u0tb = msg_string[i];
}
}

von Martin (Gast)


Lesenswert?

HEW4 ist aber nicht C++ oder täusche ich mich da.

von Martin (Gast)


Lesenswert?

Wie so oft die Frage, was sagt denn dein Debugger?

von Thomas (Gast)


Lesenswert?

der Code ist doch C++ oder nicht?

Das ist es ja, der Debugger sagt: alles in Ordnung!
Hast du schon mal mit HEW4 gearbeitet?

von Martin (Gast)


Lesenswert?

> der Code ist doch C++ oder nicht?

Das ist eher C (ohne ++).

> Hast du schon mal mit HEW4 gearbeitet?

Ich arbeite seid einigen Jahen damit.


* U0_in wird nicht initialisiert!
* Wurden die IO-Pins richtig gesetzt?
* Durchläuft der Code diese Zeile: "u0tb = convert;    // put ASCII data 
in transmit buffer" ?

von Thomas (Gast)


Lesenswert?

> Das ist eher C (ohne ++).

Da hast du recht!

U=_in habe ich jetzt initialisiert..
IO-Pin sind gesetzt..
Die Zeile "u0tb = convert; " wird durchlaufen, aber er schreibt nicht 
den Wert von "convert" ins Buffer Register u0tb.
Muß ich das noch irgendwo freischalten?

von Rudi (Gast)


Lesenswert?

Hallo Thomas,

ich weiß nicht, wie der M16C28 aufgebaut ist und ob es dort verschiedene 
Gehäusevarianten bzgl. IOs gibt, denke aber, dass er ähnlich dem M16C29 
ist, den wir verwenden.

Beim M16C29 gibt es zwei Gehäusevarianten, die sich in unterschiedlicher 
PINanzahl widerspiegeln. Wichtig ist, dass das entsprechende Register 
für das verwendete Gehäuse gesetzt ist, sonst kann es passierenn, dass 
du an den vermeintlichen IOs nichts messen kannst. Wir verwenden den 
80poligen Chip und dann muss das Register wie folgt gesetzt werden:

  prcr = 0x04;
  /* Set to 80 pin chip */
  pacr = 0x03;

Beste Grüße
Rudi

von Thomas (Gast)


Lesenswert?

Hallo Rudi,
ja mein M16C28 ist auch eine 80Pin version.
Hab die Register gesetzt, aber läuft trotzdem nicht wie gehabt.
Könnte das vielleicht an der indizialisierung vom Uart liegen?
es läuft auch nicht wenn ich einfach nur den Uart intitialisiere und was 
ins Buffer schreibe, dann müsste doch der Wert an der Schnittstelle 
anliegen, oder sehe ich das falsch?

gruß

von Rudi (Gast)


Lesenswert?

noch eine Frage:

Du arbeitest mit Interrupt - hast du diesen auch entsprechend deklariert 
in der sect30.inc-Datei?

Wenn nicht, dann wird deine Interrupt-Routine gar nicht erst 'scharf' 
geschaltet.

Rudi

von Martin (Gast)


Lesenswert?

Das ist aber egal, es soll ja ersteinmal nur ein einzelnes Zeichen 
gesendet werden. Der Interrupt ist erst für Zeichenketten erforderlich.

von Martin (Gast)


Lesenswert?

Sorry, das war zur Hälfte Müll was isch geschrieben habe.

Interrupt -> Empfangen,
Zeichenketten senden -> text_write

von Rudi (Gast)


Lesenswert?

Mmh, so sehe ich keinen Fehler in der Initialisierung - scheint insweit 
ok zu sein.
Ich denke, dass das u0tb-Register nicht direkt vom Debugger gelesen 
werden kann - dieses Problem haben wir auch schon bei anderen Registern 
festgestellt.

Hast Du schon mal dierekt am Port mit einem Oszi geschaut, ob sich das 
was rührt?

Rudi

von Thomas (Gast)


Lesenswert?

Danke erstmal allen,

ja in der sect30.inc-Datei habe ich das Interrupt deklariert
und mit dem Oszi habe ich auch direkt am Pin gemessen... nix

Was kann man denn da machen wenn das u0tb-Register nicht gelesen werden 
kann, einen anderen Debugger benutzen oder so?
Was kann ich denn eventuell da nehmen?

Thomas

von Martin (Gast)


Lesenswert?

Oder mal in der Hardware suchen ?!? Evtl ein Kurzschluss am Pin? Oder 
ist ein Pull-up/down am Ausgang von Nöten?

von Thomas (Gast)


Lesenswert?

das werde ich mal austesten,

danke dir

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.