打印
[ZLG-ARM]

lpc2132的串口驱动(中断方式)

[复制链接]
3129|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LPC300|  楼主 | 2010-6-23 21:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "lpc213x.h"
#include "Includes.h"

#define BIT(x)  (1<<x)
#define SET_BIT(x, y)   (x|=(1<<y))
#define CLR_BIT(x, y)   (x&=~(1<<y))
#define GET_BIT(x, y)   (x&(1<<y))

volatile struct
{
    INT8U  rd_buf[32];
    INT8U  td_buf[2048];
    INT16U rd_max;
    INT16U td_max;
    INT16U rd_cnt;
    INT16U td_cnt;
} uart0;

OS_EVENT *uart0_rd_ok;
OS_EVENT *uart0_td_ok;

extern void UART0_Handler(void);

void UART0_Exception(void)
{  
       unsigned char i, k;
      
       k = U0IIR&0x0F;
    switch(k)
    {
        case 0x02:            
            for (i=0; i<16; i++)
            {
                if (uart0.td_cnt < uart0.td_max)
                {
                    U0THR = uart0.td_buf[uart0.td_cnt];
                    uart0.td_cnt++;
                }
                else
                {
                    U0IER = U0IER & (~0x02);        
                    OSSemPost(uart0_td_ok);
                    goto UART0_Exception_RET;
                }
            }
            break;
        case 0x04:
            for (i=0; i<8; i++)
            {
                uart0.rd_buf[uart0.rd_cnt] = U0RBR;
                if (uart0.rd_buf[0] == 0xFD)
                {
                    uart0.rd_cnt++;
                    if (uart0.rd_cnt == uart0.rd_max)
                    {
                        OSSemPost(uart0_rd_ok);
                        goto UART0_Exception_RET;
                    }   
                    else if (uart0.rd_cnt > 31)
                    {
                        uart0.rd_cnt = 31;
                    }                    
                }
            }
            break;
        case 0x0C:
            uart0.rd_buf[uart0.rd_cnt] = U0RBR;
            if (uart0.rd_buf[0] == 0xFD)
            {
                uart0.rd_cnt++;                       
                if (uart0.rd_cnt == uart0.rd_max)
                {
                    OSSemPost(uart0_rd_ok);
                    goto UART0_Exception_RET;
                }   
                else if (uart0.rd_cnt > 31)
                {
                    uart0.rd_cnt = 31;
                }                    
            }
            break;
        default:
            break;
    }
UART0_Exception_RET:
      VICVectAddr = 0x00;                        
}

void UART0_init(void)
{  
    INT16U i;
   
    for (i=0; i<32; i++)
    {
        uart0.rd_buf[i] = 0x00;
    }
    for (i=0; i<2048; i++)
    {
        uart0.td_buf[i] = (unsigned char)i;
    }
    uart0.rd_max = 8;
    uart0.td_max = 0;
    uart0.rd_cnt = 0;
    uart0.td_cnt = 0;

    SET_BIT(PINSEL0, 0);
    CLR_BIT(PINSEL0, 1);
    SET_BIT(PINSEL0, 2);
    CLR_BIT(PINSEL0, 3);
   
    U0LCR = 0x83;                  
       U0DLL = 0x06;
       U0DLM = 0x00;
       U0LCR = 0x03;
       U0FCR = 0x87;
       U0IER = 0x01;
      
       VICIntSelect = 0x00000000;
       VICVectCntl1 = 0x26;
       VICVectAddr1 = (unsigned long)UART0_Handler;
       VICIntEnable = (1<<6);
}

void UART0_putc(unsigned char c)
{
    U0THR = c;
    while ((U0LSR&0x40) == 0)
    {
    }
}

void UART0_puts(char *p)
{  
    while(*p)
    {
        UART0_putc(*p);                  
           p++;      
       }
}

void UART0_send(INT16U len)
{  
    //unsigned short i;
   
    //for (i=0; i<len; i++)
    //{
    //    UART0_putc(uart0.td_buf[i]);                  
       //}
    uart0.td_cnt = 0;
    uart0.td_max = len;
    if (uart0.td_max > 0)
    {
           U0THR = uart0.td_buf[uart0.td_cnt];
           uart0.td_cnt++;
           U0IER = U0IER | 0x02;                       /* 允许发送中断 */
       }
}

void UART0_task(void *pdata)
{
    INT8U err;
   
    pdata = pdata;
   
    uart0_rd_ok = OSSemCreate(0);
    uart0_td_ok = OSSemCreate(0);
   
    UART0_init();
    do
    {
        OSSemPend(uart0_rd_ok, 0, &err);
        UART0_send(1024);
        OSSemPend(uart0_td_ok, 0, &err);
        uart0.rd_cnt = 0;
    } while(1);
}

相关下载

相关帖子

沙发
6019实验室| | 2010-6-23 21:52 | 只看该作者
谢谢啦中断看了几天都不明白,这下好了,虽然我的是2104

使用特权

评论回复
板凳
无语凝咽| | 2010-6-23 21:52 | 只看该作者
在多任务中,串口驱动,当一个设备想使用串口时,必须保证当时串口是空闲,如果不空闲,必须等待,直到空间,或者指定时间内串口设备未空闲,提示信息,

楼上的串口驱动采用结构,比较不错

但是要是用在多任何中,如果用多个任何使用此串口,估计会有问题

使用特权

评论回复
地板
米其林r| | 2010-6-23 21:52 | 只看该作者
采用信号量太占用资源,不如用 Uart0Status=OSFlagCreate表示状态,另外,其实完全可以将串口的忙闲状态等信息一块封装在结构中,这样不断模块化,同时,一个状态只占用一个信息,

