打印
[ZLG-MCU]

LPC900系列I2C中断软件包

[复制链接]
2397|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wishhealth|  楼主 | 2007-11-25 19:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
zlgmcu| | 2007-11-26 09:33 | 只看该作者

re

一般分为硬件方式及软件方式.

您好,您只需要在www.zlgmcu.com搜索"软件包"
您自然就会找到I2C软件包.
主要参看硬件方式.

另在www.zlgmcu.com中有很多I2C范例.
http://www.zlgmcu.com/philips/philips-yingrong-iic.asp

使用特权

评论回复
板凳
wishhealth|  楼主 | 2007-11-26 13:51 | 只看该作者

请教zlgmcu

有中断方式的软件包吗?谢谢!

使用特权

评论回复
地板
tangqin| | 2007-11-29 10:33 | 只看该作者

900系列中端有这个I2C端口的,直接操作相关寄存器就OK了

使用特权

评论回复
5
wishhealth|  楼主 | 2007-12-2 18:23 | 只看该作者

现将小弟的程序贴上,请大家帮忙一起分析一下

使用中断的方式读写ZLG7290,写操作还可以,读操作不成功,小弟认为是I2C中断程序的问题,请帮忙一起分析下,谢谢了!!!
文件7290test.c
#include<reg935.h>
#include<900I2C.h>

#define   CSI24WC02 0xA0              /* i2c 定义器件地址 */
#define   ZLG7290   0x70

extern uint8     xdata I2C_sla;        
extern uint8    xdata I2C_suba;            
extern uint8     xdata I2C_suba_num;    
extern uint8     xdata *I2C_buf;        
extern uint8    xdata I2C_num;        
extern uint8    xdata I2C_end;        
extern uint8     xdata I2C_suba_en;        

uint8  xdata ReceiveBuffer=0;
uint8  xdata DisplayByte[16]={0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0xF6,0x6E,0x20,0x70,0x0E,0x1C,0x3A,0xCE,0xE6,0x0A};
uint8  xdata DisplayByteFull[15]={0x70,0x03,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff};
uint8  xdata DisplayByte6[6]={0xEE,0x3E,0x9C,0x7A,0x9E,0x8E};
uint8  xdata DispatchTimer=0;

bit    TimerTick=0;
bit    RequireSend=0;
bit    ReceivedByte=0;
/****************************************************************************/
/****************************************************************************/
void InitializeSystem(void)
{
 P1M1=0xbc;                      //10111100B                   
 P1M2=0x4c;                      //01001100B                      

 SCON=0xd0;                      //UART model 3,enable receive
 SSTAT=0x20;                     //UART individual interrupt
 BRGCON=0x00;                    //stop baud generate
 BRGR1=0x02;                     //9.6k
 BRGR0=0xF0;   
 BRGCON=0x03;                    //run baud generate   

 I2CInit();

 WDCON=0xe0;                     //关闭看门狗          
 RTCL=0xbf;                      //RTC low restore register,7.373MHz,0.15 second
 RTCH=0x21;                      //RTC high restore register
 RTCCON=0x63;                    //RTC use CCLK,enable RTC interrupt and RTC

 IEN0=0xd0;                         //开CPU中断,UART,RTC,I2C,
 IEN1=0x41;                      
}
/****************************************************************************/
/****************************************************************************/
void main()
{
 uint8 i=0;
 uint8 j=0;
 uint8 TickTimes=0;
 uint8 DisplayUnit[2]={0x70,0x03};
 uint8 GetKeys[4]={0x11};
 InitializeSystem();                 

 while(1)
 {
  if(TimerTick==1)
  {
   TimerTick=0;    

   if(TickTimes<12)TickTimes++;
   else TickTimes=0;

   if(TickTimes==2)
   {
    SBUF=GetKeys[0];
    DisplayByte6[5]=DisplayByte6[0];
    for(i=0;i<5;i++)DisplayByte6=DisplayByte6[i+1];
    I2C_WriteNByte(ZLG7290,ONE_BYTE_SUBA,0x10,DisplayByte6,4);  //send data display
   }
   if(TickTimes==3)SBUF=GetKeys[1];
   if(TickTimes==4)SBUF=GetKeys[3];
   if(TickTimes==5)SBUF=GetKeys[3];
   if(TickTimes==6)
   {
    I2C_WriteNByte(ZLG7290,ONE_BYTE_SUBA,0x07,DisplayByteFull,2);  //send data display
    if(j<4)j++;
    else j=0;
    DisplayByteFull[1]=1<<j;
   }
   //if(TickTimes==8)I2C_ReadNByte(ZLG7290,ONE_BYTE_SUBA,0x00,GetKeys,4);   //这条指令老不成功
  }
 }
}  
/****************************************************************************/
/****************************************************************************/
void int2() interrupt 10      //RTC 中断入口
{
 TimerTick=1;
 RTCCON=0x63;                 //clear interrupt      
}
/****************************************************************************/
/****************************************************************************/
void int3() interrupt 4       //UART RI 中断入口

 ReceiveBuffer=SBUF;
 ReceivedByte=1;
 RI=0;
}
/****************************************************************************/
/****************************************************************************/
void int4() interrupt 13      //UART TI 中断入口

 TI=0;
 RequireSend=0;               //release right of send
}
/****************************************************************************/
/***************************end of file**************************************/


