S3C2440的串口比较简单,基本上就是波特率、数据位、校验位、通道号、停止位配置OK即可
//===================================================================
// File Name : 2440lib.c
// Function : S3C2410 PLL,Uart, LED, Port Init
// Date : March 20, 2002
// Version : 0.0
// History
// 0.0 : Programming start (February 20,2002) -> SOP
//===================================================================
//#define GLOBAL_CLK 1//hzh
#include "UART.h"
//***************************[ UART ]******************************
static int whichUart=0;
static char str[30];
void __irq UART_INT (void);
/*************************************************************************************
***函数名:Uart_Init()
***功能:串口初始化,波特率 115200 8位数据位,无校验位,1位停止位
***参数:ch 串口通道号
***返回:无
*************************************************************************************/
void Uart_Init(int pclk,int baud)
{
int i;
if(pclk == 0)
pclk = PCLK;
//*** PORT H GROUP
//Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0
//Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
//Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10
rGPHCON = 0x00aaaa;
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
rUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disable
rUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable
rUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable
//UART0
rULCON0 = 0x3; //Line control register : Normal,,No parity1 stop,8 bits
// [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0]
// Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode
// 0 1 0 , 0 1 0 0 , 01 01
// PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling
rUCON0 = 0x245; // Control register
rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); // Baud rate divisior register 0
//UART1
rULCON1 = 0x3; //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
rUCON1 = 0x245; //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止 //信号,传输模式为中断请求模式,接收模式也为中断请求模式。
rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );
//UART2
rULCON2 = 0x3; //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
rUCON2 = 0x245; //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止 //信号,传输模式为中断请求模式,接收模式也为中断请求模式。
rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 );
for(i=0;i<100;i++);
}
/*************************************************************************************
***函数名:Uart_Select()
***功能:串口选择。函数里面的whichUart在后面的函数中有引用,决定用哪个UART。
***参数:ch 串口通道号
***返回:无
*************************************************************************************/
void Uart_Select(int ch)
{
whichUart = ch;
}
/*************************************************************************************
***函数名:Uart_TxEmpty()
***功能:等待。如果UART0、1、2的transmit shifter register和 buffer register,
一直是空的,就一直等待,直到不为空,就跳出循环
***参数:ch 串口通道号
***返回:无
*************************************************************************************/
void Uart_TxEmpty(int ch)
{
if(ch==0)
while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty.
else if(ch==1)
while(!(rUTRSTAT1 & 0x4)); //Wait until tx shifter is empty.
else if(ch==2)
while(!(rUTRSTAT2 & 0x4)); //Wait until tx shifter is empty.
}
/*************************************************************************************
***函数名:Uart_Getch()
***功能:从终端上获取敲入的字符。 返回值为char类型。RdURXH有数据时,返回URXH的
数据。当URXH没有数据时,总是等待,直到有数据。这个函数,非要从终端那
获得字符,否则一直等待。
***参数:无
***返回:终端上敲入的字符
*************************************************************************************/
char Uart_Getch(void)
{
if(whichUart==0)
{
while(!(rUTRSTAT0 & 0x1)); //Receive data ready
return RdURXH0();
}
else if(whichUart==1)
{
while(!(rUTRSTAT1 & 0x1)); //Receive data ready
return RdURXH1();
}
else if(whichUart==2)
{
while(!(rUTRSTAT2 & 0x1)); //Receive data ready
return RdURXH2();
}
return 0 ;
}
/*************************************************************************************
***函数名:Uart_GetKey()
***功能:这个与Uart_Getch 不同的是,当URXH没有数据时返回0。有数据时,返回数据,
这个函数用来查看URXH中的值。
***参数:无
***返回:获取PC机按键
*************************************************************************************/
char Uart_GetKey(void)
{
if(whichUart==0)
{
if(rUTRSTAT0 & 0x1) //Receive data ready
return RdURXH0();
else
return 0;
}
else if(whichUart==1)
{
if(rUTRSTAT1 & 0x1) //Receive data ready
return RdURXH1();
else
return 0;
}
else if(whichUart==2)
{
if(rUTRSTAT2 & 0x1) //Receive data ready
return RdURXH2();
else
return 0;
}
return 0 ;
}
/*************************************************************************************
***函数名:Uart_GetString()
***功能:从终端那得到一个字符串,并存储到 字符型指针string 中
***参数:string 存放接收到的字符串
***返回:
*************************************************************************************/
void Uart_GetString(char *string)
{
char *string2 = string; //指针string2用来做比较
char c;
while((c = Uart_Getch())!='\r') //输入的字符不是 回车,就存储到string中
{
if(c=='\b') //输入的是 退格(删除) ,
{
if( (int)string2 < (int)string ) //sring如果还没有输入数据(此时string2==string),就删除,不做任何操作。
{
Uart_Printf("\b \b"); //实际中,我在调试的时候发现Uart_Printf("\b");并不能删除显示字符。Uart_Printf(" \b");也不能。Uart_Printf("\b \b\b \b");可以删除2个字符
string--; //有数据才删除
}
}
else
{
*string++ = c; //输入的 不是 回车和退格 ,将数据存储到string中
Uart_SendByte(c); //回写,没输入一个数据,在 超级终端上显示
}
}
*string='\0'; // 在C语言中没有字符串变量,字符串不能存放在一个变量中,只能存放在字符型数组中。以'\0'作为字符串结束的标志。'\0'不计入串的长度。
Uart_SendByte('\n'); //在超级终端上显示换行
}
/*************************************************************************************
***函数名:Uart_GetIntNum()
***功能:此函数是将转换为10进制,因为从UART从 超级终端 得到的10进制、或16进制,
都是当做字符在处理。这个函数,就是将输入的如:"0X12BD"或"-0x334ACC"或"-BBH"
或"123"之类的字符串,转换成10进制。由此可知,不支持输入二进制和八进制表示的数。
***参数:无
***返回:接收到的-十进制整数数字
*************************************************************************************/
int Uart_GetIntNum(void)
{
char str[30]; //定义字符型数组。
char *string = str; //将数组的首地址,赋值给指针string。数组名就是首地址
int base = 10; //是10进制
int minus = 0; //判断是否为负,为负是minus=1
int result = 0; //最后转换的结果,因为从 超级终端 那得到的都是字符
int lastIndex; //数组的最后一个字符是什么
int i; //从超级终端那得到字符,并存储到string所指向的数组str[]中。
Uart_GetString(string); //如果是负数
if (string[0]=='-') //更新负数标志
{
minus = 1; //string指向str[1]
string++;
}
/*除去那个负号外,或没有负号,如果是以0x或0X开头,即16进制*/
if (string[0]=='0' && (string[1]=='x' || string[1]=='X'))
{
base = 16; //指示为16进制
string += 2; //指向str[2],因为str[0]存储了字符'0'、str[1]存储了字符'x'或'X'
}
/*strlen函数,求字符串的长度。减1是因为,数组下标从0开始。'\0'不计入串的长度。*/
lastIndex = strlen(string) - 1;
if (lastIndex<0) //说明0x或0X或- 后面没有任何内容
return -1;
if (string[lastIndex]=='h' || string[lastIndex]=='H' ) //如果16进制是用H或h表示的
{
base = 16; //指示是16进制的数
string[lastIndex] = 0; //把H或h去掉
lastIndex--; //数组最后一位不要,即存储H或h的那位
}
if (base==10) //如果是10进制
{
result = atoi(string); //atoi函数,将字符串转换成整型,转换后赋值给result
result = minus ? (-1*result):result; //是负数,就在 乘以 -1
}
/****************************如果是16进制******************************************/
else
{
for (i=0;i<=lastIndex;i++)
{
if (isalpha(string[i])) //isalpha函数,判断是否是字母。
{
if (isupper(string[i])) //isupper函数,判断是否是大写字母
result = (result<<4) + string[i] - 'A' + 10; //将大写字母转换为相应的10进制
else
result = (result<<4) + string[i] - 'a' + 10; //将小写字母转换为相应的10进制
} //result<<4,左移4位相当于乘以16,举例说明更好理解。如果字符串为ABCH,
//处理A:result=0X16+0+10,处理B:result=10(A)X16+11,处理C :result=10(A)X16X16+11(B)X16,
//处理C:result=10(A)X16X16X16+11(B)X16X16+12 。这样才能将16进制转化为正确的10进制
else //如果是数字字符,转换成十进制数,分析过程同上
result = (result<<4) + string[i] - '0';
}
result = minus ? (-1*result):result; //是负数,别忘了乘以负号
}
return result; //将正确的10进制返回
}
/*************************************************************************************
***函数名:Uart_GetIntNum_GJ()
***功能:接收10进制的数,将'0'至'9'的字符,转换成10进制数。
***参数:无
***返回:接收到的-十进制数字
*************************************************************************************/
int Uart_GetIntNum_GJ(void)
{
char string[16] ;
char *p_string = string ;
char c;
int i = 0 ;
int data = 0 ;
while( ( c = Uart_Getch()) != '\r' )
{
if(c=='\b') p_string--;
else *p_string++=c;
Uart_SendByte( c ) ;
}
*p_string = '\0';
i = 0 ;
while( string[i] != '\0' )
{
data = data * 10 ;
if( string[i]<'0'||string[i]>'9' )
return -1 ;
data = data + ( string[i]-'0' ) ;
i++ ;
}
return data ;
}
/*************************************************************************************
***函数名:Uart_SendByte()
***功能:发送一个字符
***参数:要发送字符数据
***返回:无
***备注 : 函数中的 WrUTXH0('\r')相当于
(*(volatile unsigned char *)0x50000020)=(unsigned char)('\r')。
而0x50000020为UTXH0寄存器的地址。因为前面初始化串口的时候,FIFO disable 。
相当于将 '\r' 发送赋值给UTXH0,然后UART发送 。UTXH0为 UART channel 0 transmit
buffer register 。 rUTRSTAT0 & 0x2 取出rUTRSTAT0 寄存器中的第2位,含义为
Transmit buffer是否为空 。为1时表示空。while(!(rUTRSTAT0 & 0x2)); 注意这是一
个空循环语句。后面有个分号,这代表空循环语句,直到THR为空时,就跳出循环,
执行下一条。WrUTXH0(data);
*************************************************************************************/
void Uart_SendByte(int data)
{
if(whichUart==0)
{
if(data=='\n')
{
while(!(rUTRSTAT0 & 0x2)); //等待,直到发送缓冲区为空
WrUTXH0('\r'); //发送回车符
}
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
WrUTXH0(data); //发送字符
}
else if(whichUart==1)
{
if(data=='\n')
{
while(!(rUTRSTAT1 & 0x2));
rUTXH1 = '\r';
}
while(!(rUTRSTAT1 & 0x2)); //Wait until THR is empty.
rUTXH1 = data;
}
else if(whichUart==2)
{
if(data=='\n')
{
while(!(rUTRSTAT2 & 0x2));
rUTXH2 = '\r';
}
while(!(rUTRSTAT2 & 0x2)); //Wait until THR is empty.
rUTXH2 = data;
}
}
/*************************************************************************************
***函数名:Uart_SendString()
***功能:发送字符串
***参数:字符串指针
***返回:无
*************************************************************************************/
void Uart_SendString(char *pt)
{
while(*pt)
Uart_SendByte(*pt++);
}
/*************************************************************************************
***函数名:Uart_Printf()
***功能:串口打印函数,相当于标准C中的printf()
***参数:可变参
***返回:无
***If you don't use vsprintf(), the code size is reduced very much.
*************************************************************************************/
void Uart_Printf(char *fmt,...)
{
va_list ap;
char string[256];
va_start(ap,fmt);
vsprintf(string,fmt,ap);
Uart_SendString(string);
va_end(ap);
}
/*****************************************************************************
***函数名:UART_INT_initialize
***功能:串口中断初始化
***参数:无
***返回:无
*****************************************************************************/
void UART_INT_initialize (void)
{
//第三步 清子中断标志,开子屏蔽
ClearSubPending (BIT_SUB_RXD0);
EnableSubIrq(BIT_SUB_RXD0);
//第四步 清总中断
ClearPending(BIT_UART0); //清除INTPND,SRCPND中断标示
//第五步:设置中断服务函数入口
pISR_UART0 = (unsigned)UART_INT ;
//开总中断
EnableIrq(BIT_UART0);
}
/*****************************************************************************
***函数名:UART_INT()
***功能:串口中断服务函数
***参数:无
***返回:无
*****************************************************************************/
void __irq UART_INT (void)
{
static U8 i;
static U8 time_flag = 0;
static U8 password_flag = 0;
U8 ch;
if(rUTRSTAT0 & 0x1) //判断接收缓存是否准备好
{
ch = rURXH0;
if (ch != '#')
{
str[i++] = ch;
while(!(rUTRSTAT0 & 0x2));
rUTXH0 = ch;
}
else if ((time_flag == 0)&(password_flag == 0))
{
str[i]='\0';
i=0;
if (!(strcmp(str,"time" ))) //灭LED
{
time_flag = 1;
}
if (!(strcmp(str ,"password" ))) //亮LED
{
password_flag = 1;
}
if (!(strcmp(str ,"bellon" ))) //蜂鸣器响
{
rGPBCON |=0x01;
rGPBDAT |= 0x1;
}
if (!(strcmp(str ,"belloff" ))) //蜂鸣器不响
{rGPBDAT &= 0x1e0;}
}
else if(time_flag == 1)
{
check_ASCII_table((U8*)str,(U8*)str,14);
combine((U8*)str,(U8*)str,14);
RTC_time_set(str[0],str[1],str[2],str[3],str[4],str[5],str[6]);
time_flag = 0;
i = 0;
}
else if(password_flag == 1)
{
check_ASCII_table((U8*)str,(U8*)str,6);
password_administrator = str[0]*100000+str[1]*10000+
str[2]*1000+str[3]*100+str[4]*10+str[5];
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[0]);
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[1]);
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[2]);
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[3]);
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[4]);
// Wr24C080(0xa0,(U8)DOOR_PASSWOR1_1,str[5]);
password_flag = 0;
i = 0;
store_password = 1;
}
}
ClearSubPending (BIT_SUB_RXD0);
ClearPending(BIT_UART0); //清除INTPND,SRCPND中断标示
}
头文件如下
#ifndef UART_H
#define UART_H
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include <stdarg.h> //主要是定义Uart_Print,实现字符串格式化输出。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "RTC.h"
#include "common_functions.h"
#include "2440lib.h"
#include "global_value.h"
/*************************************************************************************
***函数名:Uart_Init()
***功能:串口初始化,波特率 115200 8位数据位,无校验位,1位停止位
***参数:ch 串口通道号
***返回:无
*************************************************************************************/
extern void Uart_Init(int pclk,int baud);
extern void Uart_SendByte(int data);
extern void Uart_Printf(char *fmt,...);
extern void UART_INT_initialize (void);
#endif