打印
[ZLG-ARM]

LPC2200 uart中断收发(多字节)

[复制链接]
4312|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cdd51408|  楼主 | 2008-12-24 09:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
串口整理好久,终于有所收获,和大家共享一下,顺道请各位高手看看有没有需要改进的地方。

#include "config.h"

/* 定义串口模式设置数据结构 */
typedef struct UartMode
{
    uint8 datab;        // 字长度,5/6/7/8可选
    uint8 stopb;        // 停止位,1/2可选
    uint8 parity;        // 奇偶校验位,0-无校验,1-奇校验,2-偶校验
}UARTMODE;

uint8 rcv_buf[256];        // UART0数据接收缓冲区
volatile uint8 rcv_new;    // 接收新数据标志

/*
*********************************************************************************************************
** 函数名称 :IRQ_UART0()
** 函数功能 :串口0接收中断服务程序
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
uint8 head=0;
uint8 tail=0;

void __irq IRQ_UART0 (void)
{

        
    if ((U0IIR & 0x0F) == 0x04)    //U0IIR中断标识
        rcv_new = 1;            // 设置接收到新的数据标志
    else
        return;//非接收到新数据的中断是否直接返回?
        
    while((U0LSR&0x01)!=0)
    {
        rcv_buf[tail] = U0RBR;        // 读取FIFO的数据,并清除中断
        tail++;    
        tail%=256;
    }
    
  
    VICVectAddr = 0x00;            // 中断处理结束
}

/*
*********************************************************************************************************
** 函数名称 :UART0_SendByte()
** 函数功能 :向串口0发送1字节数据
** 入口参数 :dat    要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendByte (uint8 dat)
{
    U0THR = dat;    // 要发送的数据
}

/*
*********************************************************************************************************
** 函数名称 :UART0_SendBuf()
** 函数功能 :向串口发送8字节数据
** 入口参数 :dat    要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendBuf (void)
{
    uint8 i;
    
    for (i=head; i<tail; i++)
        UART0_SendByte(rcv_buf);
    
    head=tail;
    
    while ((U0LSR & 0x20) == 0);    // 等待数据发送完毕
}

/*
*********************************************************************************************************
** 函数名称 :UART0_Init()
** 函数功能 :串口初始化,设置工作模式和波特率。
** 入口参数 :baud    波特率
**              set    模式设置(UARTMODE数据结构)
** 出口参数 :1-初始化成功,  0-初始化失败
*********************************************************************************************************
*/
int8 UART0_Init (uint32 baud, UARTMODE set)
{
    uint32 bak;
    
    /* 参数过滤 */
    if ((baud ==0 ) || (baud > 115200))    return (0);
    if ((set.datab <5) || (set.datab > 8))    return (0);
    if ((set.stopb == 0) || (set.stopb > 2))     return (0);
    if (set.parity > 4)    return (0);
    
    /* 设置串口波特率 */
    U0LCR = 0x80;                        // DLAB = 1    
    bak   = (Fpclk >> 4) / baud;
    U0DLM = bak >> 8;
    U0DLL = bak & 0xFF;
    
    /* 设置串口模式 */
    bak   = set.datab - 5;                // 设置字长
    if (set.stopb == 2)    bak |= 0x04;    // 判断是否为2位停止位
    
    if (set.parity != 0)
    {
        set.parity = set.parity - 1;
        bak |= 0x08;
    }
    bak |= set.parity << 4;                // 设置奇偶校验
    
    U0LCR = bak;
    
    return (1);
}


