一.串口工作原理:
1.由上面的串口电路可知具体流程如下:
发送:写数据——》buffer—》shifter—》TXDn-->RSTXDn--->PC
接收:PC---》RSRXDn---》RXDn--->shifter-->buffer--->取数据
2.由上图可知,
buffer有两种模式,FIFO模式 和 Non-FIFO模式。
如果使用FIFO模式,则需要配置FIFO Register,具有64 字节的缓存可用。
如果使用Non-FIFO模式,则不需要配置FIFO Register,但是只具有一个字节的缓存可用。
3.做串口模块的具体流程:
<1>.从串口电路图中可以知道,我们首先应该配置相应的引脚为相应的功能模式.在这里我们可以看到相应的引脚是GPH。
<2>.从用户手册中我们需要逐一地配置相应的寄存器.
这里我们先使用Non-FIFO模式,浏览后我们可以获取的信息有:
第一:我们需要配置帧格式设置(ULCON0).
第二:我们需要配置工作模式(UCON0).(工作模式包括DMA 中断 轮循模式 我们这里先采用轮循模式 ).
第三:我们需要配置波特率.
注:对于状态寄存器,我们不需要配置,除非有特殊的要求.
所以总结:对于串口模块,我们要做以下4步:
1.引脚设置
2.帧格式设置
3.工作模式设置(DMA 中断 轮询)
4.波特率设置.
以下是基于mini2440串口模块的源代码:
/************************************************
NAME : UART.C
DESC :
Revision: 2015.8.18 ver 0.0
************************************************/
#include "uart.h"
#include <stdio.h>
#include <stdarg.h>
/***********************************************
Function name : uart_init
Description : uart 初始化
Input parameter : none
Return : none
Others : uart init
*************************************************/
void uart_init()
{
//1.配置GPHCON中串口0的发送和接收的相应位
rGPHCON &= ~(0xf<<4);
rGPHCON |=(0xa<<4);
//2.设置一次可以传输多少数据位
rULCON0 |= (0x3<<0);
//3.配置串口控制器 设置发送接收模式 发送为DMA模式 接收为轮询模式
rUCON0 |= (0x9<<0);
//rUCON0 = 0<<12|0<<10|0<<4|1<<2|1;
//4.设置波特率
rUBRDIV0 = (int)(PCLK/(BAUDRATE*16)) - 1;
}
/***********************************************
Function name : getc
Description : 接收数据
Input parameter : none
Return : char
Others : none
*************************************************/
unsigned char uart_getc(void)
{
unsigned char ret;
while((rUTRSTAT0 & (1<<0))==0);
ret = rURXH0;
if(ret == '\r')
ret = '\n';
return ret;
}
/***********************************************
Function name : myputc
Description : 发送数据
Input parameter : char
Return : none
Others : none
*************************************************/
void myputc(unsigned char ch)
{
if(ch=='\n')
myputc('\r');
while((rUTRSTAT0 & 2) == 0);
rUTXH0 = ch;
}
/***********************************************
Function name : send_string
Description : 发送字符串
Input parameter : char *
Return : none
Others : none
*************************************************/
void uart_puts(const char *str)
{
while(*str)
{
myputc(*str);
str++;
}
myputc('\n');
}
/***********************************************
Function name : mygets
Description : 接收字符串
Input parameter : char *
Return : none
Others : none
*************************************************/
void mygets(char *str)
{
S32 i=0;
U8 ch;
while((ch=uart_getc())!='\n')
{
if(ch=='\b')
{
if(i>0)
{
myputc('\b');
myputc(' ');
myputc('\b');
i--;
}
}
else
{
str[i++] = ch;
myputc(ch);
}
}
str[i]='\0';
myputc('\n');
}
/***********************************************
Function name : uart_printf
Description : 发送信息
Input parameter : char *fmt....
Return : none
Others : none
*************************************************/
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_puts(string); //把格式化字符串从开发板串口送出去
va_end(ap); //ap付值为0,没什么实际用处,主要是为程序健壮性
}