主题 : WinCE 下可以对IIC的EEPROM等进行操作么 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 9121
精华: 0
发帖: 7
金钱: 70 两
威望: 35 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2009-09-17
最后登录: 2009-10-22
楼主  发表于: 2009-09-23 15:35

 WinCE 下可以对IIC的EEPROM等进行操作么

刚买了一块mini2440+T35的板子,今天学习了一下装系统,还好,都装上了。
但有一个问题,我看手册上对Linux系统的说明要比WinCE要说细好多。在Linux系统的内容里还介绍了关于IIC的EEPROM,PWM,GPIO等的测试。可WinCE中就没有。而且WinCE程序中也没有这样的测试程序。所以我想问一下,就现有的驱动、资源来说,在WinCE下,是否可以对上述的设备进行操作。
我是做电子电路、单片机出身的,所以对这几个设备比较看重,还请明白的朋友指点一二,先谢谢了。
级别: 新手上路
UID: 9140
精华: 0
发帖: 20
金钱: 140 两
威望: 52 点
贡献值: 0 点
综合积分: 40 分
注册时间: 2009-09-18
最后登录: 2014-05-29
1楼  发表于: 2009-09-23 19:27
完全可以,我刚写了一个代码,你先看看,最详细的代码见http://blog.sina.com.cn/tymanium
1.4.2 驱动程序架构和访问流程

l         体系结构和访问流程

在流式接口驱动程序中,驱动程序负责把外设抽象成一个文件,而应用程序则使用操作系统提供的文件API对外设进行访问。文件API被操作系统转发到FileSys.exe进程中;然后FileSys.exe发现是对设备的操作,就会把执行交给Device.exe处理;接着Device.exe根据具体的请求,调用流驱动接口函数;最终,驱动程序负责与硬件交互。

图7 流接口驱动体系结构

       具体过程分析如下:

(1)       应用程序须使用该设备,首先调用CreateFile(TEXT(“IIC1”)…)打开设备。CreateFile函数是在FileSys.exe中实现的。但是FileSys.exe只作简单判断:如果发现打开的是设备驱动而不是一个文件,那么就重新把主动权交还给设备管理器。

(2)       设备管理器调用驱动程序中的IIC_Open()函数打开设备。在IIC_Open中,驱动程序可以对硬件进行一些额外的初始化工作,使硬件进入工作状态。

(3)       IIC_Open()函数把打开设备的结果返回给设备管理器。

(4)       设备管理器把IIC_Open()返回的结果再传给应用程序中的CreateFile()函数调用。

(5)       设备已被成功打开,接下来可对设备进行读写和控制操作。以控制操作为例,CreateFile函数返回的句柄作为DeviceIoControl()的第1个参数,向设备发送控制请求。同样,DeviceIoControl()要FileSys.exe转发给设备管理器。

(6)       设备管理器调用驱动程序中的IIC_IOControl()函数,与硬件完成交互,读写设备的数据信息,然后返回给设备管理器,再返回给应用程序。

(7)       当应用程序不再使用该设备时,它可调用CloseHandle()将设备关闭。此时调用的是驱动程序中的IIC_Close()函数。

l         驱动目录组织

在AT24LC08读写驱动中,根据访问和交互的对象不同,将驱动程序目录组织如下:

Ø         IICBus.c               用于和用户态程序的交互,提供流驱动接口函数;

Ø         IIC2440.c              和S3C2440的硬件交互,完成寄存器的配置;

Ø         24LC08.c                     对AT24LC08芯片操作,按照芯片的读写模式配置。
1.4.3 流驱动接口函数的实现

       在本驱动中,定义前缀为“IIC”,IICBus.c文件中的流接口驱动函数都以该前缀命名,本驱动中流接口重点实现以下3个函数:

BOOL IIC_Init(DWORD dwcontext)

BOOL IIC_Deinit(DWORD hDeviceContext)

BOOL IIC_IOControl(DWORD hOpenContext, DWORD dwCode,

                            EEPROM_INFO *pBufIn, DWORD dwLenIn,

                            U8 *pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)

         IIC_Init()函数

该函数在设备加载时被调用,具体代码实现:

BOOL IIC_Init(DWORD dwcontext)

