s3c2410开发板x串口控制器中,哪个寄存器用来设置串口比特率

串口驱动分析(二)-linux-电脑编程网串口驱动分析(二)作者: linuxdevelop  和相关&&
3.7 发送中断函数uart_tx_interrupt
static void s3c2410uart_tx_interrupt(int irq, void *dev_id,
struct pt_regs *reg) {
struct uart_info *info = dev_
struct uart_port *port = info-&
&
if (port-&x_char) {
UART_UTXH(port) = port-&x_
port-&icount.tx++;
port-&x_char = 0;
&
if (info-&xmit.head == info-&xmit.tail
|| info-&tty-&stopped || info-&tty-&hw_stopped) {
s3c2410uart_stop_tx(info-&port, 0);
count = port-&fifosize && 1;
UART_UTXH(port) = info-&xmit.buf[info-&xmit.tail];
info-&xmit.tail = (info-&xmit.tail + 1) & (UART_XMIT_SIZE - 1);
port-&icount.tx++;
if (info-&xmit.head == info-&xmit.tail)
} while (--count & 0);
if (CIRC_CNT(info-&xmit.head, info-&xmit.tail,
UART_XMIT_SIZE) & WAKEUP_CHARS)
uart_event(info, EVT_WRITE_WAKEUP);
if (info-&xmit.head == info-&xmit.tail)
s3c2410uart_stop_tx(info-&port, 0);
&
&
&&&&&&&&&&& (1) 首先查看port中的x_char是不是为0,不为0则把x_char发送出去。x_char是xon/xoff的意思,每发一个字节时在开始前先发xon信号,在结束时发xoff。
&&&&&&&&&&& (2) 如果x_char没有被设置,再看环形缓冲区是否为空,或者info-&tty-&stopped 和 info-&tty-&hw_stopped 两个位是不是为1,如果这些条件成立的话,就停止发送。Tty-&stop指示tty设备是否停止,tty-&hw_stop指示tty设备的硬件是否停止了,以上两个位都可以通过ttydriver来设定,否则的话说明有数据要发送。
&&&&&&&&&&& (3) 如果以上条件都通过了,就利用一个while循环正式发送数据了,从环形缓冲尾巴上取一个数赋给UART_UTXH(port)(发送FIFO), UART_UTXH(port) = info-&xmit.buf[info-&xmit.tail],这条语句就是把数据送到发送FIFO中,然后计数++,循环一共进行fifosize/2次,也就是一次只能发送8 byte。
&&&&&&&&&&& (4)循环传送完一次后,再查看缓冲器里还剩余多少数据,如果少于WAKEUP_CHARS(256)的话,就执行uart_event(info, 0),告诉TTY核心,可以接受更多数据了。这里可以看出,tty_driver和tty_core之间的层次,tty_driver可以知道缓冲空还是满,但是它没有权力让发送数据过来,它只能是通知tty_core,让它来处理。
&&&&&&&&&&& (5) 最后再察看一下环形寄存器,如果serial core 没有发送来更多的数据,就关闭发送。
&
3.8 出错中断函数uart_err_interrupt
static void s3c2410uart_err_interrupt(int irq, void *dev_id,
struct pt_regs *reg) {
struct uart_info *info = dev_
struct uart_port *port = info-&
&
struct tty_struct *tty = info-&
unsigned char err = UART_UERSTAT(port) & UART_ERR_MASK;
unsigned int ch,
ch = UART_URXH(port);
if (!(err & (UERSTAT_BRK | UERSTAT_FRAME |
UERSTAT_PARITY | UERSTAT_OVERRUN)))
if (err & UERSTAT_BRK)
port-&icount.brk++;
if (err & UERSTAT_FRAME)
port-&icount.frame++;
if (err & UERSTAT_PARITY)
port-&icount.parity++;
if (err & UERSTAT_OVERRUN)
port-&icount.overrun++;
err &= port-&read_status_
if (err & UERSTAT_PARITY)
flg = TTY_PARITY;
else if (err & UERSTAT_FRAME)
flg = TTY_FRAME;
flg = TTY_NORMAL;
if (err & UERSTAT_OVERRUN) {
*tty-&flip.char_buf_ptr =
*tty-&flip.flag_buf_ptr =
tty-&flip.flag_buf_ptr++;
tty-&flip.char_buf_ptr++;
tty-&flip.count++;
if (tty-&flip.count & TTY_FLIPBUF_SIZE) {
flg = TTY_OVERRUN;
*tty-&flip.flag_buf_ptr++ =
*tty-&flip.char_buf_ptr++ =
tty-&flip.count++;
&
&
首先err = UART_UERSTAT(port) & UART_ERR_MASK确定了err的值,err的值是从是从UART Error Status Register读到的,该erstate只用了四位,所以用UART_ERR_MASK把高四位掩掉,然后测试低四位中哪个位被置1了,从而判断错误种类UERSTAT_BRK/FRAME/PARITY/OVERRUN 分别代表10/0001 ,判断出错误种类再进行相应的中断计数,然后再根据不同的err给flg设上不同的值,有
#define TTY_NORMAL 0
#define TTY_BREAK 1
#define TTY_FRAME 2
#define TTY_PARITY 3
#define TTY_OVERRUN 4
&
&
3.9 初始化函数uart_startup
static int s3c2410uart_startup(struct uart_port *port, struct uart_info *info)
ret = request_irq(RX_IRQ(port), s3c2410uart_rx_interrupt, SA_INTERRUPT,
"serial_s3c2410_rx", info);
if (ret) goto rx_
ret = request_irq(TX_IRQ(port), s3c2410uart_tx_interrupt, SA_INTERRUPT,
"serial_s3c2410_tx", info);
if (ret) goto tx_
#ifdef CONFIG_USE_ERR_IRQ
ret = request_irq(ERR_IRQ(port), s3c2410uart_err_interrupt, SA_INTERRUPT,
"serial_s3c2410_err", info);
if (ret) goto err_
ucon = (UCON_TX_INT_LVL | UCON_RX_INT_LVL |
UCON_TX_INT | UCON_RX_INT | UCON_RX_TIMEOUT);
#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
ULCON2 |= ULCON_IR | ULCON_PAR_NONE | ULCON_WL8 | ULCON_ONE_STOP;
&
save_flags(flags);
UART_UCON(port) =
restore_flags(flags);
#ifdef CONFIG_USE_ERR_IRQ
err_failed:
free_irq(TX_IRQ(port), info);
tx_failed:
free_irq(RX_IRQ(port), info);
rx_failed:
如果使用了函数open(ttyS0),那么最后调用的实现open功能的就是这个函数,它打开ttyS0。
1:利用request_irq()申请发送,接收,错误三个中断,如果失败,就要释放调已经申请的全部资源&
&
2:设置UART Control Register
&
&
3.10 函数uart_change_speed
static void s3c2410uart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
u_int ulcon,
ufcon = UART_UFCON(port);
switch (cflag & CSIZE) {
case CS5: ulcon = ULCON_WL5;
case CS6: ulcon = ULCON_WL6;
case CS7: ulcon = ULCON_WL7;
default: ulcon = ULCON_WL8;
if (cflag & CSTOPB)
ulcon |= ULCON_STOP;
if (cflag & PARENB) {
if (!(cflag & PARODD))
ulcon |= ULCON_PAR_EVEN;
if (port-&fifosize & 1)
ufcon |= UFCON_FIFO_EN;
port-&read_status_mask = UERSTAT_OVERRUN;
if (iflag & INPCK)
port-&read_status_mask |= UERSTAT_PARITY | UERSTAT_FRAME;
port-&ignore_status_mask = 0;
if (iflag & IGNPAR)
port-&ignore_status_mask |= UERSTAT_FRAME | UERSTAT_PARITY;
if (iflag & IGNBRK) {
if (iflag & IGNPAR)
port-&ignore_status_mask |= UERSTAT_OVERRUN;
quot -= 1;
save_flags(flags);
UART_UFCON(port) =
UART_ULCON(port) = (UART_ULCON(port) & ~(ULCON_PAR | ULCON_WL)) |
UART_UBRDIV(port) =
restore_flags(flags);
UBRDIVn=(int)(CLK/(bps*16))-1
quot=(CLK / (baudrate x 16) ) (CLK为PCLK或UCLK,baudrate的单位是bps
&
(1):首先看一下cflag的cs位,同CS5/6/7比较,然后设置ulcon,接下来的几个if也是将ulcon根据cflag的设置进行一下设置,设置了停止位,校验位。
(2):如果port中设置了fifosize,就把UFCON(物理地址0x)的第0位设为1。
&
&
4.控制台
4.1& 注册控制台
void __init s3c2410_console_init(void)
register_console(&s3c2410_cons);
&
static struct console s3c2410_cons = {
&&&&& name:&&&&&&&&&& "ttyS",
&&&&& write:&&&&&& s3c2410_console_write,
&&&&& device:&&&&&&&& s3c2410_console_device,
&&&&& wait_key:&&&& s3c2410_console_wait_key,
&&&&& setup:&&&&&&&&&& s3c2410_console_setup,
&&&&& flags:&&&&&& CON_PRINTBUFFER,
&&&&& index:&&&&&&&&&& -1,
};
4.2 函数console_write
static void s3c2410_console_write(struct console *co, const char *s, u_int count)
struct uart_port *port = s3c2410_ports + co-&
for (i = 0; i & i++) {
while (!(UART_UTRSTAT(port) & UTRSTAT_TX_EMP));
UART_UTXH(port) = s[i];
if (s[i] == '\n') {
while (!(UART_UTRSTAT(port) & UTRSTAT_TX_EMP));
UART_UTXH(port) = '\r';
通过串口往外发送数据
for循环count次,每次发送一个字符,当发送缓冲寄存器为空时,就往里写一个字符,如果写的数据是回车加换行,就要再写一个换行符
&
&
&
4.3 函数console_waitkey
static int s3c2410_console_wait_key(struct console *co)
struct uart_port *port = s3c2410_ports + co-&
while (!(UART_UTRSTAT(port) & UTRSTAT_RX_RDY));
c = UART_URXH(port);
该函数在while循环中等待接收数据,一旦接收缓冲器中有有效数据,该函数立即返回,返回值为接收到的一个字符
4.4 函数console_device
static kdev_t s3c2410_console_device(struct console *co)
return MKDEV(SERIAL_S3C2410_MAJOR, MINOR_START + co-&index);
通过主,次设备号返回kdev_t结构
4.5 设置函数console_setup
static int __init s3c2410_console_setup(struct console *co, char *options)
struct uart_port *
int baud = 115200;
int bits = 8;
int parity = 'n';
int flow = 'n';
port = uart_get_console(s3c2410_ports, UART_NR, co);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
return uart_set_options(port, co, baud, parity, bits, flow);
这个函数就是设置控制台(console)的状态,里面主要有三个函数
(1)uart_get_console (struct uart_port *ports, int nr, struct console *co)
该函数检查是否co-&index是一个无效的index number,返回指向该index number 对应的uart_port struct的指针
(2)uart_parse_options (options, &baud, &parity, &bits, &flow)
如果option被设置了,那么就要调用该函数,该函数解析options,options来自上一层函数的参数,它是一个字符串,应该包含baudrate,parity,bits,flow这些信息。
(3)uart_set_options( port, co, baud, parity, bits, flow)
针对以上给定的信息,对console的cflag进行设置.还要调用一下ops中的change_speed对baud rate进行实际的设置(物理),成功地话return 0
相关资料:|||||||串口驱动分析(二)来源网络,如有侵权请告知,即处理!编程Tags:                &                    > 对不起!您查找的页面在火星,地球暂时无法访问
内部服务器错误(Internal Server Error)
秒之后页面自动跳转,您可以:
2) 去其他地方逛逛:   对不起,您要访问的页面暂时没有找到,您可以:S3C2410串口通讯_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
S3C2410串口通讯
上传于||文档简介
&&串​口​通​信
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢串口通讯基础及S3C2410&UART控制器
终端电阻以吸收掉反射波。电阻网络也应该是平衡的,如图5-9所示。
为RS-422A平衡输出差分输示意图
RS-485标准
RS-485适用于收发双方共享一对线进行通信,也适用于多个点之间共享一对线路进行总线方式联网,但通信只能是半双工的,线路如图5-10所示。
典型的RS232到RS422/485转换芯片有:MAX481/483/485/487/488/489/490/491,
SN4等等,它们均只需单一+5v电源供电即可工作(芯片内部采用电荷泵方式升压)。具体使用方法可查阅有关技术手册。
五、S3C2410内置的UART控制器
S3C2410内部具有3个独立的UART控制器,每个控制器都可以工作在Interrupt(中断)模式或DMA(直接内存访问)模式,也就是说
UART控制器可以CPU与UART控制器传送资料的时候产生中断或DMA请求。并且每个UART均具有16字节的FIFO(先入先出寄存器),支持的最高波特率可达到230.4Kbps
图5-11是S3C2410内部UART控制器的结构图
UART的操作
UART的操作分为以下几个部分,分别是:资料发送、资料接收、产生中断、产生波特率、Loopback模式、红外模式以及自动流控模式。
发送的资料帧格式是可以编程设置的。它包含了起始位、5~8个资料位、可选的奇偶校验位以及1~2位停止位。这些都是通过UART的控制寄存器
ULCONn 来设置的。
同发送一样,接收的资料帧格式也是可以进行编程设置的。此外,还具备了检测溢出出错、奇偶校验出错、帧出错等出错检测,并且每种错误都可以置相应的错误标志。
自动流控模式
S3C2410的UART0和UART1都可以通过各自的nRTS和nCTS信号来实现自动流控。
在自动流控(AFC)模式下nRTS取决于接收端的状态,而nCTS控制了发送断的操作。具体地说:只有当nCTS有效时(表明接收方的FIFO已经准备就绪来接收资料了),UART才会将FIFO中的资料发送出去。在UART接收资料之前,只要当接收FIFO有至少2-byte空余的时候,nRTS就会被置为有效。图5-12是UART
自动流控模式的连接方式
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 s3c2410中断控制器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信