本帖最后由 多拉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);
} |