{

RETAILMSG(DBG_OUT,(TEXT("IIC_Init--- \r\n")));

Virtual_Alloc();

Setup_IIC();

return TRUE;

}

Setup_IIC()函数完成一些端口的初始化,以及IIC总线寄存器的初始化配置。

Setup_IIC()

{

RETAILMSG(DBG_OUT,(TEXT("IIC_INTR_Gpio_setting --- \r\n")));

s2440IOP->rGPEUP  |=  0xc000;                           //Pull-up disable

s2440IOP->rGPECON=(s2440IOP->rGPECON&~(3<<30))|(2 << 30);  //GPE15=IICSDA.

s2440IOP->rGPECON=(s2440IOP->rGPECON&~(3 << 28))|(2 << 28);  //GPE14=IICSCL.

s2440IIC->rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);           //Tx clock = 0.195MHz

       //[Bit7] = Enable ACK, [Bit6] = Prescaler IICCLK=PCLK/16, [Bit5] = Enable interrupt;

       //[Bit3:0] = Transmit clock value Tx clock=IICCLK/16

s2440IIC->rIICSTAT = 0x10;                      //IIC bus data output enable(Rx/Tx)

s2440IIC->rIICADD  = 0x10;                     //2440 slave address = [7:1]

s2440IIC->rIICLC = (1<<2)|(3);               // Filter enable, 15 clocks SDA output delay

return TRUE;

}

        IIC_Deinit()函数

该函数在设备卸载时被调用,释放加载时申请的虚拟地址空间,具体代码实现:

       BOOL IIC_Deinit(DWORD hDeviceContext)

{

              RETAILMSG(DBG_OUT, (TEXT("IIC_INTR_Deinit --- \r\n")));

              VirtualFree((void*)s2440IOP, sizeof(IOPreg), MEM_RELEASE);

              VirtualFree((void*)s2440IIC, sizeof(PWMreg), MEM_RELEASE);

              return TRUE;

}

         IIC_IOControl()函数

该函数用于处理应用程序发送过来的控制命令,控制指令dwCode有IOCTL_IIC_READ和IOCTL_IIC_WRITE两种。当收到读指令IOCTL_IIC_READ时,保存读操作的起始地址和读取字节数,然后调用E2P_Read()函数读取AT24LC08上的数据,将实际读取的字节数保存到*pdwActualOut。同样,当收到写指令IOCTL_IIC_WRITE时,保存写操作的起始地址和写字节数,然后调用E2P_PageWrite()函数往AT24LC08上写数据,将实际写入的字节数保存到*pdwActualOut。

BOOL IIC_IOControl(DWORD hOpenContext, DWORD dwCode,

EEPROM_INFO *pBufIn, DWORD dwLenIn,

U8 *pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)

{

       RETAILMSG(DBG_OUT,(TEXT("IIC: +IIC_IOControl (%d) \r\n"), dwCode));

       switch(dwCode){

              case IOCTL_IIC_READ:

              {

                     U16 ReadAddress = pBufIn->start_address;                    

                     U8 ReadNum = (U8)dwLenOut;                         //ReadNum为要读取的字节数

                     *pdwActualOut = E2P_Read(ReadAddress, ReadNum, pBufOut);

                     return TRUE;

              }

              case IOCTL_IIC_WRITE:

              {

                     U16 WriteAddress = pBufIn->start_address;              

                     U8 WriteNum = (U8)dwLenIn;

                     *pdwActualOut = E2P_Write(WriteAddress, WriteNum, pBufIn->dwData);

                     return TRUE;

              }

       }

       return TRUE;

}
这个阶段正是我事业的上升期,我怎么能走得开呢?
级别: 精灵王
UID: 3197
精华: 3
发帖: 770
金钱: 6995 两
威望: 5398 点
贡献值: 21 点
综合积分: 1600 分
注册时间: 2008-12-30
最后登录: 2010-12-31
2楼  发表于: 2009-09-23 21:02
楼上的文章很不错,不过怎么没有应用层的测试程序?
级别: 新手上路
UID: 9121
精华: 0
发帖: 7
金钱: 70 两
威望: 35 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2009-09-17
最后登录: 2009-10-22
3楼  发表于: 2009-09-24 17:52
先谢谢了。我还是个新手,得好好看看,学习一下。