总结:wince下串口中断的使用(UART0,就是默认的调试串口)
大体思路是:1、修改串口寄存器配置
2、捆版系统中断号与串口中断号
3、创建线程,等待中断发生
4、执行任务
代码:
需要头文件 :
#include <s3c6410.h>
寄存器定义:
staticS3C6410_GPIO_REG* pIORegs= NULL; //定义指针指向GPIO寄存器首地址
staticS3C6410_UART_REG* pUARTRegs= NULL; //定义指针指向UART寄存器首地址staticS3C6410_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 =
{
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;
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;
}
结束
感谢楼主的分享!!! 因为是覆盖原先的串口设置,RBM这个底层驱动启动要靠后,我让"Order"="200",够后了
页:
[1]