?? smbus.c
字號(hào):
/***************************************Copyright (c)*************************************
**
/*--------------文件信息------------------------------------------------------------------
**文 件 名:SMBUS.C
**創(chuàng) 建 人:王勝
**日 期:2007年2月4日
**描 述:
** 本庫(kù)函數(shù)可實(shí)現(xiàn)I2C總線一次讀/寫多個(gè)字節(jié)操作,將這兩個(gè)文件復(fù)制到您的工程目錄下,在
** 主函數(shù)中使用頭文件包含語(yǔ)句 #include "SMBUS.h" 即可,其中包含三個(gè)函數(shù):
**
** SMBUS初始化函數(shù):
** void SMBus_Init(void);
**
** 多個(gè)字節(jié)數(shù)據(jù)的發(fā)送函數(shù):
** void SMBUS_Puts(
** unsigned char chip,
** unsigned char wordadr,
** char *dat,
** unsigned char number
** );
**
** 多個(gè)字節(jié)數(shù)據(jù)的讀取函數(shù):
** void SMBUS_Gets(
** unsigned char chip,
** unsigned char wordadr,
** char *dat,
** unsigned char number
** );
**
** 輸入變量定義如下:
** chip : 為I2C器件從地址,本實(shí)驗(yàn)板3個(gè)I2C器件(ZLG7290,24C02,PCF8563)的從地址定義
** (不包括R/W的控制)在頭文件"SMBUS.h"中有定義。
** wordadr : 為I2C器件內(nèi)部寄存器從器件子地址。
** dat : 為讀/寫數(shù)據(jù)指針,當(dāng)為讀取時(shí),通過(guò)指針直接修改變量的值。
** number : 為每次讀/寫數(shù)據(jù)的字節(jié)數(shù)。
**
** 硬件使用信息:
** SMBUS通信接口: SDA-->P0.6 SCL-->P0.7
**
*******************************************************************************************/
#include <c8051f020.h>
//與SMBUS操作有關(guān)變量定義
bit SM_BUSY; //SMB0忙標(biāo)志位.
unsigned char SMBMODE; //SMB0讀寫控制字CHIP_SELECT+R/W.
unsigned char SMB_num; //SMB0一次讀寫的字節(jié)數(shù)..
unsigned char start_adr; //SMB0讀寫字節(jié)在器件中的起始地址.
char *SMB_Dat; //SMBUS中斷傳輸數(shù)據(jù)指針
/******************************************************************************************/
/*函數(shù)名稱:SMBus_Init() */
/*函數(shù)功能:SMBus初始化函數(shù) */
/*輸入?yún)?shù):無(wú) */
/*輸出參數(shù):無(wú) */
/******************************************************************************************/
void SMBus_Init(void)
{
SMB0CN = 0x44; //允許SMBUS, 應(yīng)答返回AA(低電平有效)
SMB0CR = 0x00; //配置傳送速度為42Kbit/s
EIE1 |= 0x02; //使能SMBUS中斷
EIP1 |= 0x02; //設(shè)置SMBUS中斷為高優(yōu)先級(jí)
}
/******************************************************************************************/
/*函數(shù)名稱:SMBUS_Puts() */
/*函數(shù)功能:SMBUS 總線綜合發(fā)送函數(shù),向從機(jī)發(fā)送number個(gè)字節(jié)的數(shù)據(jù) */
/*入口參數(shù):chip 從機(jī)地址(7位純地址,不含讀寫位)
wordadr 從機(jī)的子地址
data 待發(fā)送的數(shù)據(jù)指針
number 發(fā)送數(shù)據(jù)的字節(jié)數(shù) */
/*出口參數(shù):無(wú) */
/******************************************************************************************/
void SMBUS_Puts(unsigned char chip,unsigned char wordadr,char *dat,unsigned char number)
{
SI = 0;
SMB_num=number; // 確定寫數(shù)據(jù)大小
while (SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // SM_BUSY是忙碌標(biāo)志位
SMBMODE=chip & 0xfe;
start_adr=wordadr; // 裝載寫字節(jié)起始地址
SMB_Dat= dat;
STO = 0;
STA = 1;
while (SM_BUSY);
}
/******************************************************************************************/
/*函數(shù)名稱:SMBUS_Gets() */
/*函數(shù)功能:SMBUS 總線綜合接收函數(shù),從從機(jī)接收number個(gè)字節(jié)的數(shù)據(jù) */
/*入口參數(shù):chip 從機(jī)地址(7位純地址,不含讀寫位)
wordadr 從機(jī)的子地址
*data 保存接收到的數(shù)據(jù)
number 讀取數(shù)據(jù)的字節(jié)數(shù) */
/*出口參數(shù):無(wú) */
/******************************************************************************************/
void SMBUS_Gets(unsigned char chip,unsigned char wordadr,char *dat,unsigned char number)
{
SI = 0;
SMB_num = number; //確定寫數(shù)據(jù)大小
while (SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // SM_BUSY是忙碌標(biāo)志位
SMBMODE = chip | 0x01;
start_adr = wordadr; //裝載寫字節(jié)起始地址
SMB_Dat =dat;
STO = 0;
STA = 1;
while (SM_BUSY);
}
//SMBUS中斷服務(wù)函數(shù)
void SMBUS_ISR (void) interrupt 7
{
switch (SMB0STA)
{
case 0x08: //(MT & MR) 發(fā)送起始位
SMB0DAT = (SMBMODE & 0xFE); //發(fā)送從器件地址 + W
STA = 0;
break;
case 0x10: //(MT & MR) 重復(fù)起始位
SMB0DAT = (SMBMODE | 0x01); // 發(fā)送從器件地址 + R.
STA = 0;
break;
case 0x18: //(MT) 發(fā)送從地址 + W 后收到ACK
SMB0DAT = start_adr; // 發(fā)送SMB0讀寫字節(jié)在器件中的起始地址.
break;
case 0x20: //(MT) 發(fā)送從地址 + W 后收到NACK
STO = 1;
STA = 1;
break;
case 0x28: //(MT) 發(fā)送數(shù)據(jù)后收到ACK
if(SMB_num)
{
if (SMBMODE & 0x01) // 如果為讀操作則重新啟動(dòng)總線.
{
STO = 0;
STA = 1;
}
else
{
SMB0DAT = *SMB_Dat; //如果為寫操作則將數(shù)據(jù)寫入SMB0DAT.
SMB_Dat++;
SMB_num--;
}
}
else //如果數(shù)據(jù)寫入完畢則發(fā)送停止信號(hào).
{
STO = 1;
SM_BUSY = 0;
}
break;
case 0x30: //(MT) 發(fā)送數(shù)據(jù)后收到NACK
STO = 1;
STA = 1;
break;
case 0x38 : //(MT)競(jìng)爭(zhēng)失敗
STO = 1;
STA = 1;
break;
case 0x40: //(MR) 發(fā)送從地址 + R 后收到 ACK
if(SMB_num==1) //如果只讀一個(gè)字節(jié)則將應(yīng)答位AA清0,
AA = 0; //收到數(shù)據(jù)以后不發(fā)送應(yīng)答位
else
AA = 1; //如果讀字節(jié)數(shù)大于1則收到數(shù)據(jù)以后發(fā)送應(yīng)答位
break;
case 0x48: //(MR) 發(fā)送從地址 + R 后收到 NACK
STO = 0;
STA = 1;
break;
case 0x50: //(MR) 收到數(shù)據(jù)字節(jié) 后已發(fā)送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) 收到數(shù)據(jù)字節(jié) 后已發(fā)送NACK
*SMB_Dat = SMB0DAT;
STO = 1;
SM_BUSY = 0;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
SI=0; // 清除中斷標(biāo)志
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -