📄 speed_detect.c
字号:
/******************************************************************************
**程序名称:CAP_test
**程序功能:捕获单元cap1~cap4测试,测试捕获方波相邻双沿的时间值
**创建人员:songhaibin
**创建日期:2008.12.2
**测试说明:该程序用于测试DSP的CAPTURE模块,测试捕获方波相邻双沿的值
*******************************************************************************/
#include "driver.h"
//变量定义
unsigned int Speed[4]={0,0,0,0}; // Speed[4] 范围500---250Hz,5000---2500Hz
// Speed[]=(1250/f)*1000,即可导出频率大小
typedef struct // 速度捕捉的结构体
{
uint8 k; // 捕捉次数
uint16 speed; // 相邻沿的计数差值
uint16 new; // new计数值
uint16 last; // last计数值
uint16 detect[5]; // 装捕捉值的数组
}CAPstu;
static CAPstu Cap1={0,0,0,0,0,0,0,0,0},Cap2={0,0,0,0,0,0,0,0,0};
static CAPstu Cap3={0,0,0,0,0,0,0,0,0},Cap4={0,0,0,0,0,0,0,0,0};
/******************************************************************************
**函数名称:Speed_detect(void)
**函数功能:机轮1~4速度检测,并实现数字滤波
**入口参数:无
**出口参数:int= 1 检测成功;
** int=-1 检测失败;
**备注:应该把CAP值读取,与速度计算的功能分开,需要增加 CAP_process()函数
*******************************************************************************/
int Speed_detect(void)
{
unsigned int CAP1_flag; // 捕获1~4中断标志变量
unsigned int CAP2_flag;
unsigned int CAP3_flag;
unsigned int CAP4_flag;
CAP1_flag = EVAIFRC&0X0001; // CAP1中断标志
CAP2_flag = EVAIFRC&0X0002; // CAP2中断标志
CAP3_flag = EVAIFRC&0X0004; // CAP3中断标志
CAP4_flag = EVBIFRC&0X0001; // CAP4中断标志
if(CAP1_flag==0x0001) // 判断CAP1中断标志置位否
{
EVAIFRC=EVAIFRC|0x0001; // 写"1"清除CAP1中断标志
Cap1.new = CAP1FIFO; // 读取计数器的值
if(Cap1.new > Cap1.last)
{
Cap1.speed=Cap1.new-Cap1.last; // 计算双沿的时间计数值
}
else
{
Cap1.speed=Cap1.new-Cap1.last+25000; /*此处尚须修改,需要防止超过n周期*/
}
Cap1.last=Cap1.new; // 将新的捕捉值赋给上一次的变量
Cap1.detect[Cap1.k]=Cap1.speed; // 装入捕捉计数差值数组
Cap1.k++; // 计数器增1
if(Cap1.k==5)
{
Speed[0]=(Cap1.detect[1]+Cap1.detect[2]
+Cap1.detect[3]+Cap1.detect[4])/4; // 4次平均值
Cap1.k=0; // 复位计数器
}
}
if(CAP2_flag==0x0002) // 判断CAP2中断标志置位否
{
EVAIFRC=EVAIFRC|0x0002; // 写"1"清除CAP2中断标志
Cap2.new=CAP2FIFO; // 读取计数器的值
if(Cap2.new>Cap2.last)
{
Cap2.speed=Cap2.new-Cap2.last;
}
else
{
Cap2.speed=Cap2.new-Cap2.last+25000;
}
Cap2.last=Cap2.new;
Cap2.detect[Cap2.k]=Cap2.speed; // 装入捕捉计数差值数组
Cap2.k++; // 计数器增1
if(Cap2.k==5)
{
Speed[1]=(Cap2.detect[1]+Cap2.detect[2]
+Cap2.detect[3]+Cap2.detect[4])/4; // 4次平均值
Cap2.k=0; // 复位计数器
}
}
if(CAP3_flag==0x0004) // 判断CAP3中断标志置位否
{
EVAIFRC=EVAIFRC|0x0004; // 写"1"清除CAP3中断标志
Cap3.new=CAP3FIFO; // 读取计数器的值
if(Cap3.new>Cap3.last)
{
Cap3.speed=Cap3.new-Cap3.last;
}
else
{
Cap3.speed=Cap3.new-Cap3.last+25000;
}
Cap3.last=Cap3.new;
Cap3.detect[Cap3.k]=Cap3.speed; // 装入捕捉计数差值数组
Cap3.k++; // 计数器增1
if(Cap3.k==5)
{
Speed[2]=(Cap3.detect[1]+Cap3.detect[2]
+Cap3.detect[3]+Cap3.detect[4])/4; // 4次平均值
Cap3.k=0; // 复位计数器
}
}
if(CAP4_flag==0x0001) // 判断CAP4中断标志置位否
{
EVBIFRC=EVBIFRC|0x0001; // 写"1"清除CAP4中断标志
Cap4.new=CAP4FIFO; // 读取计数器的值
if(Cap4.new>Cap4.last)
{
Cap4.speed=Cap4.new-Cap4.last;
}
else
{
Cap4.speed=Cap4.new-Cap4.last+25000;
}
Cap4.last=Cap4.new;
Cap4.detect[Cap4.k]=Cap4.speed; // 装入捕捉计数差值数组
Cap4.k++; // 计数器增1
if(Cap4.k==5)
{
Speed[3]=(Cap4.detect[1]+Cap4.detect[2]
+Cap4.detect[3]+Cap4.detect[4])/4; // 4次平均值
Cap4.k=0; // 复位计数器
}
}
if(1==State[0][0])
return ok; // 如果轮速传感器无故障,则检测成功
else
return fail; // 检测失败
}
/******************************************************************************
**函数名称:CAP_Init()
**函数功能:捕获单元初始化,cap1~cap3用定时器2,CAP4用定时器4
**入口参数:无
**出口参数:无
*******************************************************************************/
int CAP_Init(void)
{
/*端口设置*/
MCRA=MCRA|0x0038; // 配置 IOPA3--CAP1,IOPA4--CAP2,IOPA5--CAP3
MCRC=MCRC|0x0080; // IOPA7--CAP4
T2PR= 0x61A8; // 通用定时器2的周期寄存器为25000 10ms
T2CON=0X1400; // 通用定时器2为连续增计数模式 16分频 X/16=2.5M
T2CNT=0X00; // 计数器清0
T4PR=0X61A8; // 通用定时器4的周期寄存器为25000 10ms
T4CON=0X1400; // 通用定时器4为连续增计数模式 16分频 X/16=2.5M
T4CNT=0X00; // 计数器清0
// CAPCONA=0XB0FF; // 设置捕获单元1、2、3为检测2个边沿,且选择TIMER2为时钟;
// CAPCONB=0XA0C0; // 设置捕获单元4为检测双沿,且选择TIMER4为时钟
CAPCONA=0XB055; // 设置捕获单元1、2、3捕获上升沿
CAPCONB=0XA040; // 设置捕获单元4捕获上升沿
}
/**************************************************************************
**程序名称:CAP_test.c
**程序描述:
** 通过控制PWM12输出占空比50%的方波,试验CAP1~CAP4的工作是否正常
** PWM 频率 1000HZ
**时间日期: 12.10
**备注说明:此功能与第7路PWM同用定时器3,因此频率冲突,不可同时使用
***************************************************************************/
void CAPtest_Init(void)
{
MCRC=MCRC|0x0040; // 配置IOPE6为PWM12
ACTRB=0x0555; // PWM12低有效
DBTCONB=0x00; // 不使能死区控制
T3PR=39999; // PWM12频率设定1KHz
CMPR6=20000; // 占空比50%
COMCONB=0x8200; // 使能比较操作
T3CON=0x1000; // 定时器3为连续增计数模式,不分频X/1=40M
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -