📄 sysfun.c
字号:
/**
Title: SysFun_C
Author: Atai
Date: 2007.12.18
v1
*/
/*
080103 修正数码管显示地位溢出问题
*/
/*
080107 电压采样平均
*/
#include"LF2407REGS.H"
#include"SysFun.h"
#include "IoDef.h"
/*========================PARAMETERS==============================================*/
extern Uint CLOCKWISE;
extern Uint Motor;
extern Uint ENA;
extern Uint DIR;
extern Uint CurrentState;
#define nFilter 32
#define nKeyDelay 31 //153为1s
unsigned int NMAX=0xfff0;//指定最大间隔时间,防止溢出
unsigned int nIntervalTime=0;//保存当前间隔时间;
unsigned int nKeyAutoMan=0;//自动、手动
unsigned int nKeyRunPause=0;//启动、停止调整参数
unsigned int nKeyIncrease=0;//增加
unsigned int nKeyDecrease=0;//减少
unsigned int nKeyStop=0; //急停
unsigned int nADCResult0=0;//记录AD转换结果;采样电压值为:0~1023
Uint nADCResult1 =0; //记录AD转换结果
float fADAdjust;
float fADCInVoltage;
float fSetVelocity;
unsigned int nADCfilter[nFilter];
Uint flagDelay=0;
Uint flagKeyDelay=0;
Uint flagfirsttime=0;
unsigned int nIntervalSecond=0;//保存当前间隔时间 s;
unsigned int nDeciSecond=0; //显示小数点后一位 0.1s
/*===================功能(中断)模块初始化=======================================*/
/**
系统初始化配置
*/
void SysInitial()
{ asm(" setc INTM");//禁止所有中断
asm(" clrc SXM");//抑制符号位扩展
asm(" clrc OVM");//累加器中结果正常溢出
asm(" clrc CNF");//b0被配置为数据空间
*SCSR1=0x81FE;//CLKIN=10M,CPU=40M
*WDCR=0x00EB;//不使能看门狗
*IFR=0xFFFF;//清除所有中断标志位
}
/**
AD 转换初始化
AD转化包括旋钮、电压采样两路,分别连接ADCIN00, ADCIN01
最大转换通道是1
Timer 4 控制
*/
void AdcInitial()//ADC采样寄存器初始化
{
int i;
*ADCTRL1=*ADCTRL1|0x4000;//复位ADC模块
asm( " nop");
*ADCTRL1=0x0030;//使用级联模式 ,低优先级
*ADCTRL2=0x8404;//级联模式下利用evb启动ADC,中断标志置位后马上申请中断
*MAXCONV=0x0002;//page 375 最大转换通道是3
*ADCTRL2=*ADCTRL2|0x4200;//page 367 复位seq,指针指向conv00,intflag 写1清零
*CHSELSEQ1=0x3210; //page 377 ADC input Channel Select Sequenceing control Registers
//===========利用定时器4启动ADC=============
*T4CON=0x120C;//连续增计数模式,4分频:40M/4-->(100ns),定时器没有启动
// *T4PER=0x8000;
// *T4PER=0xFFFF;
*T4PER=0x2000; //0x800000/0x2000=0x400=1024次
*GPTCONB=0x400;//周期启动ADC
*EVBIFRB=0xFFFF;//写1复位
*T4CNT=0x0000;//计数器清零
*IMR=*IMR|0x0020;
*IFR=0xFFFF;//清除所有中断标志位
for(i=0;i<nFilter;i++)//滤波
{
nADCfilter[i]=0;
}
}
/**
捕获单元初始化
Timer 1 控制
*/
/*=======================================================
void CapInitial()
{
//20080103 K1改成上升沿和下降沿检测 K1,IOPA3
*MCRA=*MCRA | 0x0038;//IOPA3,4,5为CAP功能的CAP1,2,3
*T1CON=0x170C;//连续增模式,没有使能定时器,128分频,禁止比较
*T1PER=0xFFFF;//对应128/40M=0.000 003 2 S;
*T1CNT=0x0000;
// *CAPCONA=0xBE55;// page 314 三个捕获单元使能,选择定时器1,检测上升沿
*CAPCONA=0xBED5;// page 314 三个捕获单元使能,选择定时器1,检测上升沿 CAP1检测双边080103
*CAPFIFOA=0x0000;//初始化FIFO为空
*IMR=*IMR | 0x0008;//允许CAP中断
*IFR=0xFFFF;//清除所有中断标志位
*EVAIMRC=0xFFFF;//允许cap1,2,3中断
*EVAIFRC=0xFFFF;//复位标志位
}
=======================================================*/
/*//////////////////////////////////////////////////////////////////////////////////////
2、电机控制接口,初始化IO以及PWM设置
电机 ENA1 DIR1 PWM1 ENA2 DIR2 PWM2
DSP IO IOPE5 IOPE4 IOPA6 IOPE7 IOPE6 IOPA7
PWM输出初始化
仅使能PWM1
高位有效
Timer 3 控制
page
284
*//////////////////////////////////////////////////////////////////////////////////////
void MotorInitial()
{
// *MCRC=*MCRC|0x007E;//IOPE1-6对应 PWM7-12
// *MCRC=*MCRC|0x0060;//IOPE5,6对应 PWM11-12 0110 //IOPE1-4 基本IO
//PWM //io now
_MCRC.bit4 =1; //IOPE4 PWM11
_MCRA.bit6=0; //IOPA6 PWM
_MCRA.bit7 = 0; //IOPA7 PWM
_PADATDIR.bit14 = 1; //输出
_PADATDIR.bit15 = 1;
//ENA
_MCRC.bit5 =0; //
_MCRC.bit7 = 0; //
_PEDATDIR.bit13 = 1; //
_PEDATDIR.bit15 = 1;
//DIR iope4/dir1/pwm10 pwm
_MCRC.bit6 = 0; //
_PEDATDIR.bit14 = 1;
//定义为0
ENA1=0;
ENA2=0;
DIR1=0;
DIR2=0;
PWM1=0;
PWM2=0;
//定时器3
*ACTRB=0x0555;//PWM低有效
*DBTCONB=0x00; //PWM on underflow mode
*T3PER=0x666; //400Hz =40M/0x1999=40M/4/0x666 寄存器16位,最多FFFF=65535
*CMPR6=0x333;
//28倍, 10Hz 对应0x666*400/10=0xFFF0;
*COMCONB=0x8200;//使能比较操作 enable FCOMPOE, PWM output enabled
*T3CON=0x1200;//连续增 计数模式//时钟预标定系数位110 X/4
}
/*
void MotorInitial()
{
// *MCRC=*MCRC|0x007E;//IOPE1-6对应 PWM7-12
// *MCRC=*MCRC|0x0060;//IOPE5,6对应 PWM11-12 0110 //IOPE1-4 基本IO
//PWM
_MCRA.bit6=1; //IOPA6 PWM
_MCRA.bit7 = 1; //IOPA7 PWM
_PADATDIR.bit14 = 1; //输出
_PADATDIR.bit15 = 1;
//ENA
_MCRC.bit5 =0; //
_MCRC.bit7 = 0; //
_PEDATDIR.bit13 = 1; //
_PEDATDIR.bit15 = 1;
//DIR
_MCRC.bit4 =0; //
_MCRC.bit6 = 0; //
_PEDATDIR.bit12 = 1; //输出
_PEDATDIR.bit14 = 1;
//定义为0
ENA1=0;
ENA2=0;
DIR1=0;
DIR2=0;
PWM1=0;
PWM2=0;
//定时器1
*ACTRA=0x0555;//PWM低有效
*DBTCONB=0x00; //PWM on underflow mode 无死区
*T1PER=0x0000;
*CMPR3 = *T1PER/2;
//*COMCONB=0x8200;//使能比较操作 enable FCOMPOE, PWM output enabled
*COMCONA=0x8200;//使能比较操作 enable FCOMPOE, PWM output enabled
*T1CON=0x1000;//连续增 计数模式 T2 useful
}
*/
/*===================================================================
若使用PWM1, 则需用Timer 1
void PWMInitial(){
*MCRA=*MCRA|0x0040;//IOPA6, PWM1;
*ACTRA=0x0002;//page288 PWM Pin 1 高有效
*DBTCONA = 0x00;//page 292 Disable all Dead-band timer period
*COMCONA = 0x8200; //page 284 PWM enable, Action control Register Reload Condition : immediately
/*-----------------------------------------------------------
*MCRC=*MCRC|0x007E;//IOPE1-6 PWM7-12
*DBTCONB=0x00; //page 292PWM on underflow mode
*T3PER=5000;
*COMCONB=0x8200;//使能比较操作 enable FCOMPOE, PWM output enabled
*T3CON=0x1000;//连续增 计数模式 T2 useful
-----------------------------------------------------------
}
/*=======================================================================*/
/**
内置计时器初始化
Timer 2
*/
void Timer2Initial()
{ *T2CON=0x120C;//时钟预定标系数2
*T2CNT=0;
*T2PER=0xFFFF;
*IMR|=0x0004;
*EVAIMRB|=0x0008;//使能timer2上溢中断
}
/*=====================GENERAL FUNCTION==========================*/
/**
延时n毫秒
*/
void DelayMs(unsigned int ms)
{
int N=0;
int i;
while(ms>0)
{
ms--;
for(i=N;i>0;i--)
DelayUs(1000);
}
}
/*********************************************延时**************************************/
//通过2407延时1us, 40M Hz 40*1000/40M=1us 0xA000
void DelayUs(Ulong t)
{
int i,j;
for (i=0;i<t;i++)
for(j=0xA000;j>0;j--)
asm( "nop");
}
//通过定时器延时1/10秒
void delayDecis(int deciS)//初始化时,定时中断位开启
{ //开始定时
if( flagDelay==0)
{
nIntervalTime=0;
flagDelay=1;
}
while(1)
{
if(nIntervalTime>=153)
{
nIntervalTime=0;
nIntervalSecond++;
}
nDeciSecond=nIntervalTime/15;
if(nDeciSecond>9)
{nDeciSecond=9;}
if((nIntervalSecond*10+nDeciSecond)>=deciS)
{
flagDelay=0;
nIntervalSecond=0;
return;
}
}
}
/*======================中断响应===================================*/
/**
无处理中断
*/
void interrupt nothing()
{ asm(" clrc INTM");}
/**
按键捕捉中断
改变nKeyPressed值,表示某个按键按下;
*/
void interrupt CapInt()
{
/* unsigned int temp;
static int tempn=0;
// asm(" clrc INTM");
if(0x0001==(*EVAIFRC&0x0001))//捕获单元1
{ temp=*CAP1FIFO;//必须读捕获值
*EVAIFRC |=0x0001;//清除中断标志
if(tempn<1)
{nKeyPressed=1; tempn=1;}
else
{nKeyReleased=1; tempn=0;}
}//cap1
if(0x0002==(*EVAIFRC&0x0002)) //捕获单元2
{ temp=*CAP2FIFO;
*EVAIFRC |=0x0002;
nKeyPressed=2;
}//cap2
if(0x0004==(*EVAIFRC&0x0004)) //捕获单元3
{ temp=*CAP3FIFO;
*EVAIFRC |=0x0004;
nKeyPressed=3;
}//cap3
// *IFR=0xFFFF;//清除所有中断标志位
//*IFR=*IFR | 0x0008;//清int4中断标志
// *T1CNT=0x0000;
asm(" clrc INTM");
*/
}
/*//////////////////////////////////////////////////////////////////////////////////////
1、手控面板接口
引脚 nKeyAutoMan(K1) nKeyRunPause(K2) nKeyIncrease(K3) nKeyDecrease(K4) nKeyStop
DSP IO IOPF5 IOPF4 IOPB6 IOPC1 IOPB4 IOPB5
*/////////////////////////////////////////////////////////////////////////////////////////////////////
void KeyInitial()
{
// _MCRC.bit11=0; //按键A 选择键
// _PFDATDIR.bit11=0;//输入
_MCRC.bit13 =0;
_PFDATDIR.bit13 =0;
_MCRC.bit12 =0;
_PFDATDIR.bit12 =0;
_MCRA.bit14 =0;
_PBDATDIR.bit14 =0;
_MCRB.bit1 =0;
_PCDATDIR .bit9 =0;
_MCRA.bit12 =0;
_PBDATDIR.bit12 =0;
_MCRA.bit13 =0;
_PBDATDIR.bit13 =0;
}
/**
通用计时器中断响应
Timer 2
Timer 2 溢出中断
*/
//循环扫描IOPA3,4,
void interrupt Timer2Int()//对应到文件“VECTORS.ASM”的定时器中断:_Timer2Int
{
if(0x002E ==(*PIVR))
{ *T2CNT=0x0000;
nIntervalTime++;
if(nIntervalTime>=NMAX)
{
nIntervalTime=0;
}
}
if((flagKeyDelay==1)&&(flagfirsttime==0))
{
nIntervalTime=0;
flagfirsttime=1;
}
if(nIntervalTime>nKeyDelay)
{flagKeyDelay=0;flagfirsttime=0;}
/*
扫描按键
*/
/*#define KeyAutoMan _PFDATDIR.bit5
#define KeyRunPause _PFDATDIR.bit4
#define KeyIncrease _PBDATDIR.bit6
#define KeyDecrease _PBDATDIR.bit4
#define KeyStop _PBDATDIR.bit5
*/
// if(0x0008==(*PADATDIR&0x0008))
//拨动开关,不须锁定
nKeyAutoMan=KeyAutoMan;
nKeyRunPause=KeyRunPause;
nKeyIncrease=KeyIncrease;
nKeyDecrease=KeyDecrease;
//参数调整阶段时,0-10.0,每秒钟增加5. delay 0.1 后继续检查
//手动模式下,只是确定方向和运动
// if(CurrentState==CONFIG)
{
}
//手动模式下,只是确定方向和运动
/* if(CurrentState==MANUAL)
{
if(KeyIncrease||KeyDecrease)
{
ENA=1;
if(Motor==0)
ENA1=1;
if(Motor==1)
ENA2=1;
}
if(KeyIncrease==1)
{
if(CLOCKWISE==0)
DIR=0;
else
DIR=1;
}
if(KeyDecrease==1)
{
if(CLOCKWISE==0)
DIR=1;
else
DIR=0;
}
if(Motor==0)
DIR1=DIR;
if(Motor==1)
DIR2=DIR;
}
*/
nKeyStop = KeyStop;
*EVAIFRB|=0xFFFF;//清除事件管理器中断标志位
asm(" clrc INTM");//清除总中断标志位
}
void interrupt AdcInt()//对应到文件"VECTORS.ASM"的ADC转换中断:_AdcInt
{
int i=0;
static unsigned int sum=0;
static unsigned int nFilterIndex=0;
asm(" clrc SXM");//抑制符号扩展,从而移位时候最高位填写0
while(1)
{ if(!(*ADCTRL2 & 0x1000)) break;}
nADCResult0 =(*RESULT0)>>6;//右移6位
nADCResult1 = (*RESULT2)>>6;//右移6位
// nADCResult3 = (*RESULT3)>>6;
// nADCResult0=nADCResult3;
*ADCTRL2=*ADCTRL2|0x4200;//复位seq,指针指向conv00,intflag 写1清零
*EVBIFRB=0xFFFF;//写1复位
fADAdjust=((float)nADCResult0/1024*30);
nADCfilter[nFilterIndex]=nADCResult1; //10bit
sum+=nADCfilter[nFilterIndex]; //16bit
if(nFilterIndex==(nFilter-1)) //32=5bit
{sum-=nADCfilter[0];}
else
{sum-=nADCfilter[nFilterIndex+1];}
nFilterIndex=(++nFilterIndex)%nFilter;
fADCInVoltage=((float)sum/nFilter*30/1024);// 归一到0-30.0
START_ADC;
asm(" clrc INTM");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -