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

📄 wsaa1064.c

📁 C8051F.rar
💻 C
字号:
//参考程序A  : WSAA1064.C 功能: SAA1064 驱动四位数码管,显示"3,2,1,0 "  
#include <c8051f020.h>                    // SFR declarations
#define  WRITE       0x00                 //  SMBUS寻址字节的写标志位
#define  READ        0x01                 //  SMBUS寻址字节的读标志位
#define  CHIP_B        0x70              //SAA1064器件自身的寻址字节
#define  SMB_BUS_ERROR  0x0         //总线错误       
                                    //MT为主发送器,MR为主接收器:
#define  SMB_START      0x08        // (MT & MR) 发送起始位
#define  SMB_RP_START   0x10        // (MT & MR) 重复起始位
#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      
char SLAW,DATA1[64];                      // SLAW保存从地址+ WRITE 位
char DATA0[6]={0x17,0x4f,0xb5,0x06,0x3f}; //SAA1064控制码,"3","2","1","0".
char SLAR;                                // 保存从地址+ READ 位
char WORD,WORDADR;                        // 保存被收/发的数据字节
char xdata sendnumber;                    // 保存被收/发的数据字节的数目        
//unsigned char xdata  WORDADR;      //保存被传送的数据在SAA1064中的首地址.
unsigned char xdata SENDMODE;                                      
unsigned char i,j;
bit SM_BUSY;                              
void SYSCLK_Init (void);
void SMBUS_ISR (void);
char SLA_READ(char sla,char wordadr,char number);
void SLA_SEND(char sla,char wordadr, char word,char number);
void MAIN (void)
{
   unsigned char check;         // 工作变量 check
   WDTCN = 0xde;                // 关闭看们狗
   WDTCN = 0xad;
   SYSCLK_Init();           // 时钟初始化
   XBR0 = 0x01;             // 选交叉开关	:P0.0-->SDA,P0.1-->SCL
   XBR2 = 0x40;             // 交叉开关使能
   SMB0CN = 0x44;           // 允许SMBUS, 应答返回AA(低电平)
   SMB0CR = 0x0C9;          // SMBus 时钟速率 = 100 kHz(系统时钟为11.0592MHZ)
   EIE1 |= 2;               // SMBus 中断使能
   EA = 1;                  // 开中断
   SM_BUSY = 0;             //  SM_BUSY是标志位
   SI = 0;                  //SM_BUSY中断标志位
 //写5个连续的数据到SAA1064的寄存器中去.要求四位数码显示"0","1","2","3"
 //第一个是控制命令(17H),第二到第四个数是四位数码显示的字型码:3FH,06H,5BH,4FH
  for  (j=0;j<0x6;j++)          //向SAA1064的0地址依次写入5个数据,
  { i=DATA0[j];                 
   SLA_SEND(CHIP_B, j, i,0x01 ); //5个数据的数值是:
   }             // "17H"(控制码),"3FH"("0"),"06H"("1")"5BH"("2"),"4FH"("3")
 while(1) ;
  }
void SYSCLK_Init (void)
{
   int i;                              /*延时计数器*/
   OSCXCN = 0x67;                      /*启动外部11.0592MHz晶振*/
   for (i=0; i < 255; i++) ;           /*等待外部晶体起振*/
   while ((OSCXCN & 0x80)==0x00) ;     /*查询标志位*/
   OSCICN = 0x088;               /*选择外部晶体作为系统时钟并使能时钟丢失检测*/  
}                    
void SLA_SEND(char sla, char wordadr, char word,char number){
  SENDMODE=0x01;
   sendnumber=number+1;
   while(SM_BUSY);         // 若SMBUS忙碌就等待
   SM_BUSY = 1;            // 置SM_BUSY位(忙碌标志位)为1
   SLAW = (CHIP_B| WRITE); // COMMAND = 7 个地址位 + 一位WRITE.
   WORD = word;            // WORD中存放要送到24C02中去的数据(8位)
   WORDADR = wordadr;      //WORDADR 中存放被传送数据送入24C02的首地址.
   STO = 0;
   STA = 1;                // 启动数据传输
	while(SM_BUSY);        // 等待传输完成
}
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    (MT) 发送数据后收到NACK
         STO = 1;
         STA = 1;
         SI = 0;                          // 清除中断标志
         break;
      case SMB_MRADDACK:	//0x40   (MR) 发送从地址 + R 后收到 ACK
         AA = 0;                          // 回送NACK
         SI = 0;
         break;
      case SMB_MRADDNACK:	//0x48   (MR) 发送从地址 + R 后收到 NACK
         STO = 0;
         STA = 1;
         SI = 0;
         break;
      case SMB_MRDBNACK:	//0x58   (MR) 收到数据字节 后已发送NACK   
         WORD = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;
         AA = 1;                          // AA置1
         SI = 0;
         break;
      default:
         STO = 1;
         SM_BUSY = 0;
         break;
      }
}

⌨️ 快捷键说明

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