文件900I2C.C
#include<900I2C.h>
#include<reg935.h>

/* 定义用于和I2C中断传递信息的全局变量 */
volatile uint8     xdata I2C_sla;            /* I2C器件从地址                     */
volatile uint8    xdata I2C_suba;            /* I2C器件内部子地址                 */
volatile uint8     xdata I2C_suba_num;        /* I2C子地址字节数                    */
volatile uint8     xdata *I2C_buf;            /* 数据缓冲区指针                      */
volatile uint8  xdata I2C_num;            /* 要读取/写入的数据个数             */
volatile uint8  xdata I2C_end=1;        /* I2C总线结束标志:结束总线是置1     */
volatile uint8     xdata I2C_suba_en;        /*     子地址控制。
                                        0--子地址已经处理或者不需要子地址
                                        1--读取操作
                                        2--写操作 */

/*******************************************************************************************************
* Function name:I2CInit()
*******************************************************************************************************/
void  I2CInit(void)
{  
 I2SCLH=I2SCLL=15;                //setting clock 7.373MHz/(15+15)/2=123KHz
}
/********************************************************************************************************
** 函数名称:ISendByte()
** 函数功能:向无子地址器件发送1字节数据。
** 入口参数:sla        器件地址
**           dat        要发送的数据
********************************************************************************************************/
void  ISendByte(uint8 sla, uint8 dat)
{  /* 参数设置 */
   I2C_sla     = sla;        // 写操作的器件地址
   I2C_buf     = &dat;        // 待发送的数据
   I2C_num     = 1;            // 发送1字节数据
   I2C_suba_en = 0;             // 无子地址
   I2C_end     = 0;
   
   I2CON=I2CON&0xd3;    //清零SI STA AA位
   I2CON=I2CON|0x60;    // 设置为主机,并启动总线
}
/********************************************************************************************************
** 函数名称:IRcvByte()
** 函数功能:向无子地址器件读取1字节数据。
** 入口参数:sla        器件地址
**           dat        接收数据的变量指针
********************************************************************************************************/
void  IRcvByte(uint8 sla, uint8 *dat)
{  /* 参数设置 */
   I2C_sla     = sla+1;        // 读操作的器件地址
   I2C_buf     = dat;
   I2C_num     = 1;
   I2C_suba_en = 0;            // 无子地址
   I2C_end     = 0;

   I2CON=I2CON&0xd3;    //清零SI STA AA位   
   I2CON=I2CON|0x60;    // 设置为主机,并启动总线
}
/********************************************************************************************************
** 函数名称 :I2C_ReadNByte()
** 函数功能 :从有子地址器件任意地址开始读取N字节数据
** 入口参数 :    sla            器件从地址
**                suba_type    子地址结构    1-单字节地址    2-8+X结构    2-双字节地址
**                suba        器件子地址
**                s            数据接收缓冲区指针
**                num            读取的个数
*******************************************************************************************************/
void I2C_ReadNByte (uint8 sla, uint8 suba_type, uint8 suba, uint8 *s, uint8 num)
{
    if (num > 0)    /* 判断num个数的合法性 */
    {    /* 参数设置 */
        if (suba_type == 1)
        {    /* 子地址为单字节 */
            I2C_sla         = sla + 1;                            /* 读器件的从地址,R=1     */
            I2C_suba        = suba;                                /* 器件子地址             */
            I2C_suba_num    = 1;                                /* 器件子地址为1字节     */
        }
        if (suba_type == 2)
        {    /* 子地址为2字节 */
            I2C_sla         = sla + 1;                            /* 读器件的从地址,R=1     */
            I2C_suba            = suba;                                /* 器件子地址             */
            I2C_suba_num    = 2;                                /* 器件子地址为2字节     */
        }
        if (suba_type == 3)
        {    /* 子地址结构为8+X*/
            I2C_sla            = sla + ((suba >> 7 )& 0x0e) + 1;    /* 读器件的从地址,R=1    */
            I2C_suba        = suba & 0x0ff;                        /* 器件子地址             */
            I2C_suba_num    = 1;                                /* 器件子地址为8+x         */
        }
        I2C_buf     = s;                                        /* 数据接收缓冲区指针     */
        I2C_num     = num;                                        /* 要读取的个数         */
        I2C_suba_en = 1;                                        /* 有子地址读             */
        I2C_end     = 0;

        I2CON=I2CON&0xd3;    //清零SI STA AA位   
        I2CON=I2CON|0x60;    // 设置为主机,并启动总线
    }
}

