打印

[飞凌嵌入式 ] 飞凌嵌入式OK335 xD Win CE学习之使用IIC

[复制链接]
2192|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 多拉A梦喜欢你 于 2014-10-7 14:55 编辑

    前几天购买了一套飞凌公司的OK335xD开发板,开发板到手后,首先按照手册做了一遍,整体感觉还可以,出厂默认系统是Linux,由于我一直做ce,而且飞凌公司已经发布了ce6.0的bsp包于是我就下载了一份。貌似飞凌的335x系列开发板已经全部都支持ce6.0了,这在国内只此一家,不信可以上淘宝。真心佩服飞凌的实力。好了废话不多说了,TI的335x芯片号称是史上资料最全的芯片但是网上搜索335的wince资料是真心的少啊,少的可怜,为了方便后人我就把我新作的iic的程序和心得写出来。
IIC的通信原理我就不说了,网上搜索有很多的。我使用的是飞凌公司的OK335xD开发板,IIC芯片为AT24C02,大小是256字节。由于飞凌底板上没有24c02芯片所以我还需要自己亲自动手焊接一个。


                           原理图

一开始我以为原理图画好了,飞凌bsp里面有自带的IIC驱动,我就直接写应用程序就可以了,但是程序写好后,iic始终打不开,难道是驱动没有加载,但是我看了OK335xD的原理图音频芯片也使用了iic通信,为什么音频能使用我的iic设备打不开呢。最后上网查资料,我去原来我需要修改pinmux文件这就是TI和三星的最大的不同了,三星的东西是都在寄存器里面设置好的,然后把各个iic的驱动都一一加载上,但是TI的东西需要先配置引脚如下:
#define I2C2_PADS    \
PAD_ENTRY(SPI0_SCLK,  (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)) /* I2C_DATA */  \
PAD_ENTRY(SPI0_D0, (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)) /* I2C_SCLK */  \
配置好引脚后开始做应用程序,应用程序界面如下所示:


测试程序代码如下:
// Forlinx_IICDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "Forlinx_IIC.h"
#include "Forlinx_IICDlg.h"
#include "i2cproxy.h"
#include "sdk_i2c.h"
#include "winioctl.h"



#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define FILE_DEVICE_UNKNOWN 0x00000022
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0

//------------------------------------------------------------------------------

#define IOCTL_I2C_SET_SLAVE_ADDRESS     \
    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)

//------------------------------------------------------------------------------

#define IOCTL_I2C_SET_SUBADDRESS_MODE     \
    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0201, METHOD_BUFFERED, FILE_ANY_ACCESS)

//------------------------------------------------------------------------------

#define IOCTL_I2C_SET_BAUD_INDEX     \
    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0202, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define  PAGE_SIZE 8
#define  SLAVEADDR 0x0

HANDLE IICFILE;
// CForlinx_IICDlg 对话框

CForlinx_IICDlg::CForlinx_IICDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CForlinx_IICDlg::IDD, pParent)
{
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CForlinx_IICDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CForlinx_IICDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
        ON_WM_SIZE()
#endif
        //}}AFX_MSG_MAP
        ON_BN_CLICKED(IDC_BUTTON1, &CForlinx_IICDlg::OnBnClickedButton1)
        ON_BN_CLICKED(IDC_BUTTON2, &CForlinx_IICDlg::OnBnClickedButton2)
        ON_BN_CLICKED(IDC_BUTTON3, &CForlinx_IICDlg::OnBnClickedButton3)
        ON_BN_CLICKED(IDC_BUTTON4, &CForlinx_IICDlg::OnBnClickedButton4)
END_MESSAGE_MAP()


// CForlinx_IICDlg 消息处理程序

BOOL CForlinx_IICDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        // TODO: 在此添加额外的初始化代码
        
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CForlinx_IICDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
        if (AfxIsDRAEnabled())
        {
                DRA::RelayoutDialog(
                        AfxGetResourceHandle(),
                        this->m_hWnd,
                        DRA::GetDisplayMode() != DRA::Portrait ?
                        MAKEINTRESOURCE(IDD_FORLINX_IIC_DIALOG_WIDE) :
                        MAKEINTRESOURCE(IDD_FORLINX_IIC_DIALOG));
        }
}
#endif