/*
*********************************************************************************************************
** 函数名称 :main()
** 函数功能 :从串口UART0接收字符串"ABCDEFGH",并发送回上位机显示。
** 调试说明 :需要PC串口显示终端软件如EasyARM.exe。
*********************************************************************************************************
*/
int main (void)
{
    UARTMODE set;

    set.datab  = 8;
    set.stopb  = 1;
    set.parity = 0;
    
    rcv_new = 0;
    
    PINSEL0 = 0x00000005;                // 设置I/O连接到UART0
    
    UART0_Init(115200, set);            // 串口初始化
    //U0FCR = 0x01;                        // 使能FIFO,并设置触发点为1字节
    //U0IER = 0x01;                        // 允许RBR中断,即接收中断
    
    //IRQEnable();                        // 使能IRQ中断
    /* 使能UART0中断 */
    VICIntSelect = 0x00000000;            // 设置所有的通道为IRQ中断
    VICVectCntl0 = 0x20 | 0x06;            // UART0分配到IRQ slot0,即最高优先级
    VICVectAddr0 = (uint32)IRQ_UART0;    // 设置UART0向量地址
    VICIntEnable = 1 << 0x06;            // 使能UART0中断

    while (1)
    {    
        if (rcv_new == 1)
        {    
            U0IER=0x00;//关串口中断
            rcv_new =0;
            
            UART0_SendBuf();
            
            U0IER=0x01;//开串口中断
        }
    }
    return 0;
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

相关帖子

沙发
tubie| | 2008-12-28 21:51 | 只看该作者

我觉得没有必要搞得像楼上那么复杂吧,本来就是个简单的

使用特权

评论回复
板凳
xwj| | 2008-12-29 08:33 | 只看该作者

“我们”要换成你们吧?

使用特权

评论回复
地板
HWM| | 2008-12-29 08:54 | 只看该作者

我一般都把这些玩意儿整成“流”

使用特权

评论回复
5
HWM| | 2008-12-29 09:28 | 只看该作者

一般认为自己的代码很垃圾的,离专业通常不会太近。

使用特权

评论回复
6
xwj| | 2008-12-29 12:28 | 只看该作者

MD

牛皮癣,
看到就烦...

就算你说的再好,说得天花乱坠,我还是字觉得烦.

使用特权

评论回复
7
g19860529| | 2008-12-29 12:37 | 只看该作者

armecos是不是精神有问题?

真的,我感觉就是

使用特权

评论回复
8
sz_kd| | 2008-12-29 12:40 | 只看该作者

人家是牛必须承认~~~~

使用特权

评论回复
9
hackdj| | 2008-12-29 13:18 | 只看该作者

到处都是这个广告,看的是有点麻烦

ecos自己弄弄还是不难的,底层移植都做好了,自己改改就ok

使用特权

评论回复
10
john_light| | 2008-12-29 13:34 | 只看该作者

闲着也是闲着,我顶老杨。

能从十本书里头找到一两本对自己有用的就不错。

能从别人一百句话里头找到几句对自己有促进的同样不错。

我是个粗人,近来觉得抽象这东西还有点用。

老杨的广告吗,我就看看。

使用特权

评论回复
11
wgc204| | 2008-12-31 13:26 | 只看该作者

谢谢楼主分享

谢谢楼主分享

不过下面两句应该不能注解掉的;

U0FCR = 0x01;                        // 使能FIFO,并设置触发点为1字节
U0IER = 0x01;                        // 允许RBR中断,即接收中断

使用特权

评论回复
12
zhongyb| | 2009-1-1 16:49 | 只看该作者

看到armecos就想到了罗家英

一个建议,如果真的想把你们的产品推广好,何不考虑开源呢?

使用特权

评论回复
13
暮然| | 2009-1-4 22:09 | 只看该作者

跑题了,各位!

    各位,还是另开一贴,慢慢研讨吧。不是每个人都愿意看这些谁是谁非的争论,和一群政客一般。
    看了楼主的代码,想来也是从周工那参考了不少。提两个建议吧。
    uart接收中断:采用fifo,应该有两个中断结果,其一是完全接收到填满fifo。其二是未完全填满fifo。你只用到了上述第一种情况。在多数情况下,uart通信协议并不是只有一种数据长度,当遇到多种数据长度协议时,就不适用了,很可能就会把一些过长数据阶段,剩下未知长度数据;也可能无法实时的处理较短长度数据,而必须等到填满fifo才处理。上述其二的方法就是:采用fifo接收超时中断,即fifo在连续收到数据,未达到设定数据个数时,在之后的4~5个ms内没收到数据,产生中断,可在中断中将数据从fifo中读出。
   uart数据发送:很多人喜欢用for(~~~~)sent 方式发送,在发送数据过程中,mcu除了能处理中断,就不能干其他事情,效率低下。可改为在主循环中查询发送,即不影响发送也不耗费mcu时间。更好的是采用fifo发送。
    这些东西是在工程实践中积累的经验,希望对楼主,对其他人有帮助。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

7

帖子

0

粉丝