/********************************************************************************************************
** 函数名称 :I2C_WriteNByte()
** 函数功能 :向有子地址器件写入N字节数据
** 入口参数 :    sla            器件从地址
**                suba_type    子地址结构    1-单字节地址    3-8+X结构    2-双字节地址
**                  suba        器件内部物理地址
**                  *s            将要写入的数据的指针
**                  num            将要写入的数据的个数
********************************************************************************************************/
void I2C_WriteNByte(uint8 sla, uint8 suba_type, uint8 suba, uint8 *s, uint8 num)
{   
    if (num > 0)/* 如果读取的个数为0,则返回错误 */
    {    /* 设置参数 */    
        if (suba_type == 1)
        {    /* 子地址为单字节 */
            I2C_sla         = sla;                                /* 读器件的从地址         */
            I2C_suba        = suba;                                /* 器件子地址             */
            I2C_suba_num    = 1;                                /* 器件子地址为1字节     */
        }
        if (suba_type == 2)
        {    /* 子地址为2字节 */
            I2C_sla         = sla;                                /* 读器件的从地址         */
            I2C_suba            = suba;                                /* 器件子地址             */
            I2C_suba_num    = 2;                                /* 器件子地址为2字节     */
        }
        if (suba_type == 3)
        {    /* 子地址结构为8+X */
            I2C_sla            = sla + ((suba >> 7 )& 0x0e);        /* 读器件的从地址        */
            I2C_suba        = suba & 0x0ff;                        /* 器件子地址            */
            I2C_suba_num    = 1;                                /* 器件子地址为8+X         */
        }

        I2C_buf     = s;                                        /* 数据                 */
        I2C_num     = num;                                        /* 数据个数             */
        I2C_suba_en = 2;                                        /* 有子地址,写操作     */
        I2C_end     = 0;

        I2CON=I2CON&0xd3;    //清零SI STA AA位   
        I2CON=I2CON|0x60;    // 设置为主机,并启动总线
    }
}