使用特权

评论回复
5
LPC300|  楼主 | 2010-6-23 21:53 | 只看该作者
呵呵,改了一下
#include "lpc213x.h"
#include "Includes.h"

#define BIT(x)  (1<<x)
#define SET_BIT(x, y)   (x|=(1<<y))
#define CLR_BIT(x, y)   (x&=~(1<<y))
#define GET_BIT(x, y)   (x&(1<<y))

volatile struct
{
    INT8U  rd_buf[32];
    INT8U  td_buf[2048];
    INT16U rd_max;
    INT16U td_max;
    INT16U rd_cnt;
    INT16U td_cnt;
    OS_EVENT *rd_ok;
    OS_EVENT *td_ok;
} uart0;

extern void UART0_Handler(void);

void UART0_Exception(void)
{  
       unsigned char i, k;
      
       k = U0IIR&0x0F;
    switch(k)
    {
        case 0x02:            
            for (i=0; i<16; i++)
            {
                if (uart0.td_cnt < uart0.td_max)
                {
                    U0THR = uart0.td_buf[uart0.td_cnt];
                    uart0.td_cnt++;
                }
                else
                {
                    U0IER = U0IER & (~0x02);        
                    OSSemPost(uart0.td_ok);
                    goto UART0_Exception_RET;
                }
            }
            break;
        case 0x04:
            for (i=0; i<8; i++)
            {
                uart0.rd_buf[uart0.rd_cnt] = U0RBR;
                if (uart0.rd_buf[0] == 0xFD)
                {
                    uart0.rd_cnt++;
                    if (uart0.rd_cnt == uart0.rd_max)
                    {
                        OSSemPost(uart0.rd_ok);
                        goto UART0_Exception_RET;
                    }   
                    else if (uart0.rd_cnt > 31)
                    {
                        uart0.rd_cnt = 31;
                    }                    
                }
            }
            break;
        case 0x0C:
            uart0.rd_buf[uart0.rd_cnt] = U0RBR;
            if (uart0.rd_buf[0] == 0xFD)
            {
                uart0.rd_cnt++;                       
                if (uart0.rd_cnt == uart0.rd_max)
                {
                    OSSemPost(uart0.rd_ok);
                    goto UART0_Exception_RET;
                }   
                else if (uart0.rd_cnt > 31)
                {
                    uart0.rd_cnt = 31;
                }                    
            }
            break;
        default:
            break;
    }
UART0_Exception_RET:
      VICVectAddr = 0x00;                        
}

void UART0_init(void)
{  
    INT16U i;
   
    for (i=0; i<32; i++)
    {
        uart0.rd_buf[i] = 0x00;
    }
    for (i=0; i<2048; i++)
    {
        uart0.td_buf[i] = (unsigned char)i;
    }
    uart0.rd_max = 8;
    uart0.td_max = 0;
    uart0.rd_cnt = 0;
    uart0.td_cnt = 0;
    uart0.rd_ok = OSSemCreate(0);
    uart0.td_ok = OSSemCreate(0);

    SET_BIT(PINSEL0, 0);
    CLR_BIT(PINSEL0, 1);
    SET_BIT(PINSEL0, 2);
    CLR_BIT(PINSEL0, 3);
   
    U0LCR = 0x83;                  
       U0DLL = 0x06;
       U0DLM = 0x00;
       U0LCR = 0x03;
       U0FCR = 0x87;
       U0IER = 0x01;
      
       VICIntSelect = 0x00000000;
       VICVectCntl1 = 0x26;
       VICVectAddr1 = (unsigned long)UART0_Handler;
       VICIntEnable = (1<<6);
}

void UART0_putc(unsigned char c)
{
    U0THR = c;
    while ((U0LSR&0x40) == 0)
    {
    }
}

void UART0_puts(char *p)
{  
    while(*p)
    {
        UART0_putc(*p);                  
           p++;      
       }
}

void UART0_send(INT16U len)
{  
    uart0.td_cnt = 0;
    uart0.td_max = len;
    if (uart0.td_max > 0)
    {
           U0THR = uart0.td_buf[uart0.td_cnt];
           uart0.td_cnt++;
           U0IER = U0IER | 0x02;                       
       }
}

void UART0_task(void *pdata)
{
    INT8U err;
   
    pdata = pdata;
   
    UART0_init();
    do
    {
        OSSemPend(uart0.rd_ok, 0, &err);
        UART0_send(1024);
        OSSemPend(uart0.td_ok, 0, &err);
        uart0.rd_cnt = 0;
    } while(1);
}

使用特权

评论回复
6
0331631| | 2010-10-21 22:29 | 只看该作者
先标记一下 慢慢看程序

使用特权

评论回复
7
金鱼木鱼| | 2010-10-21 22:57 | 只看该作者
mark

使用特权

评论回复
8
dong_abc| | 2010-10-21 23:09 | 只看该作者
记号

使用特权

评论回复
9
杜_U_ME| | 2010-10-22 22:59 | 只看该作者
学习下

使用特权

评论回复
10
七叶一枝花| | 2010-11-30 18:38 | 只看该作者
关注了。

使用特权

评论回复
11
bit6019| | 2010-11-30 23:49 | 只看该作者
学习了

使用特权

评论回复
12
wxbhlj| | 2011-7-13 13:54 | 只看该作者
楼主程序不错,若要配上注释看起来就轻松多了。

使用特权

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

本版积分规则

个人签名:30——驱动高手、流利的英语

107

主题

525

帖子

0

粉丝