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

📄 nsa_timer_drv.c

📁 ds1306和bs5460的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
//  文件名:							版本
//                                                            
//  timer.c							0.02
//        
//  概述:
//		本模块提供与时钟芯片DS1306及CS5460有关的读写函数,及相应的时钟数据
//
/////////////////////////////////////////////////////////////////////////////

#include "timer.h"
#include "hardef.h"



#undef TEST_TIME
#undef TEST_CS5460ABS

static struct t_time time;

volatile TDATE g_tDate;

static bool CompareDate(volatile const TDATE *ptDate,const struct  t_time *ptTime)
{
	if(ptDate->wYear != ptTime->year)   return false;
	if(ptDate->byMon != ptTime->month)  return false;
	if(ptDate->byDay != ptTime->date)   return false;
	if(ptDate->byHour!= ptTime->hour)   return false;
	if(ptDate->byMin != ptTime->minute) return false;
	if(ptDate->wMs   != ptTime->msec)   return false;

	return true;
}

//从DS1306读一字节
char read_DS1306(const char reg)
{
	register char temp;
	register unsigned short data,status;
	
	data=reg;
	data<<=8;
	*QSM_SPICC=0x5f;// 片选寄存器设置 CPU的PCS3直接接到DS1306的CE腿,没有经过38译码器 zaken
	*QSM_SPITD=data;	//control register
	
	QSM_SPCR0=0x8105;	//  bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送16位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=1.0Mbps
						
	QSM_SPCR3=0x00;     //	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
						
	QSM_SPCR2=0x0000;   //	ENDQP=0,NEWQP=0
	
	QSM_SPCR1=0xb004;	//	bit15:SPE,QSPI允许/禁止
						//	bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us
	
	while(!(QSM_SPSR & 0x80));
	
	for(status =0; status < 250; status++);
	
	QSM_SPSR=0;
	temp=(char)*(QSM_SPIRD+0);
	return temp;
}

//向DS1306写一字节
void TM_Write_DS1306(const char reg, const unsigned char control)
{
	register unsigned short data,status;

	data=reg;				//reg:address of register
	data<<=8;				//control:content of register
	data|=control;
	*QSM_SPICC=0x5f;      
	*QSM_SPITD=data;	//control register
  
	QSM_SPCR0=0x8105;	//	bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送16位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=1.0Mbps
	QSM_SPCR3=0x00;     //	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
	QSM_SPCR2=0x0000;   //	ENDQP=0,NEWQP=0
	QSM_SPCR1=0xb004;	//	bit15:SPE,QSPI允许/禁止
						//	bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us

	while(!(QSM_SPSR&0x80));
  
	for(status=0;status<250;status++);

	QSM_SPSR=0;
}

void TM_Read_Timer(void)//读DS1306时钟芯片的时间函数
{
	register unsigned char temp;
	register unsigned short temp2,status;
	register unsigned char i;
	
	for (i =0; i <= 7; i++)
	{
		*(QSM_SPICC+i)=0x9f;//yy/mm/dd/ww/hh/mm/ss
		*(QSM_SPITD+i)=0;	//the first byte is address byte
	}	

	QSM_SPCR0=0x8105;	//  bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送16位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=1.0Mbps
						
	QSM_SPCR3=0x00;     //	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
						
	QSM_SPCR2=0x0700;   //	ENDQP=7,NEWQP=0
	
	QSM_SPCR1=0xb004;	//	bit15:SPE,QSPI允许/禁止
						//  bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us
	
	while(!(QSM_SPSR & 0x80));
	
	for(status =0; status < 250; status++);
	
	QSM_SPSR=0;
	
	temp2=(short)*(QSM_SPIRD+7);
	temp=(unsigned char)BcdHex((WORD)temp2);
	if(temp > 90)
		time.year=temp+1900;							//year
	else
		time.year=temp+2000;
	temp=(char)*(QSM_SPIRD+6);
	time.month=(unsigned char)BcdHex((WORD)temp);		//month
	if(time.month>12) time.month=0;
	
	temp=(char)*(QSM_SPIRD+5);
	time.date=(unsigned char)BcdHex((WORD)temp);		//date
	if(time.date>32) time.date=0;
	
	temp=(char)*(QSM_SPIRD+3);
	time.hour=(unsigned char)BcdHex((WORD)temp);		//hour
	if(time.hour>24) time.hour=0;
	
	temp=(char)*(QSM_SPIRD+2);
	time.minute=(unsigned char)BcdHex((WORD)temp);		//minute
	if(time.minute>60) time.minute=0;
	
	temp=(char)*(QSM_SPIRD+1);
	time.second=(unsigned char)BcdHex((WORD)temp);		//second
	if(time.second > 60) time.second=0;
	time.msec=time.second*1000;							//msecond=1000*second

	//copy t_time time to TDATE g_tDate
CopyTimeToDate:
	g_tDate.wYear=time.year;
	g_tDate.byMon=time.month;
	g_tDate.byDay=time.date;
	g_tDate.byHour=time.hour;
	g_tDate.byMin=time.minute;
	g_tDate.wMs=time.msec;
	if(!CompareDate(&g_tDate,&time)) goto CopyTimeToDate;
  
}

void TM_Write_Timer(const TDATE *ptDate)//写DS1306时钟芯片的时间函数
{
	register unsigned short data,status;
	unsigned short temp;

	//copy TDATE tDate to t_time time
CopyDateToTime:
	time.year=ptDate->wYear;
	time.month=ptDate->byMon;
	time.date=ptDate->byDay;
	time.hour=ptDate->byHour;
	time.minute=ptDate->byMin;
	time.msec=ptDate->wMs;
	if(!CompareDate(ptDate,&time)) goto CopyDateToTime;
	//deal with msec
	time.second=time.msec/1000;
	temp=time.msec%1000;
	if((temp>=500)&&(time.second<59)) time.second++;

	TM_Write_DS1306((char)0x8f,0);		//disable write protect
	
	*(QSM_SPICC+0)=0x9f;      //address byte for burst transfer
	*(QSM_SPITD+0)=0x80;	  //address increase automatically
	
	*(QSM_SPICC+1)=0x9f;      //sec
	data=HexBcd(time.second);
	*(QSM_SPITD+1)=data;
	
	*(QSM_SPICC+2)=0x9f;      //min
	data=HexBcd(time.minute);
	*(QSM_SPITD+2)=data;
	
	*(QSM_SPICC+3)=0x9f;      //hour
	data=HexBcd(time.hour);
	*(QSM_SPITD+3)=data;
	
	*(QSM_SPICC+4)=0x9f;      //day of the week
	data=HexBcd(time.date);
	*(QSM_SPITD+4)=data;
	
	*(QSM_SPICC+5)=0x9f;      //date
	data=HexBcd(time.date);
	*(QSM_SPITD+5)=data;
	
	*(QSM_SPICC+6)=0x9f;      //month
	data=HexBcd(time.month);
	*(QSM_SPITD+6)=data;
	
	*(QSM_SPICC+7)=0x1f;      //year
	data=HexBcd((unsigned short)(time.year%100));
	*(QSM_SPITD+7)=data;
	
	
	QSM_SPCR0=0x8105;	//  bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送16位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=1.0Mbps
						
	QSM_SPCR3=0x00;     //	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
						
	QSM_SPCR2=0x0700;   //	ENDQP=7,NEWQP=0
	
	QSM_SPCR1=0xb004;	//	bit15:SPE,QSPI允许/禁止
						//	bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us
	
	while(!(QSM_SPSR & 0x80));
	
	for(status =0; status < 250; status++);
	
	QSM_SPSR=0;
	
	TM_Write_DS1306((char)0x8f,0x40);	//enable write protect

}

void TM_Read_DS_Array(char Offset,unsigned char Size,unsigned char *pTo)//读DS1306的用户RAM(96 BYTE) zaken
{
	char Addr;
	unsigned char i;
	Addr=0x20+Offset;
	for(i =0; i < Size; i++)
	{
		*pTo++=read_DS1306(Addr++);
	}
}

void TM_Write_DS_Array(char Offset,unsigned char Size,unsigned char *pFrom)
{
	char Addr;
	unsigned char i;
	Addr=0xA0+Offset;

	TM_Write_DS1306((char)0x8f,0);		//disable write protect

	for(i =0; i < Size; i++)
	{
		TM_Write_DS1306(Addr++,*pFrom++);//写DS1306用户RAM  96(BYTE)偏移基地址 0xA0
	}
	TM_Write_DS1306((char)0x8f,0x40);	//enable write protect
}