/********************************************************************************************************
** 函数名称 :I2CInterrupt ()
** 函数名次 :硬件I2C中断服务程序。 
********************************************************************************************************/
void I2CInterrupt() interrupt 6       //IIC 中断入口
{    
    switch (I2STAT & 0xF8)
    {    /* 根据状态码进行相应的处理 */
        case 0x08:    /* 已发送起始条件 */                /* 主发送和主接收都有         */
            /* 装入SLA+W或者SLA+R */
             if(I2C_suba_en == 1)/* SLA+R */                /* 指定子地址读             */
             {    I2DAT = I2C_sla & 0xFE;                 /* 先写入地址                 */
             }
            else    /* SLA+W */
            {      I2DAT = I2C_sla;                        /* 否则直接发送从机地址     */
            }
            I2CON=I2CON&0xd7;    //清零SI STA位
            break;
            
           case 0x10:    /*已发送重复起始条件 */             /* 主发送和主接收都有         */
               /* 装入SLA+W或者SLA+R */
               I2DAT = I2C_sla;                            /* 重起总线后,重发从地址     */
               I2CON=I2CON&0xd7;    //清零SI STA位
               break;

        case 0x18:
           case 0x28:    /* 已发送I2DAT中的数据,已接收ACK */
               if (I2C_suba_en == 0)
               {
                   if (I2C_num > 0)
                   {    I2DAT = *I2C_buf++;
                       I2CON=I2CON&0xd7;    //清零SI STA位
                       I2C_num--;
                   }
                   else    /* 没有数据发送了 */
                   {        /* 停止总线 */
                    I2CON=I2CON|0x10;    //stop bus,set on bit STO 
                       I2CON=I2CON&0xd7;    //清零SI STA位
                         I2C_end = 1;                        /* 总线已经停止             */
                   }
               }
               
            if(I2C_suba_en == 1)    /* 若是指定地址读,则重新启动总线                 */
            { 
                if (I2C_suba_num == 2)
                {    I2DAT = ((I2C_suba >> 8) & 0xff);
                       I2CON=I2CON&0xd7;    //清零SI STA位
                       I2C_suba_num--;
                       break;    
                   } 
                   
                   if(I2C_suba_num == 1)
                   {    I2DAT = (I2C_suba & 0xff);
                       I2CON=I2CON&0xd7;    //清零SI STA位
                       I2C_suba_num--;
                       break;    
                   }
                   
                if (I2C_suba_num == 0)
                {    
                    I2CON=I2CON|0x20;    //start BUS,set on bit STA
                    I2CON=I2CON&0xf7;    //清零SI位
                       I2C_suba_en = 0;                     /* 子地址己处理             */
                       break;
                   }
            }
            
            if (I2C_suba_en == 2)/* 指定子地址写,子地址尚未指定,则发送子地址         */
               {
                    if (I2C_suba_num > 0)
                {    if (I2C_suba_num == 2)
                    {    I2DAT = ((I2C_suba >> 8) & 0xff);
                        I2CON=I2CON&0xd7;    //清零SI STA位
                        I2C_suba_num--;
                        break;
                    }
                    if (I2C_suba_num == 1)
                    {    I2DAT    = (I2C_suba & 0xff);
                           I2CON=I2CON&0xd7;    //清零SI STA位
                           I2C_suba_num--;
                           I2C_suba_en  = 0;
                           break;
                       }
                   }
             }
               break;
                 
       case 0x40:    /* 已发送SLA+R,已接收ACK */
               if (I2C_num <= 1)    /* 如果是最后一个字节 */            
               {    
                I2CON=I2CON&0xfb;    //clear AA
               }
               else
               {     
                I2CON=I2CON|0x04;    //set AA
               }
               I2CON=I2CON&0xd7;    //清零SI STA位
               break;

           case 0x20:    /* 已发送SLA+W,已接收非应答              */
           case 0x30:    /* 已发送I2DAT中的数据,已接收非应答     */
           case 0x38:    /* 在SLA+R/W或数据字节中丢失仲裁         */
           case 0x48:    /* 已发送SLA+R,已接收非应答              */
             I2CON=I2CON&0xd7;    //清零SI STA位
            I2C_end = 0xFF; 
               break;                   
    
        case 0x50:    /* 已接收数据字节,已返回ACK */
            *I2C_buf++ = I2DAT;
            I2C_num--;
            if (I2C_num == 1)/* 接收最后一个字节 */
            {      
                I2CON=I2CON&0xd3;    //清零SI AA STA位
            }
            else
            {      
                I2CON=I2CON|0x04;    //set AA
                  I2CON=I2CON&0xd7;    //清零SI STA位
            }
            break;
        
        case 0x58:    /* 已接收数据字节,已返回非应答 */
            *I2C_buf++ = I2DAT;                         /* 读取最后一字节数据         */
            I2CON=I2CON|0x10;    //stop bus,set on bit STO 
            I2CON=I2CON&0xd7;    //清零SI STA位
            I2C_end = 1; 
            break;
            
          default:
              break;
    }
}


使用特权

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

本版积分规则

9

主题

17

帖子

0

粉丝