⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbus.c

📁 书中详细说明了多路数据采集的方法,以及怎么样用AD来采集数据哟,大家不妨看看嘛,说不定有所帮助哟?
💻 C
字号:
/***************************************Copyright (c)*************************************
**
/*--------------文件信息------------------------------------------------------------------  
**文 件 名:SMBUS.C 
**创 建 人:王胜
**日    期:2007年2月4日  
**描    述:
**         本库函数可实现I2C总线一次读/写多个字节操作,将这两个文件复制到您的工程目录下,在
**         主函数中使用头文件包含语句  #include "SMBUS.h" 即可,其中包含三个函数:
**
**         SMBUS初始化函数:
**         void SMBus_Init(void);
**
**         多个字节数据的发送函数:
**         void SMBUS_Puts(
**                            unsigned char chip,
**						      unsigned char wordadr,
**						      char *dat,
**						      unsigned char number
**						  );
**
**         多个字节数据的读取函数:
**         void SMBUS_Gets(
**                            unsigned char chip,
**							  unsigned char wordadr,
**							  char *dat,
**							  unsigned char number
**						  );
**
**         输入变量定义如下:
**         chip    : 为I2C器件从地址,本实验板3个I2C器件(ZLG7290,24C02,PCF8563)的从地址定义                 
**                  (不包括R/W的控制)在头文件"SMBUS.h"中有定义。
**         wordadr : 为I2C器件内部寄存器从器件子地址。
**         dat     : 为读/写数据指针,当为读取时,通过指针直接修改变量的值。
**         number  : 为每次读/写数据的字节数。
*******************************************************************************************/

#include <c8051f020.h>

//与SMBUS操作有关变量定义
bit SM_BUSY;                       //SMB0忙标志位.
unsigned char SMBMODE;             //SMB0读写控制字CHIP_SELECT+R/W.
unsigned char SMB_num;             //SMB0一次读写的字节数..
unsigned char start_adr;           //SMB0读写字节在器件中的起始地址.
char          *SMB_Dat;            //SMBUS中断传输数据指针

/******************************************************************************************/ 
/*函数名称:SMBus_Init()                                                                  */
/*函数功能:SMBus初始化函数                                                               */
/*输入参数:无                                                                            */
/*输出参数:无                                                                            */
/******************************************************************************************/ 
void SMBus_Init(void)       
{
    SMB0CN    = 0x44;  //允许SMBUS, 应答返回AA(低电平有效)
    SMB0CR    = 0x00;  //配置传送速度为42Kbit/s
    EIE1     |= 0x02;  //使能SMBUS中断
    EIP1     |= 0x02;  //设置SMBUS中断为高优先级
}
                                                        
/******************************************************************************************/
/*函数名称:SMBUS_Puts()                                                                  */
/*函数功能:SMBUS 总线综合发送函数,向从机发送number个字节的数据                          */
/*入口参数:chip     从机地址(7位纯地址,不含读写位)                                      
            wordadr  从机的子地址
			data     待发送的数据指针 
			number   发送数据的字节数                                                     */                                                     
/*出口参数:无                                                                            */
/******************************************************************************************/

void SMBUS_Puts(unsigned char chip,unsigned char wordadr,char *dat,unsigned char number)
{  
   SI = 0;
   SMB_num=number;          // 确定写数据大小
   while (SM_BUSY);         // 若SMBUS忙碌就等待
   SM_BUSY = 1;             // SM_BUSY是忙碌标志位 
   SMBMODE=chip & 0xfe;
   start_adr=wordadr;       // 装载写字节起始地址
   SMB_Dat= dat;
   STO = 0;
   STA = 1;  
   while (SM_BUSY);
}
 
/******************************************************************************************/
/*函数名称:SMBUS_Gets()                                                                  */
/*函数功能:SMBUS 总线综合接收函数,从从机接收number个字节的数据                          */
/*入口参数:chip     从机地址(7位纯地址,不含读写位)                                      
            wordadr  从机的子地址
			*data    保存接收到的数据 
			number   读取数据的字节数                                                     */                                                     
/*出口参数:无                                                                            */
/******************************************************************************************/  

void SMBUS_Gets(unsigned char chip,unsigned char wordadr,char *dat,unsigned char number)
{
   SI = 0;
   SMB_num = number;          //确定写数据大小
   while (SM_BUSY);           // 若SMBUS忙碌就等待
   SM_BUSY = 1;               // SM_BUSY是忙碌标志位 
   SMBMODE = chip | 0x01;   
   start_adr = wordadr;       //装载写字节起始地址
   SMB_Dat =dat;    
   STO = 0;
   STA = 1; 
   while (SM_BUSY); 
}

//SMBUS中断服务函数
void SMBUS_ISR (void) interrupt 7
{
   switch (SMB0STA)
   {                  
      case  0x08:					    //(MT & MR) 发送起始位
         SMB0DAT = (SMBMODE & 0xFE);    //发送从器件地址 + W
         STA = 0;                      
         break;
      case  0x10:				        //(MT & MR) 重复起始位
         SMB0DAT = (SMBMODE | 0x01);    // 发送从器件地址 + R.
         STA = 0;
         break;
      case 0x18:				        //(MT) 发送从地址 + W 后收到ACK
         SMB0DAT = start_adr;           // 发送SMB0读写字节在器件中的起始地址.
         break;
      case  0x20:				        //(MT) 发送从地址 + W 后收到NACK
         STO = 1;
         STA = 1;
         break;
      case  0x28:					    //(MT) 发送数据后收到ACK
         if(SMB_num)
		 {							    
             if (SMBMODE & 0x01)        // 如果为读操作则重新启动总线.
			 {     
                 STO = 0;
                 STA = 1;
           	  } 
			 else 
			 { 
                 SMB0DAT = *SMB_Dat;   //如果为写操作则将数据写入SMB0DAT.
                 SMB_Dat++;		
				 SMB_num--;
              }
          }
		 else           //如果数据写入完毕则发送停止信号.
		 { 
             STO = 1;
             SM_BUSY = 0; 
          }
         break;
      case  0x30:       //(MT) 发送数据后收到NACK
         STO = 1;
         STA = 1;
         break;
      case  0x38 :	    //(MT)竞争失败
         STO = 1;
         STA = 1;
         break;
      case  0x40:       //(MR) 发送从地址 + R 后收到 ACK
         if(SMB_num==1) //如果只读一个字节则将应答位AA清0,
		  AA = 0;       //收到数据以后不发送应答位               
         else
		 AA = 1;        //如果读字节数大于1则收到数据以后发送应答位
         break;
      case  0x48:	    //(MR) 发送从地址 + R 后收到 NACK
         STO = 0;
         STA = 1;
         break;
      case  0x50:		//(MR) 收到数据字节 后已发送ACK  
		 if(SMB_num>2)
		 {								 
            *SMB_Dat = SMB0DAT;  
            SMB_Dat++;
			SMB_num--;
			AA=1;           
          }
		 else if(SMB_num ==2)
		 { 
			 *SMB_Dat = SMB0DAT;  
             SMB_Dat++;
			 SMB_num--;
			 AA=0;
          }                  
          break;
      case  0x58:	  //(MR) 收到数据字节 后已发送NACK 
         *SMB_Dat = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;                   
         break;
      default:
         STO = 1;                         
         SM_BUSY = 0;
         break;
      }
     SI=0;    // 清除中断标志
 }



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -