嵌入式爱好者

查看: 5958|回复: 2

[Win CE] 总结:wince下串口中断的使用(UART0,就是默认的调试串口)

[复制链接]

5

主题

19

帖子

36

积分

扫一扫,手机访问本帖
发表于 2014-2-18 14:41:29 | 显示全部楼层 |阅读模式
大体思路是:
1、修改串口寄存器配置
2、捆版系统中断号与串口中断号
3、创建线程,等待中断发生
4、执行任务

代码:
需要头文件 :
#include <s3c6410.h>
寄存器定义:
static  S3C6410_GPIO_REG* pIORegs  = NULL; //定义指针指向GPIO寄存器首地址
static  S3C6410_UART_REG* pUARTRegs  = NULL; //定义指针指向UART寄存器首地址static  S3C6410_VIC_REG*  pVICRegs  = NULL; //定义指针指向VIC寄存器首地址
//串口中断0相关
static HANDLE hUARTListenEvent = NULL;
static HANDLE hUARTListenThread = NULL;
static DWORD dwUARTSysItr = SYSINTR_UNDEFINED;
//串口
#define DEBUG_BAUDRATE1      (115200)//波特率
#define UART0_BASE           (0x7F005000)//基础地址
#define WrUTXH0(ch)     (*(volatile unsigned char *)(UART0_BASE+0x20))=(unsigned char)(ch)//向缓冲区写数据
const UINT32 aSlotTable[16] =
{
    0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa,
    0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf
};//波特率表
/*映射VIC1寄存器*/
BOOL RBM_VIC1_Alloc(void)
{
        PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_VIC1;
        //物理地址映射到虚拟内存中
    pVICRegs = (S3C6410_VIC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_VIC_REG), FALSE);

        if(pVICRegs == NULL)   
        {
                RETAILMSG(1,(TEXT( "pVICRegs is not allocated\n\r")));
                return FALSE;
        }
       
        RETAILMSG(1,(TEXT( "pVICRegs is mapped to %x\n\r "), pVICRegs));

        return TRUE;
}

/*映射UART寄存器*/
BOOL RBM_UART_Alloc(void)
{
        PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_UART0;
        //物理地址映射到虚拟内存中
    pUARTRegs = (S3C6410_UART_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_UART_REG), FALSE);

        if(pUARTRegs == NULL)   
        {
                RETAILMSG(1,(TEXT( "pUARTRegs is not allocated\n\r")));
                return FALSE;
        }
       
        RETAILMSG(1,(TEXT( "pUARTRegs is mapped to %x\n\r "), pUARTRegs));

        return TRUE;
}


/*串口初始化*/
void RBM_Uart_Init(void)
{
    UINT32 DivSlot;
    float Div;

        pVICRegs->VICINTSELECT = (pVICRegs->VICINTSELECT )&(0<<5);//选择IRQ中断方式
    pVICRegs->VICIRQSTATUS = (pVICRegs->VICIRQSTATUS )|(1<<5);//激活中断
    pVICRegs->VICADDRESS =  (pVICRegs->VICADDRESS)&(0<<5);//清除当前中断

    // UART I/O port initialize (RXD0 : GPA0, TXD0: GPA1)//配置GPA端口
    pIORegs->GPACON = (pIORegs->GPACON & ~(0xff<<0)) | (0x22<<0);    // GPA0->RXD0, GPA1->TXD0
    pIORegs->GPAPUD = (pIORegs->GPAPUD & ~(0xf<<0)) | (0x0<<0);        // RXD0:  TXD0: pull up/down disable//上下拉电阻禁止

    // Initialize UART Ch0
    pUARTRegs->ULCON = (0<<6)|(0<<3)|(0<<2)|(3<<0);                    // Normal Mode, No Parity, 1 Stop Bit, 8 Bit Data
    pUARTRegs->UCON = (0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0);    // PCLK divide, Polling Mode
    pUARTRegs->UFCON = (0<<6)|(0<<4)|(0<<2)|(0<<1)|(0<<0);            // Disable FIFO
    pUARTRegs->UMCON = (0<<5)|(0<<4)|(0<<0);                        // Disable Auto Flow Control

        pUARTRegs->UINTP =(1<<3)| (1<<2)|(1<<1)|(1<<0);//初始化清除中断标志位
        pUARTRegs->UINTSP = (1<<3)| (1<<2)|(1<<1)|(1<<0);//清除源中断标志位
        pUARTRegs->UINTM = (1<<3)| (1<<2)|(1<<1)|(0<<0);//开RXD中断,屏蔽TXD中断,屏蔽接收错误中断,屏蔽=MODEM中断
       

    Div = (float)((float)S3C6410_PCLK/(16.0*(float)DEBUG_BAUDRATE1)) - 1;
    DivSlot = (UINT32)((Div-(int)Div)*16);//波特率计算

    pUARTRegs->UBRDIV = (UINT32)Div;                                    // Baud rate
    pUARTRegs->UDIVSLOT = aSlotTable[DivSlot];

        pVICRegs->VICINTENABLE = (pVICRegs->VICINTENABLE)|(1<<5);//开矢量寄存器UART0总中断
}
/*映射GPIO寄存器*/
BOOL RBM_GPIO_Alloc(void)
{
        PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;
        //物理地址映射到虚拟内存中
    pIORegs = (S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_GPIO_REG), FALSE);

        if(pIORegs == NULL)   
        {
                RETAILMSG(1,(TEXT( "pIORegs is not allocated\n\r")));
                return FALSE;
        }
       
        RETAILMSG(1,(TEXT( "pIORegs is mapped to %x\n\r "), pIORegs));

        return TRUE;
}
/*UART0中断监听函数*/
DWORD WINAPI RBM_UART_ListenProc(void)
{
          static int numbers1=0;
        BYTE KeySelect = 0;
        while(1)
        {
                 WaitForSingleObject(hUARTListenEvent, INFINITE);//等待中断
                 pUARTRegs->UINTP =(1<<0);//初始化清除中断标志位
             pUARTRegs->UINTSP = (1<<0);//清除源中断标志位

                 KeySelect =pUARTRegs->URXH;//读数据
                 if(KeySelect=='1')//为‘1’执行,这里面写要做的事情
                 {
                 RETAILMSG(1,(TEXT( "kai shi ce shi  %d\n\r"),numbers1));
                 numbers1++;
                 }
                 InterruptDone(dwUARTSysItr);
        }
        return 0;
}

下面是版定系统中断号的方法:
/*中断设置*/
BOOL RBM_IRQ_Conf(void)
{
DWORD dwIRQ;
/*******************中断初始化:创建中断阻塞事件->注册->初始化->创建线程*********************/
/*******************************************************************************
UART
*******************************************************************************/
        hUARTListenEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//创建事件
        if(!hUARTListenEvent)               
                RETAILMSG(1,(TEXT( "Create UART event failed\n\r")));

        dwIRQ = IRQ_UART0;//串口中断
        if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIRQ, sizeof(DWORD), &dwUARTSysItr, sizeof(DWORD), NULL))
    {
        RETAILMSG(1,(TEXT( "Register UART interrupt failed\n\r")));
        dwUARTSysItr = SYSINTR_UNDEFINED;
        return FALSE;
    }//申请系统中断号

        if (!(InterruptInitialize(dwUARTSysItr, hUARTListenEvent, 0, 0)))
    {
        RETAILMSG(1,(TEXT("InterruptInitialize UART interrupt Failed \n\r")));
        return FALSE;
    }//绑定系统中断号和事件

        hUARTListenThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) RBM_UART_ListenProc, NULL, 0, NULL);
        //创建线程

        if(!hUARTListenThread)
                RETAILMSG(1,(TEXT( "Create Listen thread failed\n\r")));  
}
最后是流驱动的Init函数
/*RBM设备初始化*/
DWORD        RBM_Init(DWORD dwContext)
{
        /*将物理地址空间映射到虚拟地址空间*/
        if(!RBM_GPIO_Alloc())
                return 0;

        if(!RBM_UART_Alloc())
                return 0;

        if(!RBM_VIC1_Alloc())
                return 0;
       
        if(!RBM_IRQ_Conf())
           return 0;


        RBM_Uart_Init();

   return 1;
}
结束


回复

使用道具 举报

110

主题

1358

帖子

1443

积分

A40i/T3/T507/T527通行证i.MX6Q通行证i.MX6UL通行证i.MX8MM通行证i.MX8MP通行证RK3568通行证RK3588通行证RK3399通行证LS1028A通行证G2L通行证LS1012A通行证LS1043A\46A通行证TCU通行证FDU产品通行证FCU1401通行证FCU1301通行证FCU11xx通行证FCU1201通行证FCU2201通行证FCU2301/FCU2302通行证FCU2401通行证5G转接卡通行证FCU3001通行证AM5718通行证Hi3519A通信证AM335x通行证i.MX RT通行证XX18通行证AM62x资料下载FDU070K02\FDU101K02通行证i.MX9352通行证

发表于 2014-2-19 08:45:00 | 显示全部楼层
感谢楼主的分享!!!
该会员没有填写今日想说内容.
点评回复 支持 反对

使用道具 举报

5

主题

19

帖子

36

积分

 楼主| 发表于 2014-5-4 17:00:45 | 显示全部楼层
因为是覆盖原先的串口设置,RBM这个底层驱动启动要靠后,我让"Order"="200",够后了
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-6-3 00:44

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表