void TM_Read_CS5460(unsigned char Command,unsigned char which_cs,unsigned long *pDword)
{
	register unsigned short status;
	register unsigned char spicc;
	register unsigned char i;
    register unsigned char *pChar=(unsigned char *)pDword;

	if(which_cs>2) return;
    spicc=0x80|(which_cs+1);	// PES0,PES1,PES2 组成38译码器的输入,选通不同的5460  zake 片选0,1,2转换成硬件地址  

	for (i=0;i<=7;i++)
	{
		*(QSM_SPICC+i)=spicc;
		*(QSM_SPITD+i)=0xffff;
	}

	*(QSM_SPITD+3)=0xfffe;		//开始4字节为SPI串行口同步序列命令
	*(QSM_SPITD+4)=Command;
	*pChar=0;

	QSM_SPCR0=0xA30A;   //  bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送8位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=2.0Mbps
	QSM_SPCR3=0x00;     //	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
	QSM_SPCR2=0x0700;   //  ENDQP=7,NEWQP=0
	QSM_SPCR1=0x8104;	//	bit15:SPE,QSPI允许/禁止
						//	bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us

//#if ONLINE
	while(!(QSM_SPSR&0x80));
//#endif

  	for(status=0;status<5;status++);

	QSM_SPSR=0;

	for(i=1;i<=3;i++)
		*(pChar+i)=(unsigned char)*(QSM_SPIRD+4+i);

}

void TM_Write_CS5460(unsigned char Command,unsigned char which_cs,unsigned long *pDword)
{
	register unsigned short status;
	register unsigned char spicc;
	register unsigned char i;
    register unsigned char *pChar=(unsigned char *)pDword;

	if(which_cs>2) return;
    spicc=0x80|(which_cs+1);		//片选0,1,2转换成硬件地址

    for(i=0;i<=4;i++)               //24bits
	{
		*(QSM_SPICC+i)=spicc;
        *(QSM_SPITD+i)=0xffff;
	}
    *(QSM_SPITD+3)=0xfffe;			//开始4字节为SPI串行口同步序列命令

    *(QSM_SPITD+4)=(unsigned char)Command;	//命令字

    if((Command&0x80) && (Command!=0xff))
	{	
		//单字节命令
		//非 同步或寄存器存取 命令,如转换.校验命令等
        *(QSM_SPITD+5)=0xffff;	// nop
        *(QSM_SPITD+6)=0xffff;
        *(QSM_SPITD+7)=0xffff;
    }
	else
	{
		for(i=1;i<=3;i++)		//附加24bits
		{
			*(QSM_SPICC+4+i)=spicc;
			*(QSM_SPITD+4+i)=*(pChar+i);
		}
	}


    QSM_SPCR0=0xA30A;   //  bit15:MSTR,设置QSPI为主机/从机
						//	bit14:WOMQ,线或允许/禁止
						//	bit13-10:BITS,每次传送8位
						//	bit9:CPOL,SCK无效状态高/低
						//	bit8:CPHA,时钟相位
						//	bit7-0:BAUD=2.0Mbps
	QSM_SPCR3=0x00;		//	bit15-11:0,保留
						//	bit10:LOOPQ,反馈路径允许/禁止
						//	bit9:HMIE,HALTA和MODF中断允许/禁止
						//	bit8:HALT,暂停允许/禁止
    QSM_SPCR2=0x0700;   //  ENDQP=0,NEWQP=0
	QSM_SPCR1=0x8104;	//	bit15:SPE,QSPI允许/禁止
						//	bit14-8:DSCKL,SCK之前延时2.4us,
						//	bit7-0:DTL,传输间隔6.4us

	while(!(QSM_SPSR&0x80));
  
	for(status=0;status<5;status++);

	QSM_SPSR=0;
}

//================================================================================
//	CS5460A_BS操作:
//================================================================================
//CS5460寄存器定义
//Register Read/Write Command
#define	READ_COM	0x00
#define WRITE_COM	0x40
#define CONFIG_REG	0x00
#define IOFF_REG	0x02
#define IGN_REG		0x04
#define VOFF_REG	0x06
#define VGN_REG		0x08
#define CYCLE_REG	0x0A
#define PLUSE_REG	0x0C
#define I_REG		0x0E
#define V_REG		0x10
#define P_REG		0x12
#define E_REG		0x14
#define IRMS_REG	0x16
#define VRMS_REG	0x18
#define TBC_REG		0x1A
#define POFF_REG	0x1C
#define STATUS_REG	0x1E
#define IACOFF_REG	0x20
#define VACOFF_REG	0x22
#define MASK_REG	0x36
#define CTRL_REG	0x38
//Command Word(Write Only)
#define CONVERT		0xE8
#define SYNC0		0xFE
#define SYNC1		0xFF
#define CALIBRATE	0xC0
#define CHANNEL_I	0x08
#define CHANNEL_V	0x10
#define CHANNEL_I_V	0x18
#define R_AC		0x04
#define GAIN_CALIB	0x02
#define OFF_CALIB	0x01
/////////////////////////////////////////
//
/////////////////////////////////////////
ENERGY_REG Energy_Reg[3];
static DWORD dTCOUNT0=0;
static DWORD dTCOUNT1=0xffffffff;
OPRATE_5460_FLAG gtOp_5460_Flag;
//////////////////////////////////////////
//functions()
//////////////////////////////////////////
void Command_Convert();

