📄 nsa_timer_drv.c
字号:
/////////////////////////////////////////////////////////////////////////////
//
// 文件名: 版本
//
// 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 *)>Op_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 + -