📄 test.c
字号:
#include "lf2407regs.h"
/*------------------------------------------------------------*/
#define N 32
unsigned int receive[10];
int rev_num=0;
int rev_length=0;
unsigned int send[76];
long signed int v[6]={0,0,0,0,0,0};
int sent_num=0; //SCI已发送数目
int send_num=0; //SCI欲发送数目
unsigned int result1,result2;
int flag2=0;
//int i;
//int j; // ,a=0;
unsigned int period;
unsigned int eeprom[32];
signed int sample_buffer[6][N*2]; //采样缓冲区
signed int ad_offset[6]={0,0,0,0,0,0}; //六个通道的直流偏移量补偿值
ioport signed int port1234;//ADS8364的IO地址(任意)
#define AD_addres port1234
int cmd=0; //命令字
int sample_count=0; //采样周期(N点)计数值
/*************************************************************/
void inline DISABLE()
{
asm(" setc INTM ");
}
void inline ENABLE()
{
asm(" clrc INTM ");
}
/*------------------------------------------------------------*/
void interrupt nothing()
{
return;
}
/*------------------------------------------------------------*/
void inline DELAY(unsigned int time)
{
unsigned a,b;
b=0;
for(a=0;a<=time;a++) b+=1;
}
/*---------------------------------------------------------------------------*/
void work_begin(void)
{
int a;
for(a=0;a<6;a++) v[a]=0;
sample_count=0;
*T1CON=*T1CON | 0x40; // 启动Timer1
}
/*---------------------------------------------------------------------------*/
void work_end(void)
{
*T1CON=*T1CON & 0xFFBF; // 禁止Timer1
}
/*----------------------------SCI程序-------------------------*/
void UARTSENT(int M) //发送服务程序
{
if(sent_num>M-1)
{
sent_num=0;
send_num=0;
work_begin();
return;
} //如果需要发送的字符都已经发送完,则中断直接返回
*SCITXBUF=send[sent_num]; //依次发送定义的字符串中的各个字符
sent_num++;
}
void UARTREC() //接收服务程序
{
//unsigned int SUM,N,L;
receive[rev_num]=*SCIRXBUF; //依次接收字符
rev_num++;
if (receive[0]!=0x68)
{
rev_num=0;
return;
}
if (rev_num==2)
{
rev_length=receive[1];
}
if (rev_num==3)
{
cmd=receive[2];
}
if (rev_num>=rev_length+2)
{
rev_num=0;
rev_length=0;
return;
}
}
/*----------------------------通讯中断服务程序-------------------------*/
interrupt void CAN_SCI()
{
unsigned char ch;
ch=*PIVR; //保存现场中断向量
*EVAIMRA=*EVAIMRA | 0x80; // 允许定时器1的周期中断
ENABLE();
switch(ch)
{
case 6: //如果PIVR=6,则发生了接收中断,执行接收服务程序
{
UARTREC();
*IFR=*IFR | 0x10; //清除IFR中相应的中断标志
break;
}
case 7: //如果PIVR=7,则发生了发送中断,执行发送服务程序
{
UARTSENT(send_num);
*IFR=*IFR | 0x10; //清除IFR中相应的中断标志
break;
}
default: break;
}
ENABLE();
}
/*------------------数据传送程序---------------------------------*/
void power_calculate()
{
int b;
send[0]=0x86;
send[1]=12;
send[2]=(int)((v[0]>>5)&0x00ff);
send[3]=(int)((v[0]>>13)&0x00ff);
send[4]=(int)((v[1]>>5)&0x00ff);
send[5]=(int)((v[1]>>13)&0x00ff);
send[6]=(int)((v[2]>>5)&0x00ff);
send[7]=(int)((v[2]>>13)&0x00ff);
send[8]=(int)((v[3]>>5)&0x00ff);
send[9]=(int)((v[3]>>13)&0x00ff);
send[10]=(int)((v[4]>>5)&0x00ff);
send[11]=(int)((v[4]>>13)&0x00ff);
send[12]=(int)((v[5]>>5)&0x00ff);
send[13]=(int)((v[5]>>13)&0x00ff);
for(b=0;b<6;b++) v[b]=0;
send_num=14;
UARTSENT(send_num);
}
interrupt void ADREAD()
{
unsigned int b;
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
for(b=0;b<=5;b++)
{
v[b]=v[b]+(long)sample_buffer[b][sample_count];
}
sample_count++;
if(sample_count>(N-1))
{
sample_count=0;
cmd=11;
work_end();
}
*EVAIFRA=*EVAIFRA | 0x080;
ENABLE();
}
/*------------------AD中断服务程序---------------------------------*/
interrupt void ADINT()
{
unsigned int b;
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b][sample_count]=AD_addres-ad_offset[b];
/* for(a=0;a<6;a++)
{
b=AD_addres&0x0007;
sample_buffer[b*N+sample_count]=AD_addres-ad_offset[b];
}
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];
b=AD_addres&0x0007;
sample_buffer[b]=AD_addres-ad_offset[b];*/
for(b=0;b<=5;b++)
{
v[b]=v[b]+(long)sample_buffer[b][sample_count];
}
sample_count++;
if(sample_count>(N-1))
{
sample_count=0;
cmd=11;
work_end();
}
*XINT1CR=*XINT1CR | 0x1000;
ENABLE();
}
/*------------------------操作EEPROM程序------------------------------*/
int busy() //查询eeprom状态函数。空闲返回0;忙返回1
{
int iFlag;
int iCounter;
/* *PCDATDIR=0x0302; //使能eeprom*/
*PFDATDIR=*PFDATDIR & 0XFFFB;
*SPIDAT=0x0500; //发命令字,查询eeprom状态
while(((*SPISTS)&0x40)==0); //判断发送是否完成
iCounter=*SPIRXBUF; //读取数据,清标志位
*SPIDAT=0x00; //发命令字,回读eeprom状态
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
*PFDATDIR=*PFDATDIR | 0X0004;
/* *PCDATDIR=0x0303; //禁止eeprom*/
iFlag=*SPIRXBUF; //取eeprom状态,清标志位
iFlag=iFlag&0x0001; //到eeprom状态
return iFlag; //返回eeprom状态值
}
/*------------------------------------------------------------*/
void eep_write(unsigned int start_add,signed int * data,int num)
//eeprom写子程序。start_add为地址;data为写入数据;num为写入个数
{
int iCounter;
int iTemp;
*SPICCR=0x47; //复位SPI,8位数据,上升沿发送
*SPIBRR=0x13; //波特率2MHz
*SPICTL=0x06; //无延时,主模式,允许发送,禁止中断
*SPICCR=0xc7; //脱离复位
while(busy()); //查询eeprom状态
*PCDATDIR=0x0302; //使能eeprom
*SPIDAT=0x0600; //发命令字,打开eeprom写保护
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
*PCDATDIR=0x0303; //禁止eeprom
while(busy()); //查询eeprom状态
*PCDATDIR=0x0302; //使能eeprom
*SPIDAT=0x0200; //发命令字,进行eeprom写操作
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
*SPIDAT=start_add; //发起始地址数值高8位
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
*SPIDAT=start_add<<8; //发起始地址数值低8位
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
for(iCounter=0;iCounter<num;iCounter++) //发送数据
{
*SPIDAT=data[iCounter]<<8;
while(((*SPISTS)&0x40)==0);
iTemp=*SPIRXBUF;
}
*PCDATDIR=0x0303; //禁止eeprom
}
/*------------------------------------------------------------*/
void eep_read(unsigned int start_add,signed int *data, int num)
//eeprom读操作子程序
{
int iCounter;
int iTemp;
*SPICCR=0x47; //复位SPI,8位数据,上升沿发送
*SPICTL=0x06; //无延时,主模式,允许发送,禁止中断
*SPIBRR=0x13; //波特率2MHz
*SPICCR=0xc7; //脱离复位
while(busy()); //查询eeprom状态
*PFDATDIR=*PFDATDIR & 0XFFFB;
/* *PCDATDIR=0x0302; //使能eeprom */
*SPIDAT=0x0300; //发命令字,进行eeprom读操作
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
*SPIDAT=start_add; //发起始地址数值高8位
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
*SPIDAT=start_add<<8; //发起始地址数值低8位
while(((*SPISTS)&0x40)==0); //判断发送是否完成,标志位置1
iTemp=*SPIRXBUF; //读取数据,清标志位
for(iCounter=0;iCounter<=num;iCounter++) //读取数据
{
*SPIDAT=0x0000;
while(((*SPISTS)&0x40)==0);
data[iCounter]=(*SPIRXBUF) & 0xff;
}
*PFDATDIR=*PFDATDIR | 0X0004;
/* *PCDATDIR=0x0303; //禁止eeprom*/
}
/*----------------------计算模拟通道零点偏移量---------------------------------*/
void calculate_offset(void)
{
unsigned int a,b;
long int c;
for(a=0;a<6;a++)
{
c=0;
for(b=0;b<N;b++)
{
c+=(long)sample_buffer[a][b];
}
ad_offset[a]=(int)(c>>5);
}
// eep_write(0,ad_offset,6);
}
/*----------------------------------------------------*/
void send_ok()
{
send[0]=79;
send[1]=75;
send_num=2;
UARTSENT(send_num);
}
/**************************************************************/
void main()
{
int x;
DISABLE();
asm(" setc SXM ");
asm(" clrc OVM ");
asm(" clrc CNF ");
WSGR=0xFE40; //设置IO空间访问插入7个延时
*SCSR1=0x006d; //4倍CLOCK 使能ADC,SPI,CAN,EVA,EVB的时钟
*WDCR=0x00E8; //禁止看门狗
*MCRA=0x1017; //配置端口
*MCRB=0xFE3C;
*MCRC=0x0c00;
*PADATDIR=0xE000;
*PBDATDIR=0xFFff;
*PCDATDIR=0x0303;
*PEDATDIR=0x8080;
*PFDATDIR=0x3F0F;
*XINT1CR=0x8005; //上升沿中断
/*----------------------SCI初始化-----------------------*/
*SCICCR=0x07; //1个停止位,不校验,空闲线多处理器模式,8位字符
*SCICTL1=0x13; //使能接收和发送,SLEEP=0,禁止休眠方式
//禁止接收错误中断,TXWAKE=0,即没有选定的发送特征
*SCICTL2=0x03; //使能接收和发送中断
*SCIHBAUD=0x02;
*SCILBAUD=0x08; //波特率=9600B/S
*SCIPRI=0x60; //SCI中断(接收和发送中断)为低优先级中断
*SCICTL1=*SCICTL1 | 0x20; //使SCI脱离复位状态
/*----------------------TIMER1初始化----------------------- */
*T1CON=0x1006; // Timer1为连续增计数模式,预分频值为1,
//使用内部时钟,计数值为0或等于周期值重载,使能比较
*GPTCONA=*GPTCONA|0x42;
*T1PR=0x61a6; // Timer1的周期寄存器的值根据312.5us延时和预分频值确定
*T1CMP=0x3000; // Timer1的比较寄存器的值
*T1CNT=0x00; // Timer1的计数器清零
*EVAIFRA=*EVAIFRA | 0x80; // 清除定时器1周期中断标志
*EVAIMRA=*EVAIMRA | 0x80; // 允许定时器1的周期中断
*T1CON=*T1CON | 0x40; // 启动Timer1
/*----------------------TIMER1初始化-----------------------
*T3CON=0x1006; // Timer1为连续增计数模式,预分频值为1,
//使用内部时钟,计数值为0或等于周期值重载,使能比较
*GPTCONB=*GPTCONB|0x42;
*T3PER=0x61a6; // Timer1的周期寄存器的值根据312.5us延时和预分频值确定
*T3CMP=0x3000; // Timer1的比较寄存器的值
*T3CNT=0x00; // Timer1的计数器清零
*EVAIFRB=*EVAIFRB | 0x80; // 清除定时器1周期中断标志
// *EVAIMRB=*EVAIMRB | 0x80; // 允许定时器1的周期中断
*T3CON=*T3CON | 0x40; // 启动Timer1 */
/*----------------------ADS8364复位清零-------------------*/
*PCDATDIR=*PCDATDIR & 0xfffd;
*PCDATDIR=*PCDATDIR | 0x2;
/*-------------------------------------------------------*/
// eep_read(0,ad_offset,6);
/*-------------------------------------------------------*/
*IFR=0xFFFF; // 清除中断标志
*IMR=0x0013; // 允许INT1(xint1),5(COM)中断
ENABLE();
/*-------------------------------------------------------*/
for(;;)
{
switch(cmd)
{
case 1: cmd=0;work_end();break;
case 2: cmd=0;work_begin();break;
case 3: cmd=0;calculate_offset();break;
case 4: cmd=0;break; //接收脉冲常数
// case 5: cmd=0;active_power=0;break; //输出有功电量脉冲
// case 6: cmd=0;active_power=1;break; //输出无功电量脉冲
// case 7: cmd=0;*T1PR=period>>2;break;
// case 10: cmd=0;power_calculate();break; //修改电能脉冲频率
case 11: cmd=0;power_calculate();break; //计算传送实时值
case 12: cmd=0;send_ok();break; //用于测试
// case 13: cmd=0;send_cap();break;//传送捕捉值,用于测试
default:break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -