/*
此文件主要學習如何配置UART0,怎樣單字符輸入和輸出, 怎樣進行字符串的輸入和輸出;
*/
#include <stdarg.h>
#include "def.h"
#include "system.h"
#include "sysc.h"
#include "uart.h"
#define Inp32(ADDR) *((volatile u32 *)ADDR)
#define Outp32(ADDR,data) *((volatile u32 *)ADDR)=data
#define UART0 ((volatile UART_REGS*)0X7F005000)
void Uart_Port_Init(int channal);
void Uart_Init(u32 baud, int channal);
void Uart_Putc(char ch);
void Delay(int time);
void Uart_Puts(char *str);
void Uart_Printf(char *fmt,...);
char* Uart_Gets(char *);
char Uart_Getc(void);
char Uart_Getch(void);
char str[256];
void main(void)
{
SYSC_GetClkInform();
Uart_Init(115200, 0);
Uart_Puts("注意:按 ECS再按回車鍵 退出測試!! \n");
Uart_Printf("首先輸出字符串:The world is currut be 5\n");
Uart_Printf("The world is currut be %d \n",5);
while(str[0] != 0x1b)
{
Uart_Gets(str);
Uart_Printf("你輸入的是: %s \n",str);
}
Uart_Puts("你已經推出了程序,別做無謂針扎了....\n");
while(1);
}
//延時函數;
void Delay(int time)
{
int i;
for(;time > 0; time--)
for(i=0;i < 3000; i++);
}
//端口初始化;
void Uart_Port_Init(int channal)
{
if(channal == 0)
{
u32 uConValue;
#define rGPACON 0X7F008000
uConValue = Inp32(rGPACON);
uConValue = (uConValue & ~0xff) | 0x22; //配置為UART0功能;
Outp32(rGPACON,uConValue);
#define rGPAPUD 0X7F008008
uConValue = Inp32(rGPAPUD);
uConValue &= ~0xf; //低4位配置為0000,上下拉電阻除能;
Outp32(rGPAPUD,uConValue);
}
}
//uart初始化;
void Uart_Init(u32 baud, int channal)
{
u32 pclk;
u32 uConValue;
//if(pclk == 0)
pclk = g_PCLK;
Uart_Port_Init(channal);
//配置UART0寄存器;
if(channal == 0)
{
UART0->rUlCon = 0x3;//配置為8位數據,1位停止位,0位校驗位;
UART0->rUCon = 0x805;//配置為中斷或輪詢模式,使用pclk作為波特率;
UART0->rUfCon = 0x0;//配置為非FIFO模式;
UART0->rUmCon = 0x0;//配置為非中斷,非流控模式;
uConValue = (int)(pclk/16./baud) - 1;
UART0->rUbrDiv = uConValue;//配置波特率;
Delay(100);
}
}
//單字符輸出;
void Uart_Putc(char ch)
{
if(ch == '\n')
{
while(!((UART0->rUtrStat) & 0x2));
UART0->rUtxh = '\r';
}
while(!((UART0->rUtrStat) & 0x2));
UART0->rUtxh = ch;
}
//字符串輸出
void Uart_Puts(char *str)
{
while(*str)
{
Uart_Putc(*str++);
}
}
//格式化輸出;
void Uart_Printf(char *fmt,...)
{
char str[256];
va_list ap;
va_start(ap,fmt); //va_start() 與 va_end() 需要對稱
vsprintf(str,fmt,ap);
Uart_Puts(str);
va_end(ap);
}
//單字符阻塞型輸入;
char Uart_Getc(void)
{
while(!((UART0->rUtrStat) & 0x1));
return (UART0->rUrxh);
}
//無阻塞型字符輸入;
char Uart_Getch(void)
{
//if((UART0->rUtrStat) & 0x1)
return(UART0->rUrxh);
}
//字符寸輸入;
char* Uart_Gets(char *str)
{
char *ptr = str;
char c;
while((c = Uart_Getc()) != '\r')
{
if(c == '\b')
{
if(ptr < str)
{
Uart_Putc('\b');
Uart_Putc(' ');
Uart_Putc('\b');
str--;
}
}
else
{
*str++ = c;
Uart_Putc(c);
}
}
Uart_Putc(c);
Uart_Putc('\n');
*str = '\0';
return (ptr);
}