小弟做的IIC读取温度的应用程序。运行我的应用程序后,系统拖死了,用示波器监测IIC波形是一直都在发送数据。但是运行网上下的IIC调试助手IICMgr_CE5.0.exe后,我的应用程序就正常了。即使把IICMgr_CE5.0.exe关了,再运行我的应用程序也正常的。另外,基本可以排除IICMgr_CE5.0.exe调用底层IIC驱动的可能,因为我把地层IIC全部屏蔽了。IICMgr_CE5.0.exe应该是直接从应用层调用的IIC。后来,我把IICMgr_CE5.0.exe运行时IIC相关的寄存器值读出来,再写到我应用程序里面,效果依然一样。现在,我只能怀疑IIC中断的问题了,但是在应用层怎么注册系统中断呢?请做过IIC的大哥指导一二啊!
以下是我的代码
// tempmonDlg.cpp : implementation file
//
#include "stdafx.h"
#include "tempmon.h"
#include "tempmonDlg.h"
#include "TPRmon.h"
#include "s3c2440a_ioport.h"
#include "s3c2440a_base_regs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define UBYTE unsigned char
/* GPIO 寄存器对应的虚拟地址 */
S3C2440A_IOPORT_REG * v_pIOPregs;
/* iic 变量 */
static unsigned int save_E,save_PE; /* GPE原来的值 */
#define WRDATA (1)
#define POLLACK (2)
#define RDDATA (3)
#define SETRDADDR (4)
typedef unsigned long U32;
typedef unsigned short U16;
typedef unsigned char U8;
#define IICBUFSIZE 0x20
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt;
static U8 _iicData[IICBUFSIZE];
IICreg * v_pIICPregs;
INTreg * v_pINTreg;
unsigned char tmpdata; //温度数据
/////////////////////////////////////////////////////////////////////////////
// CTempmonDlg dialog
//系统延时函数
void UsDelay(double t)
{
LARGE_INTEGER litmp ;
LONGLONG QPart1,QPart2 ;
double d=0;
QueryPerformanceCounter(&litmp) ;
QPart1 = litmp.QuadPart ;// 获得初始值
while (d
{
QueryPerformanceCounter(&litmp) ;
QPart2 = litmp.QuadPart ;
d=(double)(QPart2 - QPart1);
}
}
/*
void UsDelay(long t)
{
long i;
for(i=0;i
}
*/
BOOL IoConfig(void)
{
BOOL RetValue = TRUE;
v_pIOPregs = (S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof (S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
v_pIOPregs = (S3C2440A_IOPORT_REG *)IOP_BASE;//0xB1600000;
}
if (!RetValue)
{
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
return RetValue;
}
BOOL IicInitialize(void)
{
BOOL RetValue = TRUE;
v_pIICPregs = (IICreg *)VirtualAlloc(0, sizeof(IICreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIICPregs == NULL)
{
ERRORMSG(1,(TEXT("For IICPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
v_pIICPregs = (IICreg *)IIC_BASE;//0xB1400000;
}
if (!RetValue)
{
if (v_pIICPregs)
{
VirtualFree((PVOID) v_pIICPregs, 0, MEM_RELEASE);
}
v_pIICPregs = NULL;
}
return RetValue;
v_pIICPregs->rIICCON = 0xaf;//(1<<7) | (0<<6) | (1<<5) | (0xf);
v_pIICPregs->rIICADD = 0x10;//0x48;
v_pIICPregs->rIICSTAT = 0x11;
v_pIICPregs->rIICLC = 0x0;
return RetValue;
}
BOOL IntrInitialize(void)
{
BOOL RetValue = TRUE;
v_pINTreg = (INTreg *)VirtualAlloc(0, sizeof(INTreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pINTreg == NULL)
{
ERRORMSG(1,(TEXT("For IICPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
v_pINTreg = (INTreg *)INT_BASE;//0xB1400000;
}
if (!RetValue)
{
if (v_pINTreg)
{
VirtualFree((PVOID) v_pINTreg, 0, MEM_RELEASE);
}
v_pINTreg = NULL;
}
v_pINTreg->rINTMSK &=~(0x1<<27);
return RetValue;
}
void ConfigIICPin(void)
{
//将GPE14、GPE15配置成IIC的SDA和SCL
save_E = v_pIOPregs->GPECON; //保存GPE14、GPE15原始值
save_PE = v_pIOPregs->GPEUP;
v_pIOPregs->GPECON &= ~(0xf << 28); //清0
v_pIOPregs->GPECON |= (0xa << 28); //配置成IIC
v_pIOPregs->GPEUP |= ( 3<< 14); //禁止上拉
}
BOOL IicIni(void) //IIC初始化
{
BOOL RetValue = TRUE;
IoConfig();
ConfigIICPin();
RetValue = IicInitialize();
return RetValue;
}
void IicExit(void)
{
v_pIOPregs->GPEUP = save_PE;
v_pIOPregs->GPECON = save_E;
v_pIICPregs = NULL;
}
void IicPoll(void)
{
U32 iicSt,i;
iicSt = v_pIICPregs->rIICSTAT;
if(iicSt & 0x8){} /*When bus arbitration is failed.*/
if(iicSt & 0x4){} /*When a slave address is matched with IICADD*/
if(iicSt & 0x2){} /*When a slave address is 0000000b*/
if(iicSt & 0x1){} /*When ACK isn't received*/
switch(_iicMode)
{
case POLLACK:
_iicStatus = iicSt;
break;
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = v_pIICPregs->rIICDS;
v_pIICPregs->rIICSTAT = 0x90;
v_pIICPregs->rIICCON = 0xaf;
UsDelay(1);
break;
}
_iicData[_iicPt++] = v_pIICPregs->rIICDS;
if((_iicDataCount)==0)
v_pIICPregs->rIICCON = 0x2f;
else
v_pIICPregs->rIICCON = 0xaf;
break;
case WRDATA:
if((_iicDataCount--)==0)
{
v_pIICPregs->rIICSTAT = 0xd0;
v_pIICPregs->rIICCON = 0xaf;
UsDelay(1);
break;
}
v_pIICPregs->rIICDS = _iicData[_iicPt++];
for(i=0;i<10;i++);
v_pIICPregs->rIICCON = 0xaf;
break;
case SETRDADDR:
if((_iicDataCount--)==0)
{
break;
}
v_pIICPregs->rIICDS = _iicData[_iicPt++];
for(i=0;i<10;i++);
v_pIICPregs->rIICCON = 0xaf;
break;
default:
break;
}
}
void Run_IicPoll(void)
{
if(v_pIICPregs->rIICCON & 0x10)
IicPoll();
}
void Iic_write(U32 slvAddr,U32 addr,U8 data)
{
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
v_pIICPregs->rIICDS = slvAddr;
v_pIICPregs->rIICSTAT = 0xf0;
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = POLLACK;
while(1)
{
v_pIICPregs->rIICDS = slvAddr;
_iicStatus = 0x100;
v_pIICPregs->rIICSTAT = 0xf0;
v_pIICPregs->rIICCON = 0xaf;
while(_iicStatus==0x100)
Run_IicPoll();
if(!(_iicStatus & 0x1))
break;
}
v_pIICPregs->rIICSTAT = 0xd0;
v_pIICPregs->rIICCON = 0xaf;
UsDelay(1);
}
void Iic_read(U32 slvAddr,U32 addr,U8 *data)
{
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicDataCount = 1;
v_pIICPregs->rIICDS = slvAddr;
v_pIICPregs->rIICSTAT = 0xf0;
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
v_pIICPregs->rIICDS = slvAddr;
v_pIICPregs->rIICSTAT = 0xb0;
v_pIICPregs->rIICCON = 0xaf;
while(_iicDataCount!=-1)
Run_IicPoll();
*data = _iicData[1];
}
CTempmonDlg::CTempmonDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTempmonDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTempmonDlg)
m_tmpData = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTempmonDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTempmonDlg)
DDX_Text(pDX, IDC_EDIT1, m_tmpData);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTempmonDlg, CDialog)
//{{AFX_MSG_MAP(CTempmonDlg)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTempmonDlg message handlers
BOOL CTempmonDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CTempmonDlg::OnButton1()
{
// TODO: Add your control notification handler code here
U8 code;
IicIni();
IntrInitialize();
Iic_write(0x90,1,2);
Sleep(1);
Iic_read(0x90,0,&code);
m_tmpData = code;
Sleep(1);
IicExit();
//m_tmpData = WriteMaxReg();//向配置寄存器写2
/*
else
{
Iicwrite(0x90,0,0);
Sleep(1);
Iicread(0x91,0,&tmpdata);
Sleep(1);
m_tmpData = tmpdata;
IicExit();
}*/
UpdateData(FALSE);
}
BOOL CTempmonDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::DestroyWindow();
}