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

📄 f020smbus.txt

📁 SMBUS的程序,是一个很值得学习的,单片机是C8051F020,也特别适合初学者认真体会的,
💻 TXT
字号:

--------------------------------------------------------------------------------
 
/***********************************************************************************/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/***********************************************************************************/
#include"common.h"

char SLAW,DATA1[64];                   // 保存从地址+ WRITE 位
char SLAR;                             // 保存从地址+ WRITE 位
char WORD,WORDADR;                     // 保存被收/发的数据字节
char xdata sendnumber;                 // 保存被收/发的数据字节的数目        
//unsigned char xdata  WORDADR;        // 保存被传送的数据在24C02中的首地址.
unsigned char xdata SENDMODE;          // SENDMODE作读/写控制字                       
unsigned char xdata  i,j,k,sla,n,m,p;
bit SM_BUSY;                           // 忙碌标志位                                       
unsigned char check;                   // 测试用的工作变量

void main (void)
{

    system_initial(); 
 delay_nus(100);                                                          
    i=0x10;
    sla=CHIP_A;
    for (j=0;j<0x40;j++)               // 向24C02的000地址依次写入64个数据,
    {                                  // 64个数据的数值从10H---4FH   
        smbus_send(sla, j, i,0x01);    // 写入AT24C02
        i++;           
    }
    for (j=0;j<0x40;j++)               // 从24C02的00地址依次连续读出64个数据,
    {                                  // 64个数据的数值应该是从10H---3FH(连续存放)
        check=smbus_read(sla, j,0x01);     
        DATA1[j]=check;                // 读出来的数据依次连续存入数组DATA[]中
    }
    delay_nms(1000);
    while(1);
 }
/***********************************************************************************/
/**/
/**/
/***********************************************************************************/
void smbus_send(char chip, char wordadr, char word,char number)
{
    SENDMODE=0x01;
    sendnumber=number+1;
    while(SM_BUSY);                  // 若SMBUS忙碌就等待
    SM_BUSY = 1;                     // 置SM_BUSY位(忙碌标志位)为1                
    SLAW = (chip| WRITE);            // COMMAND = 7 个地址位 + 一位WRITE.
    WORD = word;                     // WORD中存放要送到24C02中去的数据(8位)
    WORDADR = wordadr;               // OP_CODE 中存放被传送数据送入24C02的首地址.
    STO = 0;
    STA = 1;                         // 启动数据传输
    while(SM_BUSY);                  // 等待传输完成
}
/***********************************************************************************/
/**/
/**/
/***********************************************************************************/
char smbus_read(char chip, char wordadr,char number)
{
    sendnumber=number;
    SENDMODE=0;
    while(SM_BUSY);                  // 若SMBUS忙碌就等待
    SM_BUSY = 1;                     // 置SM_BUSY位(忙碌标志位)为1 
    SLAR = (chip| READ);             // COMMAND = 7 个地址位 + 一位READ
    WORDADR = wordadr;               // OP_CODE 中存放从24C02读出数据的的首地址.
    STO = 0;
    STA = 1;                         // 启动传输
    while(SM_BUSY);                  // 等待传输完成 
    return WORD;                     // 返回读出来的数据(一个字节)
}
void SMBUS_ISR (void) interrupt 7    // 中断服务程序
{
    switch (SMB0STA)
 {                                // 根据中断状态码跳转
                                     // (SMB0STA 是中断状态寄存器)
       case SMB_START:              // 0x08, (MT & MR) 发送起始位
               
      SMB0DAT = SLAW ;      // 装入被访问的从芯片的写地址
               STA = 0;              // 人工清除 STA 位
               SI = 0;               // 清除中断标志位
               break;
       case SMB_RP_START:          // 0x10,(MT & MR) 重复发送起始位
        
         SMB0DAT = SLAR;       // 装入被访问的从芯片的读地址
               STA = 0;              // 人工清除 STA 位
               SI = 0;               // 清除中断标志位
               break;
       case SMB_MTADDACK:            // 0x18 ,(MT) 发送从地址 + W 后收到ACK
        
         SMB0DAT = WORDADR;
               SI = 0;               // 清除中断标志位
               break;
       case SMB_MTADDNACK:           // 0x20,(MT) 发送从地址 + W 后收到NACK
           
         STO = 1;
               STA = 1;
               SI = 0;                // 清除中断标志位
               break;
      case SMB_MTDBACK:            // 0x28,(MT) 发送数据后收到ACK
           switch (SENDMODE)
     {                          // 检查低1位
                  case 1:
                sendnumber--;
                if(sendnumber)
                     SMB0DAT = WORD;
                else
       {
                  STO=1;
                  SM_BUSY=0;
             }
                         break;             
                 case 0:
                STO = 0;
                         STA = 1;
                         break;            
                default:              
                         STO = 1;
                         SM_BUSY = 0;
                         break;
         }
         SI = 0;
         break;
     case SMB_MTDBNACK:               // 0x30
         STO = 1;
         STA = 1;
         SI = 0;                      // 清除中断标志
         break;
      case SMB_MRADDACK:              // 0x40
         AA = 0;                        
         SI = 0;
         break;
      case SMB_MRADDNACK:           //0x48
         STO = 0;
         STA = 1;
         SI = 0;
         break;
     case SMB_MRDBNACK:               //0x58
         WORD = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;
         AA = 1;                          
         SI = 0;
         break;
      default:
         STO = 1;
         SM_BUSY = 0;
         break;
      }
}
/***********************************************************************************/
/*                                 end                                             */
/***********************************************************************************/

 

/***********************************************************************************/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/***********************************************************************************/
#include"common.h"
extern bit SM_BUSY;                      // 忙碌标志位 
void system_initial (void)
{
     WDTCN = 0xde;                       // 关闭看们狗
     WDTCN = 0xad;
     clock_initial();                    // 时钟初始化
     XBR0 = 0x01;                        // 选交叉开关 :P0.0-->SDA,P0.1-->CLK
     XBR2 = 0x40;                        // 交叉开关使能
     SMB0CN = 0x44;                      // 允许SMBUS, 应答返回AA(低电平
     SMB0CR = 0xc9;                      // SMBus 速率= 100 kHz,系统时钟为11.0592MHZ
     EIE1 |= 2;                          // SMBus 中断使能
     EA = 1;                             // 开中断
     SM_BUSY = 0;                        // SM_BUSY是忙碌标志位
     SI = 0;                             // SM_BUSY中断标志位
                                       
}

void clock_initial (void)
{
     int i;                               // i 用于延时计数
     OSCXCN = 0x67;                       // 先选择外捕振荡器,频率位11.0592MHZ
     for (i=0; i < 256; i++) ;            // 再延时(>1ms),
     while (!(OSCXCN & 0x80)) ;           // 等待外部晶振稳定
     OSCICN = 0x88;                       // 选择外部晶振,允许时钟丢失检测
}

 

/*============================================================================*/
/*函数名称:delay.c                                                           */
/*函数功能:延时函数                                                          */
/*函数说明:函数中的参数可以根据自己需要改变                                  */  
/*编写日期:2007-1-26                                                         */
/*============================================================================*/


/*============================================================================*/
/*函数头文件                                                                  */
/*============================================================================*/
#include "common.h"
#include "delay.h"
/*============================================================================*/


/*============================================================================*/
/*1us延时函数                                                                  */
/*============================================================================*/
void delay_1us(void)                 /*1us延时函数*/
  {
    _nop_();
  }
/*============================================================================*/
/*N us延时函数                                                                */
/*============================================================================*/
void delay_nus(unsigned int n)       /*N us延时函数*/
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1us();
  }
/*============================================================================*/
/*1ms延时函数                                                                 */
/*============================================================================*/
void delay_1ms(void)                 /*1ms延时函数*/
  {
   unsigned int i;
   for (i=0;i<154;i++);
  }
/*============================================================================*/
/*N ms延时函数                                                                */
/*============================================================================*/
void delay_nms(unsigned int n)       /*N ms延时函数*/
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }
/*============================================================================*/
/*函数结束                                                                  */
/*============================================================================*/

 

#ifndef    _common_H_
#define    _common_H_
/************************************************************************************/
#include <c8051f020.h>                    // function declarations
#include <intrins.h>
#include <absacc.h>
#include <delay.h>

/************************************************************************************/
#define uint unsigned int                 //Data type definition   
#define uchar unsigned char  
#define ulong unsigned long  

/************************************************************************************/
void clock_initial (void);                //system clock initial
void SMBUS_ISR (void);                    //smbus_ISR
char smbus_read (char chip,char wordadr,char number);
void smbus_send (char chip,char wordadr, char word,char number);
void system_initial();

#define  WRITE          0x00              //SMBUS Addressing byte write-flag 
#define  READ           0x01              //SMBUS Addressing byte read-flag
                                          //Device addresses
#define  CHIP_A         0xA0              //AT24C02 own addressing word
#define  CHIP_B         0x70              //AT24C02 own addressing word
#define  SMB_BUS_ERROR  0x00              //bud error                                  
                                          //MT is main transmitter ,MR is main receiver
#define  SMB_START      0x08              //(MT & MR) sending starting byte
#define  SMB_RP_START   0x10              //(MT & MR) Repeat starting byte
#define  SMB_MTADDACK   0x18              //(MT) 发送从地址 + W 后收到ACK
#define  SMB_MTADDNACK  0x20              //(MT) 发送从地址 + W 后收到NACK
#define  SMB_MTDBACK    0x28              //(MT) 发送数据后收到ACK
#define  SMB_MTDBNACK   0x30              //(MT) 发送数据后收到NACK
#define  SMB_MTARBLOST  0x38              //(MT) 竞争失败
#define  SMB_MRADDACK   0x40              //(MR) 发送从地址 + R 后收到 ACK
#define  SMB_MRADDNACK  0x48              //(MR) 发送从地址 + R 后收到 NACK
#define  SMB_MRDACK     0x50              //(MR) 收到数据字节 后已发送ACK                                    
#define  SMB_MRDBNACK   0x58              //(MR) 收到数据字节 后已发送NACK   
/************************************************************************************/

#endif  



 

⌨️ 快捷键说明

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