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

📄 s3530a.c

📁 S3530a和C8051f020的通信测试程序!
💻 C
字号:
#include <c8051f.h>	
#include <S3530A.h>				// SFR declarations
#include "INTRINS.H"

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

union 
{
unsigned char ClockString[7];
struct RealClock
	{
		unsigned char Year,Month,Day,Week,Hour,Minute,Second;
	} RT;
} RealTime;

char COMMAND;			// Holds the slave address + R/W bit for use in the SMBus ISR.

unsigned char *I2CDataBuff;						

char BYTE_NUMBER;							// Used by ISR to check what data has just been
												// sent - High address byte, Low byte, or data byte

unsigned char HIGH_ADD, LOW_ADD;		// High & Low byte for EEPROM memory address
				
bit SM_BUSY;								// This bit is set when a send or receive
												// is started. It is cleared by the
CDateTime  g_objDateTime;												// ISR when the operation is finished.


//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void SMBus_ISR (void);								

//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
//
// Main routine configures the crossbar and SMBus, and tests
// the SMBus interface between the three EEPROMs


void ResetRealClock(void)
{
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle
	BYTE_NUMBER = 0;									// 2 address bytes.
	COMMAND = (CLOCK3530_ADDRESS_RESET | READ);		// Chip select + READ
	STA = 1;											// Start transfer
	while (SM_BUSY);									// Wait for transfer to finish
}

//======================写S-3530A内部实时数据寄存器程序=====================
//功能:将设定年、月、日、星期、时、分、秒数据写入S-3530A                  |
//入口:发送数据放在年、月、日、星期、时、分、秒各寄存器                   |
//出口:NONE                                                               |
//==========================================================================
void SetRealClock(void)
{
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle
	BYTE_NUMBER = 7;									// 2 address bytes.
	COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | WRITE);		// Chip select + WRITE
	I2CDataBuff = &RealTime.ClockString[0];				// Data to be writen
	STA = 1;											// Start transfer
}

//==================读S-3530A实时数据寄存器子程序===========================
//功能:从S-3530A读入当前时间数据                                          |
//入口:NONE                                                               |
//出口:接收数据放在年、月、日、星期、时、分、秒各寄存器                   |
//==========================================================================
void GetRealClock(void)
{
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle
	BYTE_NUMBER = 7;									// 2 address bytes.
	COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | READ);		// Chip select + READ
	I2CDataBuff = &RealTime.ClockString[0];				// Data to be writen
	STA = 1;											// Start transfer
	while (SM_BUSY);									// Wait for transfer to finish
}

//============================写状态寄存器程序==============================
//功能:读/写S-3530A状态寄存器,对S-3530A进行设置                          |
//入口:NONE           出口:NONE                                          |
//==========================================================================
unsigned char  GetRealClockStatus(void)
{
	unsigned char result; 
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle
	BYTE_NUMBER = 1;									
	COMMAND = (CLOCK3530_ADDRESS_STATUS | READ);		
	I2CDataBuff = &result;								
	STA = 1;											// Start transfer
	while (SM_BUSY);									// Wait for transfer to finish
	return result;
}
void SetRealClockStatus(unsigned char status)
{
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle
	BYTE_NUMBER = 1;									
	COMMAND = (CLOCK3530_ADDRESS_STATUS | WRITE);		
	I2CDataBuff = &status;								
	STA = 1;											// Start transfer
}


unsigned char revolve(unsigned char val)
{
char i;
unsigned char val1=0;
	for (i=0;i<8;i++)
	{
		if (val&0x1)
			val1++;
		val1=_crol_(val1,1);
		val=_cror_(val,1);
	}
	val1=_cror_(val1,1);
	return val1;
}


//id Delay1ms(unsigned char T);

 void SET_S3530A(CDateTime g_objDateTime ) 
{
  unsigned char  var ;
    P0MDOUT |= 0x1D; 
    P1MDOUT |= 0x01; 
	
	SMB0CN = 0x44;									// Enable SMBus with ACKs on acknowledge cycle
	SMB0CR = -80;									// SMBus clock rate = 100kHz.
	EIE1 |= 2;										// SMBus interrupt enable
	EA = 1;											// Global interrupt enable
	SM_BUSY = 0;										// Free SMBus for first transfer.
	var = GetRealClockStatus();
	ResetRealClock();
	var = GetRealClockStatus();
	SetRealClockStatus(0xc2);
	var = GetRealClockStatus();
    RealTime.RT.Year=g_objDateTime.year;	
	RealTime.RT.Month=g_objDateTime.month;	
	RealTime.RT.Day=g_objDateTime.day;	
//	RealTime.RT.Week=0x00;	
	RealTime.RT.Hour=g_objDateTime.hour;	
	RealTime.RT.Minute=g_objDateTime.minute;	
	RealTime.RT.Second=g_objDateTime.second;	
	SetRealClock();
	}
/*
void TestI2C (void)
{
 char year,month,day,week,hour,minute,second ;


		
		Delay1ms(100);	
		Delay1ms(100);	
		Delay1ms(100);	
		Delay1ms(100);	
		Delay1ms(100);	
		Delay1ms(100);
		Delay1ms(100);	
		Delay1ms(100);	
		Delay1ms(100);		
			
	GetRealClock();

    year=RealTime.RT.Year;	
	month=RealTime.RT.Month;	
	day=RealTime.RT.Day;	
	week=RealTime.RT.Week;	
	hour=RealTime.RT.Hour&0x1f;	
	minute=RealTime.RT.Minute;	
	second=RealTime.RT.Second;	

	
}
*/
 CDateTime GetRealTime(void) 
 {
 CDateTime   Time ;
   GetRealClock();
    Time.year=RealTime.RT.Year;	
	Time.month=RealTime.RT.Month;	
	Time.day=RealTime.RT.Day;	
//	week=RealTime.RT.Week;	
	Time.hour=RealTime.RT.Hour&0x1f;	
	Time.minute=RealTime.RT.Minute;	
	Time.second=RealTime.RT.Second;	
  return Time ;
 }
//------------------------------------------------------------------------------------
// Interrupt Service Routine
//------------------------------------------------------------------------------------
void SMBUS_ISR (void) interrupt 7
{
	switch (SMB0STA)
		{ 	// SMBus 状态码SMB0STA 寄存器
			// 主发送器/接收器起始条件已发送
		case SMB_START:
			SMB0DAT = COMMAND ; // 装入要访问的从器件的地址
			STA = 0; 			// 手动清除START 位
			break;
			//主发送器/接收器重复起始条件已发送
			// 该状态只应在读操作期间出现在存储器地址已发送并得到确认之后 ?
		case SMB_RP_START:
			SMB0DAT = COMMAND; // COMMAND 中应保持从地址 + R.
			STA = 0;
			break;
			// 主发送器从地址 + WRITE 已发送收到ACK
		case SMB_MTADDACK:
			// 主发送器数据字节已发送收到ACK
		case SMB_MTDBACK:
			if (BYTE_NUMBER)
			{
					SMB0DAT = revolve(*I2CDataBuff);					// If R/W=WRITE, load byte to write.
					I2CDataBuff++;
					BYTE_NUMBER--;			
			}
			else
			{
				STO = 1;	SM_BUSY = 0;						// Free SMBus
			}
			break;
			// 主发送器从地址 + WRITE 已发送收到NACK
			// 从器件不应答发送STOP + START 重试
		case SMB_MTADDNACK:
			STO = 1;			STA = 1;
		break;
			// 主发送器数据字节已发送收到NACK
			// 从器件不应答发送STOP + START 重试
		case SMB_MTDBNACK:
			STO = 1;			STA = 1;
		break;
			// 主发送器竞争失败
			// 不应出现如果出现重新开始传输过程
		case SMB_MTARBLOST:
			STO = 1;			STA = 1;
		break;

			// 主接收器从地址 + READ 已发送,收到ACK
		case SMB_MRADDACK:
			AA = 1; // 在应答周期ACK
			if (!BYTE_NUMBER)
			{	
				STO = 1;	SM_BUSY = 0; // 释放SMBus
			}
		break;
			// 主接收器从地址 + READ 已发送收到NACK
			// 从器件不应答发送重复起始条件重试
		case SMB_MRADDNACK:
			STA = 1;
		break;
			// 收到数据字节ACK 已发送
			// 该状态不应出现因为AA 已在前一状态被清0 如果出现发送停止条件
		case SMB_MRDBACK:
			if (BYTE_NUMBER)
			{
				*I2CDataBuff=revolve(SMB0DAT);		
				I2CDataBuff++;
				BYTE_NUMBER--;			
			}
			if (!BYTE_NUMBER)	AA= 0;
		break;
			// 收到数据字节NACK 已发送
			// 读操作已完成读数据寄存器后发送停止条件
		case SMB_MRDBNACK:
			STO = 1;
			SM_BUSY = 0; // 释放SMBus
		break;
			// 在本应用中所有其它状态码没有意义通信复位
		default:
			STO = 1; // 通信复位
			SM_BUSY = 0; 
		break;
		}
	SI=0; // 清除中断标志
}

⌨️ 快捷键说明

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