📄 uart.c
字号:
#include "2410addr.h"
#include "clock.h"
#include "UART.h"
#include <stdarg.h>
#include <stdio.h>
// 这里只设置UART0
/*
功能:
0. port init
1. FIFO control register,不使用FIFO方式
2. MODEM control register,不使用AFC方式
3. Line control register,设置串口数据格式
4. UART CONTROL REGISTER,设置中断方式和时钟源等
5. 设置波特率
6. 延时
参数:
pclk: 使用波特率设置公式:UBRDIVn = (int)(PCLK/(bps x 16) ) -1设置
波特率中的PCLK。如果是0的话,就使用系统默认的PCLK,它在option.h
文件中定义。
baud: 波特率,例如115200等。
说明:
目前只能实现PCLK=2028000000/4,115200
*/
void Uart_Init(int pclk,int baud)
{
int i;
/* 如果是0的话,就使用系统默认的PCLK */
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 = (rGPHCON & (~0xFF)) | 0xaa; // 只设置UART0
rGPHUP = (rGPHUP & (~0xFF)) | 0xFF; // The pull up function is disabled GPH[10:0]
/* 设置FIFO control register,用于设置FIFO触发电平等。
UFCONn Bit Description Initial State
----------------------------------------
Tx FIFO Trigger Level [7:6] Determine the trigger level of transmit FIFO.
00 = Empty 01 = 4-byte
10 = 8-byte 11 = 12-byte
00
Rx FIFO Trigger Level [5:4] Determine the trigger level of receive FIFO.
00 = 4-byte 01 = 8-byte
10 = 12-byte 11 = 16-byte
00
Reserved [3] 0
Tx FIFO Reset [2] Auto-cleared after resetting FIFO
0 = Normal 1= Tx FIFO reset
0
Rx FIFO Reset [1] Auto-cleared after resetting FIFO
0 = Normal 1= Rx FIFO reset
0
FIFO Enable [0] 0 = Disable 1 = Enable 0
这里选择0,也就是不使用FIFO方式。
*/
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
/* MODEM control register,设置AFC(用nCTS,nRTS控制,nCTS表示准备好接收数据。对接收方来说nCTS就是nRTS。)
UMCONn Bit Description Initial State
------------------------------------------
Reserved [7:5] These bits must be 0's 00
Auto Flow Control (AFC) [4] 0 = Disable 1 = Enable 0
Reserved [3:1] These bits must be 0's 00
Request to Send [0] If AFC bit is enabled, this value will be ignored. In this case
the S3C2410A will control nRTS automatically.
If AFC bit is disabled, nRTS must be controlled by software.
0 = 'H' level (Inactivate nRTS)
1 = 'L' level (Activate nRTS)
0
这里设置为0,表示不使用AFC方式,可用software控制nCTS和nRTS信号线。
*/
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable
//UART0
/* 设置Line control register,用于设置Infra-red方式已经串口信号格式
ULCONn Bit Description Initial State
---------------------------------------
Reserved [7] 0
Infra-Red Mode [6] Determine whether or not to use the Infra-Red mode.
0 = Normal mode operation
1 = Infra-Red Tx/Rx mode
0
Parity Mode [5:3] Specify the type of parity generation and checking during UART
transmit and receive operation.
0xx = No parity
100 = Odd parity
101 = Even parity
110 = Parity forced/checked as 1
111 = Parity forced/checked as 0
000
Number of Stop Bit [2] Specify how many stop bits are to be used for end-of-frame
signal.
0 = One stop bit per frame
1 = Two stop bit per frame
0
Word Length [1:0] Indicate the number of data bits to be transmitted or received per
frame.
00 = 5-bit 01 = 6-bit
10 = 7-bit 11 = 8-bit
00
这里设置为0x3=00000011B,表示非Infra-red mode,没有parity,One stop bit,8bit的数据
*/
rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
/* UART CONTROL REGISTER,选择时钟源,Tx和Rx的电平的触发方式,Rx Time Out Enable,Rx错误中断允许,LoopBack设置。
发送接收是polling、中断、还是DMA方式。
UCONn Bit Description Initial State
-------------------------------------------
Clock Selection [10] Select PCLK or UEXTCLK for the UART baud rate.
0=PCLK : UBRDIVn = (int)(PCLK / (bps x 16) ) -1
1=UEXTCLK(@GPH8) : UBRDIVn = (int)(UEXTCLK / (bps x 16) ) -1
0
Tx Interrupt Type [9] Interrupt request type.
0 = Pulse (Interrupt is requested as soon as the Tx buffer becomes
empty in Non-FIFO mode or reaches Tx FIFO Trigger Level in FIFO
mode.)
1 = Level (Interrupt is requested while Tx buffer is empty in Non-FIFO
mode or reaches Tx FIFO Trigger Level in FIFO mode.)
0
Rx Interrupt Type [8] Interrupt request type.
0 = Pulse (Interrupt is requested the instant Rx buffer receives the
data in Non-FIFO mode or reaches Rx FIFO Trigger Level in FIFO
mode.)
1 = Level (Interrupt is requested while Rx buffer is receiving data in
Non-FIFO mode or reaches Rx FIFO Trigger Level in FIFO mode.)
0
Rx Time Out
Enable
[7] Enable/Disable Rx time out interrupt when UART FIFO is enabled.
The interrupt is a receive interrupt.
0 = Disable 1 = Enable
0
Rx Error Status
Interrupt Enable
[6] Enable the UART to generate an interrupt upon an exception, such as
a frame error, or overrun error during a receive operation.
0 = Do not generate receive error status interrupt.
1 = Generate receive error status interrupt.
0
Loopback Mode [5] Setting loopback bit to 1 causes the UART to enter the loopback
mode. This mode is provided for test purposes only.
0 = Normal operation 1 = Loopback mode
0
Reserved [4] Reserved 0
Transmit Mode [3:2] Determine which function is currently able to write Tx data to the
UART transmit buffer register. (UART Tx Enable/Disable)
00 = Disable
01 = Interrupt request or polling mode
10 = DMA0 request (Only for UART0),
DMA3 request (Only for UART2)
11 = DMA1 request (Only for UART1)
00
Receive Mode [1:0] Determine which function is currently able to read data from UART
receive buffer register. (UART Rx Enable/Disable)
00 = Disable
01 = Interrupt request or polling mode
10 = DMA0 request (Only for UART0),
DMA3 request (Only for UART2)
11 = DMA1 request (Only for UART1)
00
这里设置为0x245即:
// [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
/* 计算波特率,这里加入0.5可能是四舍五入,为了更精确 */
//rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );Baud rate divisior register 0
rUBRDIV0= 27; //PCLK=2028000000/4,115200
//rUBRDIV0= 17; //135000000/4,115200
/* Delay */
for(i=0;i<100;i++);
}
/*
功能:发送字符data
参数:data应该只有8bit有效。
输入:whichUart,当前使用的Uart。
*/
void Uart_SendByte(int data)
{
/* 对于\n对发送一个\r字符 */
if(data=='\n')
{
/* UART TX/RX STATUS REGISTER,可查看transmitter buffer&shifter empty,buffer empty, received data
UTRSTATn Bit Description Initial State
-----------------------------------------
Transmitter empty [2] Set to 1 automatically when the transmit buffer register has
no valid data to transmit and the transmit shift register is
empty.
0 = Not empty
1 = Transmitter (transmit buffer & shifter register) empty
1
Transmit buffer empty [1] Set to 1 automatically when transmit buffer register is empty.
0 =The buffer register is not empty
1 = Empty
(In Non-FIFO mode, Interrupt or DMA is requested.
In FIFO mode, Interrupt or DMA is requested, when Tx
FIFO Trigger Level is set to 00 (Empty))
If the UART uses the FIFO, users should check Tx FIFO
Count bits and Tx FIFO Full bit in the UFSTAT register
instead of this bit.
1
Receive buffer data ready [0] Set to 1 automatically whenever receive buffer register
contains valid data, received over the RXDn port.
0 = Empty
1 = The buffer register has a received data
(In Non-FIFO mode, Interrupt or DMA is requested)
If the UART uses the FIFO, users should check Rx FIFO
Count bits and Rx FIFO Full bit in the UFSTAT register
instead of this bit.
0
这里检测bit2是否为1,即当前是否已经发送完毕(在non-FIFO模式下)
*/
while(!(rUTRSTAT0 & 0x2));
/* 每个字符之间至少有10个delay,可能是由于超级终端的反应比较慢的原因 */
Delay(10); //because the slow response of hyper_terminal
/* UART TRANSMIT BUFFER REGISTER
写入以后即发送(对于big-endin和little-endin地址是不一样的)*/
WrUTXH0('\r');
}
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
Delay(10);
WrUTXH0(data); //这个是个宏定义
}
/*
功能:使用阻塞方式接收一个字符
返回值:接收的字符
*/
char Uart_Getch(void)
{
/* 主要用查询的方式检查接收寄存器,如果发现接收到则读取数据 */
while(!(rUTRSTAT0 & 0x1)); //Receive data ready
return RdURXH0();
}
/*
功能:发送字符串pt
*/
void Uart_SendString(char *pt)
{
while(*pt)
Uart_SendByte(*pt++);
}
void Uart_SendUWord32(unsigned int value)
{
int i;
char c;
/* print every 4 bit */
for(i = 0; i < 32 / 4; i++)
{
c = (char)(value >>(32-4));
if(c >= 10)
c = c - 10 + 'A';
else
c = c + '0';
Uart_SendByte(c);
value <<= 4;
}
}
#ifdef COMPLEX_PRINTF
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);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -