Friday, April 1, 2011

printf and scanf in Keil with RealView Compiler



สำหรับการใช้ high-level formatted IO library function ใน Keil เราจำเป็นต้องเตรียม low-level driver ให้เหมาะสมกับ อุปกรณ์ IO ที่เราจะใช้ โดยสำหรับ low-level functions ดังกล่าว Real View library ได้เตรียมไว้แล้วใน file "retarget.c" ซึ่งถูกเก็บในkeil\arm\startup โดย printf และ scanf ก็ถูกเก็บไว้ใน "Retarget.c" ดังนั่น เราต้องนำ "retarget.c" มา add ใน project>>Manage>>Components,Environment,Book.. ด้วย


Main.c

/****************************************************************/
/* Compiler : Keil Realview MDK V4.13a */
/* Target MCU : Philips ARM7-LPC2368 */
/* : X-TAL : 12.00 MHz */
/* : PLL Setup = MSEL(12),NSEL(1) */
/* Create By : Eddy */
/* Last Update : 1/April/2011 */
/* Function : Example Use printf and scanf pass UART0*/
/*****************************************************************/


#include <LPC23xx.H> // LPC2368 MPU Register
#include <stdio.h>

// Pin I/O LED Control Maskbit
#define DIR_RS485 0x00080000 // P1.19(0000 0000 0000 x000 0000 0000 0000 0000)
#define RXD_RS485() IOCLR1 = DIR_RS485 // RS485 Direction = 0 (Receive)
#define TXD_RS485() IOSET1 = DIR_RS485 // RS485 Direction = 1 (Transmit)

char uart0_buf[]; // "sprint" UART[0] Buffer

/* pototype section */
void init_serial0 (void);

void sendchar(int ch); // Put Char To UART-0
int getkey(void); // Get Char From UART-0
void print_uart0(void); // Print String to UART0
void delay(unsigned long int); // Delay Time Function
int main(void)
{
int a,b,c;
init_serial0(); // Initilial UART0 = 9600,N,8,1
printf("\n a = ");
scanf("%d",&a);
printf("\n b = ");
scanf("%d",&b);
// Loop Receive & Echo Test //
while(1) // Loop Continue
{
// UART[0] Print //
c=a*b;
printf("\n c= %d",c);
delay(50000);
}
}

void init_serial0 (void)
{
PINSEL0 &= 0xFFFFFF0F; // Reset P0.2,P0.3 Pin Config
PINSEL0 |= 0x00000010; // Select P0.2 = TxD(UART0)
PINSEL0 |= 0x00000040; // Select P0.3 = RxD(UART0)

U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
//****************Baudrate UART = 9600,N,8,1***********************
U0DLL = 0x34; // DLM=DLest[15:8],DLL=DLest[7:0]
U0FDR = 0x21; // Fractional Divider--DivAddVal[3:0]/MulVal[7:4] = 1/2
U0LCR = 0x03; // DLAB = 0
}
/******************************/
/* Write Character To UART[0] */
/******************************/
void sendchar (int ch)
{
if (ch == '\n')
{
while (!(U0LSR & 0x20)); // Wait TXD Buffer Empty
U0THR = 0x0D; // Write CR
}

while (!(U0LSR & 0x20)); // Wait TXD Buffer Empty
U0THR = ch;
}
/******************************/
/* Get character From UART[0] */
/******************************/
int getkey()
{
while (!(U0LSR & 0x01)); // Wait RXD Receive Data Ready
return (U0RBR); // Get Receice Data & Return
}
/***************************/
/* Print String to UART[0] */
/***************************/
void print_uart0(void)
{
char *p; // Pointer Buffer
p = uart0_buf; // UART Buffer
do // Get char & Print Until null
{
sendchar(*p); // Write char to UART
p++; // Next char
}
while(*p != '\0'); // End of ASCII (null)
return;
}
/***********************/
/* Delay Time Function */
/* 1-4294967296 */
/***********************/
void delay(unsigned long int count1)
{
while(count1 > 0) {count1--;} // Loop Decrease Counter
}

Retarget.c

/******************************************************************************/
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/

#include <stdio.h>
#include <time.h>
#include <rt_misc.h>

#include "LPC23xx.H"

#pragma import(__use_no_semihosting_swi)


extern int sendchar(int ch); /* in Serial.c */
extern int getkey(void); /* in Serial.c */
extern long timeval; /* in Time.c */


struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;


int fputc(int ch, FILE *f) {
return (sendchar(ch));
}

int fgetc(FILE *f) {
return (sendchar(getkey()));
}


int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}


void _ttywrch(int ch) {
sendchar (ch);
}


void _sys_exit(int return_code) {
while (1); /* endless loop */
}

2 comments:

  1. ขอบคุณครับที่แบ่งปันความรู้

    ReplyDelete
  2. เป็นประโยชน์กับผู้ที่สนใจครับ มาเชียร์ครับ
    กำลังเล่น STM32 อยู่ครับ ไปยังไม่ถึงไหนเลยครับ

    ReplyDelete