void CForlinx_IICDlg::OnBnClickedButton1()
{
        // TODO: 在此添加控件通知处理程序代码
            BOOL ret;
    DWORD dwSlaveAddr = SLAVEADDR;
    DWORD dwSubAddrMode = I2C_SUBADDRESS_MODE_8;
    DWORD dwBaud = 1;
    // 打开iic驱动 IICFILE
    IICFILE = CreateFile(TEXT("I2C3:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
    if (IICFILE == INVALID_HANDLE_VALUE)
    {
        RETAILMSG(1,(_T("FORLINX: OPEN I2C3 Failed \r\n")));
        return;
    }
    else {
        RETAILMSG(1,(_T("FORLINX: OPEN I2C3 Sucessed \r\n")));
    }
   
    ret = DeviceIoControl(IICFILE,IOCTL_I2C_SET_SLAVE_ADDRESS,&dwSlaveAddr,0,NULL,0,NULL,NULL);
    if(!ret) {
        RETAILMSG(1,(_T("FORLINX: OPEN IOCTL_I2C_SET_SLAVE_ADDRESS Failed \r\n")));
        return ;
    }        
   
    ret = DeviceIoControl(IICFILE,IOCTL_I2C_SET_SUBADDRESS_MODE,&dwSubAddrMode,0,NULL,0,NULL,NULL);
    if(!ret) {
    RETAILMSG(1,(_T("FORLINX: OPEN IOCTL_I2C_SET_SUBADDRESS_MODE Failed \r\n")));
        return ;
    }        
   
    ret = DeviceIoControl(IICFILE,IOCTL_I2C_SET_BAUD_INDEX,&dwBaud,0,NULL,0,NULL,NULL);
    if(!ret) {
    RETAILMSG(1,(_T("FORLINX: OPEN IOCTL_I2C_SET_BAUD_INDEX Failed \r\n")));
        return ;
    }        
    RETAILMSG(1,(_T("FORLINX: OPEN Sucessed \r\n")));
}

void CForlinx_IICDlg::OnBnClickedButton2()
{
        // TODO: 在此添加控件通知处理程序代码
            if (IICFILE != INVALID_HANDLE_VALUE)
    {
        CloseHandle(IICFILE);
        IICFILE = INVALID_HANDLE_VALUE;
    }
}

BOOL WriteData(HANDLE hI2C,UINT8 offset, UINT32 *psendbuff, USHORT len)
{
    //    BOOL      ret ;
    DWORD  bRet;
    UINT32    ulAlign,ulWriteLen,ulWritedNum;
    DWORD writelen;     //成功写入的长度
    DWORD I2c_addr = SLAVEADDR;
    ulWritedNum = 0;                                                     /* 初始化已经写入的个数为0     */

    if((offset + len) > 256){                                            /* 写入的有效性                */
        return -1;
    }
    while(1){
        if(len > 0){
            ulAlign = offset % PAGE_SIZE;                         /* 计算要写入的地址是否页对齐  */
            if (ulAlign == 0) {
                if (len > PAGE_SIZE) {                            /* 如果长度大于1页             */
                    ulWriteLen = PAGE_SIZE;
                }
                else {
                    ulWriteLen = len;
                }
            }else {
                if(len > (PAGE_SIZE - ulAlign)) {
                    ulWriteLen = PAGE_SIZE - ulAlign;
                }else {
                    ulWriteLen = len;
                }
            }

            
            bRet = DeviceIoControl(hI2C,IOCTL_I2C_SET_SLAVE_ADDRESS,&I2c_addr,0,NULL,0,NULL,NULL);
            if(!bRet) {
                RETAILMSG(1,(_T("AT24C02-WriteData :IOCTL_I2C_SET_SLAVE_ADDRESS Failed .....................\r\n")));
                return FALSE;
            }        
            bRet = SetFilePointer(hI2C,(BYTE)offset,NULL,FILE_BEGIN);
            //bRet = DeviceIoControl(hI2C,IOCTL_I2C_SET_SUBADDRESS,&offset,0,NULL,0,NULL,NULL);
            if(!bRet) {
                RETAILMSG(1,(_T("AT24C02-WriteData :SetFilePointer Failed .....................\r\n")));
                return FALSE;
            }        

            bRet = WriteFile(hI2C,psendbuff,ulWriteLen,&writelen,NULL);
            if(writelen!=ulWriteLen) {
                RETAILMSG(1,(_T("AT24C02-WriteData :Write Data Failed ..................... bRet = %d  writelen = %d\r\n"),bRet,writelen));
                return FALSE;
            }
            Sleep(10);                                             /* 延时10ms                      */

            offset       +=  ulWriteLen;
            ulWritedNum  +=  ulWriteLen;
            len          -=  ulWriteLen;
            psendbuff    += ulWriteLen;
        }else{
            break;
        }
    }
    return TRUE;

}

void CForlinx_IICDlg::OnBnClickedButton3()
{
        // TODO: 在此添加控件通知处理程序代码
        DWORD  bRet;
    DWORD offset = 0;
    DWORD I2c_addr = SLAVEADDR;
    UINT32 prcvbuff;
    DWORD dwLength = 32;
    DWORD dwLengthRcv;
    CString str;

    bRet = DeviceIoControl(IICFILE,IOCTL_I2C_SET_SLAVE_ADDRESS,&I2c_addr,0,NULL,0,NULL,NULL);
    if(!bRet) {
        RETAILMSG(1,(_T("AT24C02-WriteData :IOCTL_I2C_SET_SLAVE_ADDRESS Failed .....................\r\n")));
        return ;
    }        
    bRet = SetFilePointer(IICFILE,(BYTE)offset,NULL,FILE_BEGIN);
    //bRet = DeviceIoControl(IICFILE,IOCTL_I2C_SET_SUBADDRESS,&offset,0,NULL,0,NULL,NULL);
    if(!bRet) {
        RETAILMSG(1,(_T("AT24C02-WriteData :SetFilePointer Failed .....................\r\n")));
        return ;
    }        
   
        ReadFile(IICFILE, &prcvbuff, dwLength, &dwLengthRcv, NULL);
        RETAILMSG(1,(_T("prcvbuff =")));
   // for (i=0;i<255;i++)
   // {
    //    RETAILMSG(1,(_T(" %d"),prcvbuff));
   // }
         str.Format(_T("%d"),prcvbuff);
    GetDlgItem(IDC_EDIT1)->SetWindowText(str);
            RETAILMSG(1,(_T("\r\n dwLengthRcv = %d"),dwLengthRcv));
}

void CForlinx_IICDlg::OnBnClickedButton4()
{
        // TODO: 在此添加控件通知处理程序代码
         //  UCHAR psendbuff[32];
  //  int i;
  //  for (i=0;i<255;i++)
  //  {
    //    psendbuff = i;
  //  }
        UINT32 pInBuffer = 0x00;
         pInBuffer = GetDlgItemInt(IDC_EDIT2);
   

    WriteData(IICFILE,0,&pInBuffer,32);
}

022.jpg (31.94 KB )

原理图

原理图

023.jpg (14.41 KB )

应用程序界面

应用程序界面

相关帖子

沙发
jameswangchip| | 2014-10-8 09:39 | 只看该作者
飞凌嵌入式的335x系列开发板已经全部支持ce6.0了。

使用特权

评论回复
板凳
jameswangchip| | 2014-10-8 09:39 | 只看该作者
飞凌嵌入式的335x系列开发板已经全部支持ce6.0了。

使用特权

评论回复
地板
forlinx2013| | 2014-10-10 15:55 | 只看该作者
有很多工程师都在学习使用飞凌嵌入式开发平台。 :)

使用特权

评论回复
5
hanxiucao1988| | 2014-10-13 13:14 | 只看该作者
了解一下飞凌嵌入式的德州仪器平台和三星平台的区别。

使用特权

评论回复
6
jameswangchip| | 2014-10-17 15:25 | 只看该作者
飞凌嵌入式的OK335xD 支持WINCE ,ANDROID ,LINUX 。

使用特权

评论回复
7
forlinx2013| | 2014-10-20 11:40 | 只看该作者
飞凌嵌入式OK335xD 平台很多工业控制,测试测量工程师都在使用。

使用特权

评论回复
8
jamesforlinx| | 2014-10-20 11:44 | 只看该作者
自己焊接,丰衣足食。 :victory:

使用特权

评论回复
9
chen_jhhb| | 2014-10-20 13:48 | 只看该作者
学习,赞一个

使用特权

评论回复
10
jameswangchip| | 2014-10-21 14:01 | 只看该作者
看到了很多朋友使用飞凌嵌入式的开发平台,期待有更多的朋友做成更好的项目。

使用特权

评论回复
11
车彦锋| | 2014-10-21 14:13 | 只看该作者

使用特权

评论回复
12
jameswangchip| | 2014-10-22 09:33 | 只看该作者
飞凌嵌入式的OK335xD 开发平台, OK335xS开发平台, OK335xS-II 开发平台使用的朋友很多。最近飞凌嵌入式OK335xS-II 的开发板赠送工程师朋友的活动很火。

使用特权

评论回复
13
baodingforlinx| | 2014-10-22 13:15 | 只看该作者
TI 的335x平台在工业级应用很广。

使用特权

评论回复
14
jameswangchip| | 2014-10-24 13:26 | 只看该作者
:)大家一起来学习开发。

使用特权

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

本版积分规则

1

主题

1

帖子

0

粉丝