OK210开发板使用感想
好长时间没有出来透气了,这段时间一直在研究从飞凌刚买一段时间的210开发板,差不多也有一个多星期了,终于有一些成果了。通过一晚上的思索,我想吧我对飞凌开发板的感受说出来,让大家一睹为块。
一、开箱体验
拿到货后第一感觉是飞凌的包装盒很普通,不过快递倒是挺快,拍下后第三天就收到了。照片奉上:
PS;刚收到的圆通快递包裹,发货速度挺快的
PS;飞凌的包装盒,觉得图挺好,就是包装盒这个看着挺别扭的
PS;打开盒是那个光盘和保修卡,大致浏览了一下光盘里的资料,感觉内容还不少
PS;提供技术支持应该是飞凌的一大亮点
PS;以上都是飞凌OK210的配套配件
配件包括:1、用户光盘(2张),2、一条双孔交叉串口线,3、一条网线,4、一条Mini Usb线,5、一个电源适配器,6、一个合格证+保修卡
PS;再来一张核心板的特写,感觉核心板布线不错,而且有专门的电源管芯片
PS;飞凌官方说核心板是八层PCB沉金工艺,性能更加稳定,有效的预防电磁泄漏
PS;核心板和底板采用DIP方式连接
飞凌这种核心板和底板的连接方式,成本低,连接牢靠,唯一不足的就是拆卸不方便;如果经常卸核心板的用户,个人建议可以考虑飞凌金手指那套210开发板,拆卸方便而且不容易氧化,稳定,就是价格相比我买的这套有点小高。
PS;飞凌的这个flash用的是镁光1G Byte SLC nandflash,SLC读写更快,耗能更低,重复擦写次数是MLC的十倍
PS;底板的SD卡座,人性化的弯弧设计,更利于SD卡的插入和拔出
PS;4个USB HOST,完全可以满足需求
PS;两个双公头RS232电平串口
PS; HDMI接口,支持Android系统下1080p的视频输出,并且支持视频、音频同步输出,这是市面上极个别的几个嵌入式板卡厂商不能做到的
PS;54pin的 LCD fpc座,飞凌售后说质量没问题,反复的插拔不易坏,那我就可以放心大胆的用了
二、开机体验一收到这个家伙就迫不及待的按照手册的提示烧了当下主流的三种操作系统Linux,Wince,Android,给大家分享一下操作它的感受。
PS;Linux的烧写过程,我对比了飞凌提供的三个系统,Wince需要大概10s,Linux大概15~20s,android大概30~50s
PS; Android 的开机
PS;1080P的高清,播电影挺流畅的
PS; 先试了平时常玩的三款简单的游戏,玩起来一点都不卡,安卓这个系统娱乐性真是毋庸置疑
PS;神庙大逃亡这个游戏有点卡,可能是耗损的资源比较多的原因
三、使用心得第一步我开始按照手册,一步一步的做,210的产品刚上市不久,所以网上的资料很少,而且我也是刚刚从单片机转到ARM的,这里只能按照飞凌提供的官方手册一步一步的做了,唯一让我感到庆幸的是,官方提供的教程视频,虽然里面讲解的不是很全面,有些内容甚至是很简单,可能对一些个资深的工程师用处不是很大,但是对于我们初学者我感觉屡试不爽,能够有一种成就感。这里特别感谢下技术支持,一开始我按照教程做led的驱动,但是编译总是报错,最后没有办法了只能找技术支持了,技术支持很热情,一步一步的帮我分析,最后他让我比较下led下的sourse文件和我写的led驱动的sourse文件,我比较了下,果然是少写了一行代码。所以很感谢他们,因为初学者刚接触嵌入式,会遇到很多新手问题,如果旁边再没有几个人懂嵌入式遇到问题只能抓瞎了,所以新手买开发板就要选择技术支持好的,资料全的开发板。我很庆幸。时间有点长了,中间有段时间没写了,公司正在做一个项目,期间开发板就当了一个平板电脑了,我发现飞凌做的安卓系统真的很不错,唯一不足的就是开机速度实在是不敢恭维,游戏真是各种玩,真有种平板的感觉,但是样子实在让人不爽,这要是拿上公交汽车,百分百围观啊!对我这个刚刚毕业的呢,暂时还没挣到多少钱的,这种开发板真的很适合我平时一边学习一边开发东西。代码开源+不错的技术支持,已经相当优秀了,当然也有好多网友在网上骂,说什么哪家卖开发板的公司真垃圾,哪家的技术支持真艹蛋。我觉得我这次购板的经历挺好的,就拿出来分享下。今天就到这吧,写了不少了也。目前我在210的研究项目正在进行,稍后再把自己的研究成果奉上,,,,,,(未完待续)
流弊了,我买了天嵌的,那人自己也不会,什么也教不了,自己跟没头苍蝇一样乱学,现在还没有进展,更别提烧系统了。悲催
顶,不错,很有收获!
还好我这个有技术支持,不懂的问题能问问,这两天正用它写一个关于红外驱动的程序
驱动是比较难写的,不过有例子应该可以的
小编这套开发板看着真心不错啊 ,,我也想弄一套玩玩,用的怎么样啊?
小编真有钱,,我也好想有一个属于自己的开发板
经过几天的研究,终于把OK210开发板wince红外驱动的部分给完成了。
开发工具:vs2005,飞凌官方OK210开发板,杜邦线3根,烙铁一把,焊锡,4.7k电阻一个。
开发软件:Win CE 6.0
下图是所需的开发工具
从网上找了好久,不是不能用,就是骗子代码,根本不能用,最可气的就是挂羊头卖狗肉,标着红外驱动,用自己宝贵的积分,下载下来一看根本就不是,浪费了我很多时间,最后没办法只能自己动手了,这里充分体现了毛主席“自己动手,丰衣足食”这句话的重要性。好了废话不多说吧我自己的这几天的思路告诉大家让大家以后少走弯路,在这里我也希望广大网友能够不吝惜自己的劳动成果,把自己的奋斗果实奉献下,这样能让很多网友少走弯路,大家庆幸之余也会非常感激”挖井人“的。首先,我是按照单片机解码的思路,开始制作的Win CE操作系统的红外驱动,可把我害苦了。我用的是中断+定时器。思路呢和网上所有的都一样,但是总是卡死在定时器上,定时器我用的是微秒级别的延时,这样已进入系统,总是不停地去响应定时器的中断,这样就卡死在线程了。系统连起都起不来了,害的我倒腾了好几天,最后没办法只能放弃了,改用延时,网上有现成的函数。解码的遥控器类型有很多,这里我只做了最通用的NEC遥控器,其他的只需要改一下高低电平时间就行了。NEC红外协议,作为接收端来讲,首先是引导码,有9ms的低电平,然后是4.5ms的高电平,然后是32位的操作码,对于按键来说我们只需要解第三组就可以了,其他的NEC协议的知识可以从网上搜索下有很多的。现在只做红外接收模块,将准备好的杜邦线插在红外的三个引脚上,引脚顺序,大家从网上搜索下,然后就是找一个直插的4.7k上拉电阻,接到hs0038的接受引脚和5v引脚中间。由于我的红外解码思路是中断所以只能找中断引脚了,但是通篇的找飞凌OK210开发板上中断引脚真的是太难找了,(⊙o⊙)最后没办法只能找已经引出的引脚了,最后发现按键上每个引脚都能用,都是中断引脚,最后我选择了外部中断6,开发板的k4按键,将按键的上拉电阻去掉,然后焊接出一条引线,接到红外接收器的接收引脚。下面是自己焊的红外接收模块。
好了硬件准备完毕,现在开始写驱动。1.包含的头文件://made in 2013-6-7 by mr wang #include "stdafx.h"#include <windows.h>#include <ceddk.h>#include <nkintr.h>#include <pm.h>#include <drvmsg.h>#include <drvlib_mem.h>#include "pmplatform.h"#include "Pkfuncs.h"#include <types.h>#include <bsp.h>#include "gpioentry_reg.h"#include <assert.h>typedef enum{ EINT_SIGNAL_LOW_LEVEL = 0, EINT_SIGNAL_HIGH_LEVEL, EINT_SIGNAL_FALL_EDGE, EINT_SIGNAL_RISE_EDGE, EINT_SIGNAL_BOTH_EDGE}EINT_SIGNAL_METHOD; typedef enum{ EINT_FILTER_DISABLE = 0, EINT_FILTER_DELAY, EINT_FILTER_DIGITAL}EINT_FILTER_METHOD; static volatile GPIO_REG* g_pGPIOReg = NULL;static DWORD g_dwSysIntrHS38= SYSINTR_UNDEFINED;static HANDLE g_hEventHS38= NULL;static HANDLE g_hEventResetBtn= NULL;static HANDLE g_hThreadHS38= NULL;static BOOL g_bExitThread= FALSE;static BOOL pwstatus=TRUE; void Delay_us(int n);//延时usBOOLIRS_date(void);//判断遥控低电平static void InitInterrupt(void);//中断初始化void IRS_port_init(void); //引脚初始化void IRS_enable_interrupt(void);//使能中断void IRS_disable_interrupt(void);//不使能中断void IRS_clear_interrupt_pending(void);//清楚中断屏蔽位BOOLIRS_set_filter_method(EINT_FILTER_METHOD eMethod, unsignedint uiFilterWidth);//选择中断的filter方式BOOLIRS_set_interrupt_method(EINT_SIGNAL_METHOD eMethod);//设置中断方式2.解码线程:INTWINAPI HS38Thread(void){ int i,j; byte ircode[4];//四位编码 while(!g_bExitThread) { WaitForSingleObject(g_hEventHS38,INFINITE); if(g_bExitThread) { break; } IRS_disable_interrupt(); // 禁止中断 IRS_clear_interrupt_pending(); // 清除中断标志位 InterruptDone(g_dwSysIntrHS38); //中断完成,开始解码 Delay_us(8000);//延时掉ms的低电平, while(IRS_date()); Delay_us(4000);//4.5ms高电平 while(!IRS_date()); for(j=0;j<4;j++) { for(i=0;i<8;i++) { while(IRS_date()); Delay_us(700); if(IRS_date())// send 0 { ircode[j]=ircode[j]>>1; } else { ircode[j]=ircode[j]|0x80; ircode[j]=ircode[j]>>1; Delay_us(1200); } } } Sleep(100); RETAILMSG(1,(TEXT("******* ircode[3] = %x\r\n"),ircode[3]));//打印第三组操作码,便是按键的键码 IRS_enable_interrupt(); } return 0;}3.微妙延时函数void Delay_us(int n){ LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; doubledfMinus, dfFreq, dfTim; if(QueryPerformanceFrequency(&litmp)==FALSE) { return; } dfFreq = (double)litmp.QuadPart; QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart; do { QueryPerformanceCounter(&litmp); QPart2=litmp.QuadPart; dfMinus=(double)(QPart2-QPart1); dfTim=dfMinus/dfFreq; }while(dfTim<0.000001*n); }4.其他流驱动接口函数//设置寄存器地址BOOLHS38_initialize_register_address(void*pGPIOReg)//,void *pHSReg){ if(pGPIOReg == NULL) { returnFALSE; } else { g_pGPIOReg = (GPIO_REG *)pGPIOReg; } returnTRUE;}//初始化void IRS_port_init(void){ Set_PinFunction(g_pGPIOReg,GPH06_EXT_INT_6); Set_PinPullUD(g_pGPIOReg,GPH06_EXT_INT_6, sgip_PULL_UP); } //使能引脚中断void IRS_enable_interrupt(void){ Unmask_EXTINT(g_pGPIOReg, EXT_INT_6);} //禁止引脚中断void IRS_disable_interrupt(void){ Mask_EXTINT(g_pGPIOReg, EXT_INT_6); } //清除引脚中断void IRS_clear_interrupt_pending(void){ Clear_EXTINT(g_pGPIOReg, EXT_INT_6); } //设置中断方式BOOLIRS_set_interrupt_method(EINT_SIGNAL_METHOD eMethod){ BOOL Ret = TRUE; switch(eMethod) { caseEINT_SIGNAL_LOW_LEVEL: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_LOW_LEVEL); break; caseEINT_SIGNAL_HIGH_LEVEL: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_HIGH_LEVEL); break; caseEINT_SIGNAL_FALL_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_FALLING_EDGE); break; caseEINT_SIGNAL_RISE_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_RISING_EDGE); break; caseEINT_SIGNAL_BOTH_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_BOTH_EDGE); break; default: Ret = FALSE; break; } returnRet;} //设置中断filter方式BOOLIRS_set_filter_method(EINT_FILTER_METHOD eMethod, unsignedint uiFilterWidth){ BOOL Ret =TRUE; switch(eMethod) { caseEINT_FILTER_DISABLE: Clr_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6); break; caseEINT_FILTER_DELAY: Set_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6, sgip_DELAY_FLT, 0); break; caseEINT_FILTER_DIGITAL: Set_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6, sgip_DIGITAL_FLT, uiFilterWidth); break; default: Ret = FALSE; break; } returnRet;} //判断遥控接收引脚低电平,返回trueBOOLIRS_date(void){ if(Get_PinData(g_pGPIOReg,GPH06_EXT_INT_6)) { returnFALSE; // LowActive Switch (Pull-up switch) } else { returnTRUE; }} static BOOL AllocResources(void){ DWORD dwIRQ; PHYSICAL_ADDRESS ioPhysicalBase = {0,0}; //------------------ // GPIOController SFR //------------------ ioPhysicalBase.LowPart =BASE_REG_PA_GPIO; g_pGPIOReg = (GPIO_REG*)MmMapIoSpace(ioPhysicalBase, sizeof(GPIO_REG),FALSE); if(g_pGPIOReg == NULL) { returnFALSE; } dwIRQ = IRQ_EINT6; g_dwSysIntrHS38 = SYSINTR_UNDEFINED; g_hEventHS38 = NULL; if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIRQ, sizeof(DWORD), &g_dwSysIntrHS38, sizeof(DWORD), NULL)) { g_dwSysIntrHS38 =SYSINTR_UNDEFINED; returnFALSE; } g_hEventHS38 = CreateEvent(NULL, FALSE,FALSE, NULL); if(NULL== g_hEventHS38) { returnFALSE; } if(!(InterruptInitialize(g_dwSysIntrHS38, g_hEventHS38, 0, 0))) { returnFALSE; } returnTRUE;}static voidReleaseResources(void){ if(g_pGPIOReg != NULL) { MmUnmapIoSpace((PVOID)g_pGPIOReg, sizeof(GPIO_REG)); g_pGPIOReg = NULL; } if(g_dwSysIntrHS38 != SYSINTR_UNDEFINED) { InterruptDisable(g_dwSysIntrHS38); } if(g_hEventHS38 != NULL) { CloseHandle(g_hEventHS38); } if(g_dwSysIntrHS38 != SYSINTR_UNDEFINED) { KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&g_dwSysIntrHS38, sizeof(DWORD), NULL, 0,NULL); } g_pGPIOReg = NULL; g_dwSysIntrHS38 = SYSINTR_UNDEFINED; g_hEventHS38 = NULL; } static void InitInterrupt(void){ // 禁止中断 IRS_disable_interrupt(); // I初始化端口 IRS_port_init(); // 设置中断模式 IRS_set_interrupt_method(EINT_SIGNAL_BOTH_EDGE); IRS_set_filter_method(EINT_FILTER_DELAY,0); // 清除中断标志位 IRS_clear_interrupt_pending(); // 使能中断 IRS_enable_interrupt();} BOOLWINAPI DllEntry(HANDLE hinstDLL, DWORD dwReason, LPVOID /* lpvReserved */){ switch(dwReason) { caseDLL_PROCESS_ATTACH: DEBUGREGISTER((HINSTANCE)hinstDLL); returnTRUE; caseDLL_THREAD_ATTACH: break; caseDLL_THREAD_DETACH: break; caseDLL_PROCESS_DETACH: break;#ifdef UNDER_CE caseDLL_PROCESS_EXITING: break; caseDLL_SYSTEM_STARTED: break;#endif } returnTRUE;} BOOLIRS_Deinit(DWORD hDeviceContext){ g_bExitThread = TRUE; if(g_hThreadHS38) // Make Sure if thread is exist { IRS_disable_interrupt(); IRS_clear_interrupt_pending(); //Signal Thread to Finish SetEvent(g_hEventHS38); // Waitfor Thread to Finish WaitForSingleObject(g_hThreadHS38,INFINITE); CloseHandle(g_hThreadHS38); g_hThreadHS38 = NULL; } ReleaseResources(); //RETAILMSG(1,(TEXT("USERLED:IRS_Deinit\r\n"))); returnTRUE;} DWORDIRS_Init(DWORD dwContext){ RETAILMSG(1,(TEXT("Key_Gpio_Setting----\r\n"))); if(AllocResources() == FALSE) { gotoCleanUp; } HS38_initialize_register_address((void *)g_pGPIOReg); InitInterrupt(); g_hThreadHS38 = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) HS38Thread, NULL, 0, NULL); if(g_hThreadHS38 == NULL ) { gotoCleanUp; } returnTRUE; CleanUp: IRS_Deinit(0); returnFALSE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------BOOLIRS_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut){ returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode){ RETAILMSG(0,(TEXT("USERLED: IRS_Open\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------BOOLIRS_Close(DWORD hOpenContext){ RETAILMSG(0,(TEXT("USERLED: IRS_Close\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void IRS_PowerDown(DWORD hDeviceContext){ RETAILMSG(0,(TEXT("USERLED: IRS_PowerDown\r\n")));} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void IRS_PowerUp(DWORD hDeviceContext){ RETAILMSG(0,(TEXT("USERLED: IRS_PowerUp\r\n"))); } //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count){ RETAILMSG(0,(TEXT("USERLED: IRS_Read\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Seek(DWORD hOpenContext, long Amount, DWORDType){ RETAILMSG(0,(TEXT("USERLED: IRS_Seek\r\n"))); return 0;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes){ RETAILMSG(0,(TEXT("USERLED: IRS_Write\r\n"))); return 0;}6.实验结果,当你按下遥控器上的按键时,dnw或超级终端上会显示相应的按键码如下:
长时间按某一个按键,会显示同一个键值如下:
经过几天的研究,终于把OK210开发板wince红外驱动的部分给完成了。
开发工具:vs2005,飞凌官方OK210开发板,杜邦线3根,烙铁一把,焊锡,4.7k电阻一个。
开发软件:Win CE 6.0
下图是所需的开发工具
从网上找了好久,不是不能用,就是骗子代码,根本不能用,最可气的就是挂羊头卖狗肉,标着红外驱动,用自己宝贵的积分,下载下来一看根本就不是,浪费了我很多时间,最后没办法只能自己动手了,这里充分体现了毛主席“自己动手,丰衣足食”这句话的重要性。好了废话不多说吧我自己的这几天的思路告诉大家让大家以后少走弯路,在这里我也希望广大网友能够不吝惜自己的劳动成果,把自己的奋斗果实奉献下,这样能让很多网友少走弯路,大家庆幸之余也会非常感激”挖井人“的。首先,我是按照单片机解码的思路,开始制作的Win CE操作系统的红外驱动,可把我害苦了。我用的是中断+定时器。思路呢和网上所有的都一样,但是总是卡死在定时器上,定时器我用的是微秒级别的延时,这样已进入系统,总是不停地去响应定时器的中断,这样就卡死在线程了。系统连起都起不来了,害的我倒腾了好几天,最后没办法只能放弃了,改用延时,网上有现成的函数。解码的遥控器类型有很多,这里我只做了最通用的NEC遥控器,其他的只需要改一下高低电平时间就行了。NEC红外协议,作为接收端来讲,首先是引导码,有9ms的低电平,然后是4.5ms的高电平,然后是32位的操作码,对于按键来说我们只需要解第三组就可以了,其他的NEC协议的知识可以从网上搜索下有很多的。现在只做红外接收模块,将准备好的杜邦线插在红外的三个引脚上,引脚顺序,大家从网上搜索下,然后就是找一个直插的4.7k上拉电阻,接到hs0038的接受引脚和5v引脚中间。由于我的红外解码思路是中断所以只能找中断引脚了,但是通篇的找飞凌OK210开发板上中断引脚真的是太难找了,(⊙o⊙)最后没办法只能找已经引出的引脚了,最后发现按键上每个引脚都能用,都是中断引脚,最后我选择了外部中断6,开发板的k4按键,将按键的上拉电阻去掉,然后焊接出一条引线,接到红外接收器的接收引脚。下面是自己焊的红外接收模块。
好了硬件准备完毕,现在开始写驱动。1.包含的头文件://made in 2013-6-7 by mr wang #include "stdafx.h"#include <windows.h>#include <ceddk.h>#include <nkintr.h>#include <pm.h>#include <drvmsg.h>#include <drvlib_mem.h>#include "pmplatform.h"#include "Pkfuncs.h"#include <types.h>#include <bsp.h>#include "gpioentry_reg.h"#include <assert.h>typedef enum{ EINT_SIGNAL_LOW_LEVEL = 0, EINT_SIGNAL_HIGH_LEVEL, EINT_SIGNAL_FALL_EDGE, EINT_SIGNAL_RISE_EDGE, EINT_SIGNAL_BOTH_EDGE}EINT_SIGNAL_METHOD; typedef enum{ EINT_FILTER_DISABLE = 0, EINT_FILTER_DELAY, EINT_FILTER_DIGITAL}EINT_FILTER_METHOD; static volatile GPIO_REG* g_pGPIOReg = NULL;static DWORD g_dwSysIntrHS38= SYSINTR_UNDEFINED;static HANDLE g_hEventHS38= NULL;static HANDLE g_hEventResetBtn= NULL;static HANDLE g_hThreadHS38= NULL;static BOOL g_bExitThread= FALSE;static BOOL pwstatus=TRUE; void Delay_us(int n);//延时usBOOLIRS_date(void);//判断遥控低电平static void InitInterrupt(void);//中断初始化void IRS_port_init(void); //引脚初始化void IRS_enable_interrupt(void);//使能中断void IRS_disable_interrupt(void);//不使能中断void IRS_clear_interrupt_pending(void);//清楚中断屏蔽位BOOLIRS_set_filter_method(EINT_FILTER_METHOD eMethod, unsignedint uiFilterWidth);//选择中断的filter方式BOOLIRS_set_interrupt_method(EINT_SIGNAL_METHOD eMethod);//设置中断方式2.解码线程:INTWINAPI HS38Thread(void){ int i,j; byte ircode[4];//四位编码 while(!g_bExitThread) { WaitForSingleObject(g_hEventHS38,INFINITE); if(g_bExitThread) { break; } IRS_disable_interrupt(); // 禁止中断 IRS_clear_interrupt_pending(); // 清除中断标志位 InterruptDone(g_dwSysIntrHS38); //中断完成,开始解码 Delay_us(8000);//延时掉ms的低电平, while(IRS_date()); Delay_us(4000);//4.5ms高电平 while(!IRS_date()); for(j=0;j<4;j++) { for(i=0;i<8;i++) { while(IRS_date()); Delay_us(700); if(IRS_date())// send 0 { ircode[j]=ircode[j]>>1; } else { ircode[j]=ircode[j]|0x80; ircode[j]=ircode[j]>>1; Delay_us(1200); } } } Sleep(100); RETAILMSG(1,(TEXT("******* ircode[3] = %x\r\n"),ircode[3]));//打印第三组操作码,便是按键的键码 IRS_enable_interrupt(); } return 0;}3.微妙延时函数void Delay_us(int n){ LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; doubledfMinus, dfFreq, dfTim; if(QueryPerformanceFrequency(&litmp)==FALSE) { return; } dfFreq = (double)litmp.QuadPart; QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart; do { QueryPerformanceCounter(&litmp); QPart2=litmp.QuadPart; dfMinus=(double)(QPart2-QPart1); dfTim=dfMinus/dfFreq; }while(dfTim<0.000001*n); }4.其他流驱动接口函数//设置寄存器地址BOOLHS38_initialize_register_address(void*pGPIOReg)//,void *pHSReg){ if(pGPIOReg == NULL) { returnFALSE; } else { g_pGPIOReg = (GPIO_REG *)pGPIOReg; } returnTRUE;}//初始化void IRS_port_init(void){ Set_PinFunction(g_pGPIOReg,GPH06_EXT_INT_6); Set_PinPullUD(g_pGPIOReg,GPH06_EXT_INT_6, sgip_PULL_UP); } //使能引脚中断void IRS_enable_interrupt(void){ Unmask_EXTINT(g_pGPIOReg, EXT_INT_6);} //禁止引脚中断void IRS_disable_interrupt(void){ Mask_EXTINT(g_pGPIOReg, EXT_INT_6); } //清除引脚中断void IRS_clear_interrupt_pending(void){ Clear_EXTINT(g_pGPIOReg, EXT_INT_6); } //设置中断方式BOOLIRS_set_interrupt_method(EINT_SIGNAL_METHOD eMethod){ BOOL Ret = TRUE; switch(eMethod) { caseEINT_SIGNAL_LOW_LEVEL: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_LOW_LEVEL); break; caseEINT_SIGNAL_HIGH_LEVEL: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_HIGH_LEVEL); break; caseEINT_SIGNAL_FALL_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_FALLING_EDGE); break; caseEINT_SIGNAL_RISE_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_RISING_EDGE); break; caseEINT_SIGNAL_BOTH_EDGE: Set_EXTINT_TRLVL(g_pGPIOReg,EXT_INT_6, sgip_BOTH_EDGE); break; default: Ret = FALSE; break; } returnRet;} //设置中断filter方式BOOLIRS_set_filter_method(EINT_FILTER_METHOD eMethod, unsignedint uiFilterWidth){ BOOL Ret =TRUE; switch(eMethod) { caseEINT_FILTER_DISABLE: Clr_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6); break; caseEINT_FILTER_DELAY: Set_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6, sgip_DELAY_FLT, 0); break; caseEINT_FILTER_DIGITAL: Set_EXTINT_FILTER(g_pGPIOReg,EXT_INT_6, sgip_DIGITAL_FLT, uiFilterWidth); break; default: Ret = FALSE; break; } returnRet;} //判断遥控接收引脚低电平,返回trueBOOLIRS_date(void){ if(Get_PinData(g_pGPIOReg,GPH06_EXT_INT_6)) { returnFALSE; // LowActive Switch (Pull-up switch) } else { returnTRUE; }} static BOOL AllocResources(void){ DWORD dwIRQ; PHYSICAL_ADDRESS ioPhysicalBase = {0,0}; //------------------ // GPIOController SFR //------------------ ioPhysicalBase.LowPart =BASE_REG_PA_GPIO; g_pGPIOReg = (GPIO_REG*)MmMapIoSpace(ioPhysicalBase, sizeof(GPIO_REG),FALSE); if(g_pGPIOReg == NULL) { returnFALSE; } dwIRQ = IRQ_EINT6; g_dwSysIntrHS38 = SYSINTR_UNDEFINED; g_hEventHS38 = NULL; if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIRQ, sizeof(DWORD), &g_dwSysIntrHS38, sizeof(DWORD), NULL)) { g_dwSysIntrHS38 =SYSINTR_UNDEFINED; returnFALSE; } g_hEventHS38 = CreateEvent(NULL, FALSE,FALSE, NULL); if(NULL== g_hEventHS38) { returnFALSE; } if(!(InterruptInitialize(g_dwSysIntrHS38, g_hEventHS38, 0, 0))) { returnFALSE; } returnTRUE;}static voidReleaseResources(void){ if(g_pGPIOReg != NULL) { MmUnmapIoSpace((PVOID)g_pGPIOReg, sizeof(GPIO_REG)); g_pGPIOReg = NULL; } if(g_dwSysIntrHS38 != SYSINTR_UNDEFINED) { InterruptDisable(g_dwSysIntrHS38); } if(g_hEventHS38 != NULL) { CloseHandle(g_hEventHS38); } if(g_dwSysIntrHS38 != SYSINTR_UNDEFINED) { KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&g_dwSysIntrHS38, sizeof(DWORD), NULL, 0,NULL); } g_pGPIOReg = NULL; g_dwSysIntrHS38 = SYSINTR_UNDEFINED; g_hEventHS38 = NULL; } static void InitInterrupt(void){ // 禁止中断 IRS_disable_interrupt(); // I初始化端口 IRS_port_init(); // 设置中断模式 IRS_set_interrupt_method(EINT_SIGNAL_BOTH_EDGE); IRS_set_filter_method(EINT_FILTER_DELAY,0); // 清除中断标志位 IRS_clear_interrupt_pending(); // 使能中断 IRS_enable_interrupt();} BOOLWINAPI DllEntry(HANDLE hinstDLL, DWORD dwReason, LPVOID /* lpvReserved */){ switch(dwReason) { caseDLL_PROCESS_ATTACH: DEBUGREGISTER((HINSTANCE)hinstDLL); returnTRUE; caseDLL_THREAD_ATTACH: break; caseDLL_THREAD_DETACH: break; caseDLL_PROCESS_DETACH: break;#ifdef UNDER_CE caseDLL_PROCESS_EXITING: break; caseDLL_SYSTEM_STARTED: break;#endif } returnTRUE;} BOOLIRS_Deinit(DWORD hDeviceContext){ g_bExitThread = TRUE; if(g_hThreadHS38) // Make Sure if thread is exist { IRS_disable_interrupt(); IRS_clear_interrupt_pending(); //Signal Thread to Finish SetEvent(g_hEventHS38); // Waitfor Thread to Finish WaitForSingleObject(g_hThreadHS38,INFINITE); CloseHandle(g_hThreadHS38); g_hThreadHS38 = NULL; } ReleaseResources(); //RETAILMSG(1,(TEXT("USERLED:IRS_Deinit\r\n"))); returnTRUE;} DWORDIRS_Init(DWORD dwContext){ RETAILMSG(1,(TEXT("Key_Gpio_Setting----\r\n"))); if(AllocResources() == FALSE) { gotoCleanUp; } HS38_initialize_register_address((void *)g_pGPIOReg); InitInterrupt(); g_hThreadHS38 = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) HS38Thread, NULL, 0, NULL); if(g_hThreadHS38 == NULL ) { gotoCleanUp; } returnTRUE; CleanUp: IRS_Deinit(0); returnFALSE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------BOOLIRS_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut){ returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode){ RETAILMSG(0,(TEXT("USERLED: IRS_Open\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------BOOLIRS_Close(DWORD hOpenContext){ RETAILMSG(0,(TEXT("USERLED: IRS_Close\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void IRS_PowerDown(DWORD hDeviceContext){ RETAILMSG(0,(TEXT("USERLED: IRS_PowerDown\r\n")));} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void IRS_PowerUp(DWORD hDeviceContext){ RETAILMSG(0,(TEXT("USERLED: IRS_PowerUp\r\n"))); } //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count){ RETAILMSG(0,(TEXT("USERLED: IRS_Read\r\n"))); returnTRUE;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Seek(DWORD hOpenContext, long Amount, DWORDType){ RETAILMSG(0,(TEXT("USERLED: IRS_Seek\r\n"))); return 0;} //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------DWORDIRS_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes){ RETAILMSG(0,(TEXT("USERLED: IRS_Write\r\n"))); return 0;}6.实验结果,当你按下遥控器上的按键时,dnw或超级终端上会显示相应的按键码如下:
长时间按某一个按键,会显示同一个键值如下:
经过几天的研究,终于把OK210开发板wince红外驱动的部分给完成了。
开发工具:vs2005,飞凌官方OK210开发板,杜邦线3根,烙铁一把,焊锡,4.7k电阻一个。
开发软件:Win CE 6.0
下图是所需的开发工具
从网上找了好久,不是不能用,就是骗子代码,根本不能用,最可气的就是挂羊头卖狗肉,标着红外驱动,用自己宝贵的积分,下载下来一看根本就不是,浪费了我很多时间,最后没办法只能自己动手了,这里充分体现了毛主席“自己动手,丰衣足食”这句话的重要性。好了废话不多说吧我自己的这几天的思路告诉大家让大家以后少走弯路,在这里我也希望广大网友能够不吝惜自己的劳动成果,把自己的奋斗果实奉献下,这样能让很多网友少走弯路,大家庆幸之余也会非常感激”挖井人“的。首先,我是按照单片机解码的思路,开始制作的Win CE操作系统的红外驱动,可把我害苦了。我用的是中断+定时器。思路呢和网上所有的都一样,但是总是卡死在定时器上,定时器我用的是微秒级别的延时,这样已进入系统,总是不停地去响应定时器的中断,这样就卡死在线程了。系统连起都起不来了,害的我倒腾了好几天,最后没办法只能放弃了,改用延时,网上有现成的函数。解码的遥控器类型有很多,这里我只做了最通用的NEC遥控器,其他的只需要改一下高低电平时间就行了。NEC红外协议,作为接收端来讲,首先是引导码,有9ms的低电平,然后是4.5ms的高电平,然后是32位的操作码,对于按键来说我们只需要解第三组就可以了,其他的NEC协议的知识可以从网上搜索下有很多的。现在只做红外接收模块,将准备好的杜邦线插在红外的三个引脚上,引脚顺序,大家从网上搜索下,然后就是找一个直插的4.7k上拉电阻,接到hs0038的接受引脚和5v引脚中间。由于我的红外解码思路是中断所以只能找中断引脚了,但是通篇的找飞凌OK210开发板上中断引脚真的是太难找了,(⊙o⊙)最后没办法只能找已经引出的引脚了,最后发现按键上每个引脚都能用,都是中断引脚,最后我选择了外部中断6,开发板的k4按键,将按键的上拉电阻去掉,然后焊接出一条引线,接到红外接收器的接收引脚。下面是自己焊的红外接收模块。
好了硬件准备完毕,现在开始写驱动。1.包含的头文件://made in 2013-6-7 by mr wang #include "stdafx.h"#include <windows.h>#include <ceddk.h>#include <nkintr.h>#include <pm.h>#include <drvmsg.h>#include <drvlib_mem.h>#include "pmplatform.h"#include "Pkfuncs.h"#include <types.h>#include <bsp.h>#include "gpioentry_reg.h"#include <assert.h>typedef enum{ EINT_SIGNAL_LOW_LEVEL = 0, EINT_SIGNAL_HIGH_LEVEL, EINT_SIGNAL_FALL_EDGE, EINT_SIGNAL_RISE_EDGE, EINT_SIGNAL_BOTH_EDGE}EINT_SIGNAL_METHOD; typedef enum{ EINT_FILTER_DISABLE = 0, EINT_FILTER_DELAY, EINT_FILTER_DIGITAL}EINT_FILTER_METHOD; static volatile GPIO_REG* g_pGPIOReg = NULL;static DWORD g_dwSysIntrHS38= SYSINTR_UNDEFINED;static HANDLE g_hEventHS38= NULL;static HANDLE g_hEventResetBtn= NULL;static HANDLE g_hThreadHS38= NULL;static BOOL g_bExitThread= FALSE;static BOOL pwstatus=TRUE; void Delay_us(int n);//延时usBOOLIRS_date(void);//判断遥控低电平static void InitInterrupt(void);//中断初始化void IRS_port_init(void); //引脚初始化void IRS_enable_interrupt(void);//使能中断void IRS_disable_interrupt(void);//不使能中断void IRS_clear_interrupt_pending(void);//清楚中断屏蔽位BOOLIRS_set_filter_method(EINT_FILTER_METHOD eMethod, unsignedint uiFilterWidth);//选择中断的filter方式BOOLIRS_set_interrupt_method(EINT_SIGNAL_METHOD eMethod);//设置中断方式2.解码线程:INTWINAPI HS38Thread(void){ int i,j; byte ircode[4];//四位编码 while(!g_bExitThread) { WaitForSingleObject(g_hEventHS38,INFINITE); if(g_bExitThread) { break; } IRS_disable_interrupt(); // 禁止中断 IRS_clear_interrupt_pending(); // 清除中断标志位 InterruptDone(g_dwSysIntrHS38); //中断完成,开始解码 Delay_us(8000);//延时掉ms的低电平, while(IRS_date()); Delay_us(4000);//4.5ms高电平 while(!IRS_date()); for(j=0;j<4;j++) { for(i=0;i<8;i++) { while(IRS_date()); Delay_us(700); if(IRS_date())// send 0 { ircode[j]=ircode[j]>>1; } else { ircode[j]=ircode[j]|0x80; ircode[j]=ircode[j]>>1; Delay_us(1200); } } } Sleep(100); RETAILMSG(1,(TEXT("******* ircode[3] = %x\r\n"),ircode[3]));//打印第三组操作码,便是按键的键码 IRS_enable_interrupt(); } return 0;}3.微妙延时函数void Delay_us(int n){ LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; doubledfMinu