支持3个串口,分为两种电平,TTL和RS232,其中引出来的是RS232电平的串口,TTL电平的串口为CON1,CON2,CON3,但是这两种电平公用那三个串口。
下面看电路图:
可见TTL电平的串口直接与2440相连,且只使用了RXD,TXD信号
而RS232电平的串口则进过MAX3232的电平转,UART2使用了转换过的RSTXD,RSRXD信号,
而UART0特殊,使用了RSRXD,RSTXD,CTS,RTS四个信号
UART1也可以使用RSRXD,RSTXD,CTS,RTS四个信号,只是这里没有设计
CTS,RTS也被称为自动流控信号(AFC)
相关寄存器:
FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
非自动流控制的例子(软件控制nRTS 和nCTS)
带FIFO 的Rx 操作
1. 选择接收模式(中断或DMA 模式)。
2. 检查UFSTATn寄存器中Rx FIFO的计数。如果该值小于32,用户必须设置UMCONn[0]的值为'1(' 激活nRTS),
并且如果该值大于等于32 用户必须设置UMCONn[0]的值为'0'(取消激活nRTS)。
3. 重复步骤2。
带FIFO 的Tx 操作
1. 选择发送模式(中断或DMA 模式)。
2. 检查UMSTATn[0]的值。如果值为'1'(激活nCTS),用户写入数据到Tx FIFO 寄存器中。
波特率发生UBRDIVn = (int)( UART 时钟 / ( 波特率 × 16) ) - 1(UART 时钟:PCLK,FCLK/n 或UEXTCLK)
例如,如果波特率为115200 bps 并且UART 时钟为40 MHz,则UBRDIVn 为:UBRDIVn = (int)(40000000 / (115200 x 16) ) - 1
= (int)(21.7) - 1 [取最接近的整数]
= 22 - 1 = 21
- //程序在开发板上运行,只要PC端的波特率和该程序中的波特率一致即可通讯
- //PC端任何的输出,开发板上都可以接受
- //同样开发板上任何的回馈,PC端也都可以接受
- #include <stdio.h>
-
#include "def.h"
-
#include "2440addr.h"
-
#include "pll.h"
-
-
extern int data; //发送接收连接参数
-
extern void pll_(void);
-
extern void Port_Init(void);
-
extern void Uart_Init(int pclk,int baud);
-
extern void Uart_SendByte(int data);
-
extern void Uart_Printf(char *fmt,...);
-
extern void Uart_Getch(void);
-
extern void delay(int times);
-
extern Led_port_init(void);
-
-
void Main(void)
-
{
-
int i,z = 0x1e0;
-
Port_Init();
-
pll_();
-
Uart_Init( 0,115200 ); //我们只使用UART0,无aFIFO
-
delay(100000);
-
Uart_Printf("\n");
-
delay(100000);
-
Uart_Printf("串口测试开始!请输入:\n"); //开发板发往PC
-
Uart_Printf("a:亮灯\n?:退出\n");
-
Uart_Printf("其他键:灭\n");
-
Led_port_init();
-
-
while(1) //查询收发
-
{
-
Uart_Getch(); //从PC端接收
-
Uart_SendByte(data); //发送给PC
-
Uart_Printf("\n");
-
Uart_Printf("数据已经接收\n"); //发送给PC,在PC上显示
-
-
if(data == 'a')
-
{
-
z = 0x1e0;
-
for(i=0;i<4;i++)
-
{
-
rGPBDAT = z <<= 1 ;
-
delay(100000);
-
}
-
}
-
-
else
-
rGPBDAT = 0xffff;
-
-
if(data == '?')
-
{
-
Uart_Printf("\n");
-
Uart_Printf("你已经退出!\n");
-
break;
-
}
-
}
-
}
- #include "def.h"
-
#include "2440addr.h"
-
#include "pll.h"
-
-
#include <stdarg.h>
-
#include <string.h>
-
#include <stdlib.h>
-
#include <stdio.h>
-
#include <ctype.h>
-
-
int data; //发送接收连接参数
-
-
void Port_Init(void)
-
{
-
//*** 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 = 0x00faaa; //不使用CLKOUT1,CLKOUT0,UCLK,设为输入
-
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
-
}
-
-
-
void Uart_Init(int pclk,int baud)
-
{
-
int i;
-
if(pclk == 0)
-
pclk = PCLK;
-
rULCON0 = 0x3; //普通模式,无奇偶校验,一个停止位,8个数据位
-
rUCON0 = 0x245; //PCLK作为波特率,发送/接收采用电平中断,禁止超时中断,产生接受错误中断,
-
//非环回模式,不发出断点信号,发送/接受采用中断轮询,
-
rUFCON0 = 0x0; //FIFO disable
-
rUMCON0 = 0x0; //AFC(自动流控) disable
-
rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0
-
for(i=0;i<100;i++);
-
}
-
-
-
/********************************************
-
UTXH0 :UART 通道0 发送缓冲寄存器,【7:0】 发送数据
-
0x50000020(L) 小端模式
-
0x50000023(B) 小端模式
-
URXH0 :UART 通道0 接收缓冲寄存器,【7:0】 接收数据
-
0x50000024(L) 小端模式
-
0x50000027(B) 小端模式
-
-
UTRSTAT0 : UART 通道0 Tx/Rx 状态寄存器
-
0位判断接受缓存器内是否有可接收的数据,
-
第1位和第2位判断发送缓存器中是否为空
-
*********************************************/
-
void Uart_SendByte(int data)
-
{
-
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
-
WrUTXH0(data); //将要发送的内容写入发送缓冲寄存器,一次8位
-
//小端模式
-
}
-
-
-
-
/*********************************************
-
发送字符串
-
*********************************************/
-
void Uart_SendString(char *pt)
-
{
-
while(*pt)
-
Uart_SendByte(*pt++);
-
}
-
-
-
/*********************************************
-
显示字符
-
*********************************************/
-
void Uart_Printf(char *fmt,...) //不确定参数的表示,占位符
-
{
-
va_list ap; //定义ap为参数的列表指针
-
char string[256];
-
va_start(ap,fmt); //指定参数列表集合中开始的参数,指针fmt指向要发送的字符串
-
vsprintf(string,fmt,ap);
-
Uart_SendString(string);
-
va_end(ap); //参数列表结束,从指定开始的参数到了最后一个参数
-
}
-
-
-
/***************************************************
-
四个重要的宏: va_list va_start va_arg va_end
-
va_list 定义了参数列表指针
-
va_start 指定列表开始的参数
-
va_arg 取出列表中的参数, 顺序为函数传递参数顺序(从左到右)
-
va_end 参数列表结束
-
-
Uart_Printf()函数分析
-
-
ARM与PC机通信,常通过Uart_Printf()这个函数在上位机里输出信息。下面来详细分析这个函数功能。
-
-
原形:
-
-
//-----------------------------------------------------------------
-
-
void Uart_Printf(char *fmt,...) //...表示可变参数(多个可变参数组成一
-
-
个列表,后面有专门的指针指向他),不限定个数和类型,
-
-
{
-
-
va_list ap;//初始化指向可变参数列表的指针
-
-
char string[256];
-
-
va_start(ap,fmt);//将第一个可变参数的地址付给ap,即ap指向可变参数列
-
-
表的开始
-
-
vsprintf(string,fmt,ap);//将参数fmt、ap指向的可变参数一起转换成格式
-
-
化字符串,放string数组中,其作用同
-
-
sprintf(),只是参数类型不同
-
-
Uart_SendString(string); //把格式化字符串从开发板串口送出去
-
-
va_end(ap); //ap付值为0,没什么实际用处,主要是为程序健壮性
-
-
}//-----------------------------
-
-
va_list 在这个宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个文件。
-
-
-
函数名: vsprintf
-
-
功 能: 送格式化输出串到指定数组中
-
-
用 法: int vsprintf(char *string, char *format, va_list param);
-
-
vsprintf与sprintf功能是一样的,即把格式化字符串输出到指定数组中,
-
sprintf(char *string, char *farmat [,argument,...])函数的参数从第二个参数开始与printf是一样的,
-
只是sprintf是输出到指定数组中,printf是输出到屏幕(一个标准输出文件),因而sprintf多了char *string这参数。
-
************************************************/
-
-
-
-
-
/*********************************************
-
接收字符
-
*********************************************/
-
void Uart_Getch(void)
-
{
-
while(!(rUTRSTAT0 & 0x1)); //Receive data ready
-
data = RdURXH0();
-
}
阅读(1913) | 评论(0) | 转发(0) |