//下载CS5460配置
void Download_Config()
{
	DWORD dWord;
	BYTE i;
	
	gtOp_5460_Flag.bNeed_Download_Config=false;
	for( i=0; i<CS_ALL; i++ )
	{
		if( CrcOk( (BYTE *)&Energy_Reg[i].Conf, sizeof(CONFIG_5460)-2 ) )	//Waaa 0916
		{	//CRC校验正确
			//采用默认的采样率,不设置 zaken
			TM_Write_CS5460( WRITE_COM|CONFIG_REG,	i, &Energy_Reg[i].Conf.Config );//配置寄存器   zaken
			TM_Write_CS5460( WRITE_COM|IOFF_REG,	i, &Energy_Reg[i].Conf.Ioff );//电流直流分量偏移寄存器 zaken
			TM_Write_CS5460( WRITE_COM|IGN_REG,		i, &Energy_Reg[i].Conf.Ign );//
			TM_Write_CS5460( WRITE_COM|VOFF_REG,	i, &Energy_Reg[i].Conf.Voff );//电压偏移寄存器  zaken
			TM_Write_CS5460( WRITE_COM|VGN_REG,		i, &Energy_Reg[i].Conf.Vgn );
			TM_Write_CS5460( WRITE_COM|IACOFF_REG,	i, &Energy_Reg[i].Conf.Iacoff );
			TM_Write_CS5460( WRITE_COM|VACOFF_REG,	i, &Energy_Reg[i].Conf.Vacoff );
			TM_Write_CS5460( WRITE_COM|POFF_REG,	i, &Energy_Reg[i].Conf.Poff );
			Energy_Reg[i].bUsed=true;
		
		}
		else
		{	//CRC校验错误
			dWord=0x80;//复位5460 zaken
			TM_Write_CS5460( WRITE_COM|CONFIG_REG, i, &dWord);
			//Wait for 10 XIN cycles
			for ( dWord =0; dWord<0x100; dWord++);
	
			Energy_Reg[i].bUsed=false;
			TM_Read_CS5460( CONFIG_REG, i, &Energy_Reg[i].Conf.Config );
			TM_Read_CS5460( IOFF_REG,	i, &Energy_Reg[i].Conf.Ioff );
			TM_Read_CS5460( IGN_REG,	i, &Energy_Reg[i].Conf.Ign );
			TM_Read_CS5460( VOFF_REG,	i, &Energy_Reg[i].Conf.Voff );
			TM_Read_CS5460( VGN_REG,	i, &Energy_Reg[i].Conf.Vgn );
			TM_Read_CS5460( IACOFF_REG,	i, &Energy_Reg[i].Conf.Iacoff );
			TM_Read_CS5460( VACOFF_REG, i, &Energy_Reg[i].Conf.Vacoff );
			TM_Read_CS5460( POFF_REG,	i, &Energy_Reg[i].Conf.Poff );
		}
	}
	Command_Convert();
}
//上电初始化CS5460
#ifdef TEST_CS5460ABS
void InitDegreeCalibrateBuffer();
#endif

void TM_Initinize_CS5460()
{
	unsigned char i;
	BYTE * pb=(BYTE *)&gtOp_5460_Flag;
	for( i=0; i<sizeof(OPRATE_5460_FLAG); i++ )
	{
		*pb++=0;
	}
#ifdef TEST_CS5460ABS
	InitDegreeCalibrateBuffer();
#endif
	//获取CS5460配置信息(初始化)
	if( !Read_Eng_Conf() )
	{//置CS5460初始化设置错报告标志

	}
	TM_Read_DS_Array( (char)(ENERGY_OFFSET), sizeof(DIAN_LIANG) , (BYTE *)&tDian_Liang );

	Download_Config();
}

//DC偏置校验

⌨️ 快捷键说明

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