2789|8

92

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

CE5+2440的IIC问题 [复制链接]


小弟做的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();
}

最新回复

你说的那个return语句,是很明显的阿,以后调试时不要遇到问题就手忙脚乱的,慢慢来! 好,谢谢,收藏了!  详情 回复 发表于 2009-6-26 17:01
点赞 关注

回复
举报

68

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
有没有大哥帮帮忙啊,
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
帮忙看看啊
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

4
 

1、你的代码使用的是【查询方式】;

2、IIC调试助手也使用的是【查询方式】。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

5
 
引用 3 楼 zaodt 的回复:

1、你的代码使用的是【查询方式】;

2、IIC调试助手也使用的是【查询方式】。


那为什么运行IIC调试助手后我的程序也就正常了啊?我查看过IIC的寄存器,所有的配置都一样啊
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

6
 
我移植别人代码,很顺利。

建议楼主找 2410 的周立功的那个BSP看看。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

7
 
楼主注意下每次读写IIC后都要清一次IIC寄存器,还有要注意程序中的竞争关系。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

8
 
问题已经解决,函数IicInitialize()里面在设置iic寄存器之前多了一句return语句,所以就没有能够设置好iic的寄存器。但是,还是谢谢各位的关心!这段代码是可以直接在应用程序下无限iic驱动就可以操作iic的,保证可用,有需要的兄弟可以直接使用!
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

9
 
你说的那个return语句,是很明显的阿,以后调试时不要遇到问题就手忙脚乱的,慢慢来!

好,谢谢,收藏了!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表