曲轴凸轮轴位置信号对于发动机电控十分重要,通过它们可以确定曲轴当前转速,以及判定x缸活塞到达上止点(判缸),是喷油和点火的重要依据。本次实验我们尝试基于STM32F103的最小系统板,来模拟脉冲型曲轴和凸轮轴信号。

曲轴每旋转2圈,凸轮轴旋转1圈,完成4次点火(1-3-4-2)。4缸汽油机常见的曲轴信号为60-2,即一周58个周期脉冲加两个周期低电平;4缸汽油机常见凸轮轴信号为每转4个脉冲(对应x缸活塞上止点,曲轴换向),且在一缸脉冲后30°额外添加一个脉冲,作为1缸信号(类似于磁场定向中的Z脉冲信号)。实际的曲轴与凸轮轴通过正时链条(或皮带)连接,具有同步性。

本次实验采用两个定时器(定时器1,定时器2),一个定时器中断服务(定时器1更新中断)。定时器1通过PWM(硬件动作,节省计算资源)来模拟曲轴脉冲信号,脉冲计数则在定时器1中断服务中完成。定时器2通过PWM来模拟凸轮轴脉冲信号,而脉冲计数则在定时器1中断服务中完成。

首先给出两个定时器的配置,

void TIMER1_INIT(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//输出PWM需要配置为复用推挽GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_InternalClockConfig(TIM1);//定时器1启用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//时基单元配置TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;//向下计数TIM_TimeBaseInitStructure.TIM_Period = 100-1;TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);//初始化其他未设置的变量TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM1模式(高有效)TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC1Init(TIM1, &TIM_OCInitStructure);//(第1通道)TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清中断标志位TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//开定时器中断TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清定时器1中断标志位TIM_Cmd(TIM1, DISABLE);//关定时器TIM_CtrlPWMOutputs(TIM1, DISABLE);//关pwm主使能(高级定时器独有)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级配置NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStructure);//配置中断通道
}
void TIMER2_INIT(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_InternalClockConfig(TIM2);//定时器1启用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//时基单元配置TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 200-1;TIM_TimeBaseInitStructure.TIM_Prescaler = 1080-1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);//初始化其他未设置的变量
//  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM1模式(高有效)
//  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
//  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
//  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//关下路互补,做单(上)桥臂斩波TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = 0;TIM_OC1Init(TIM2, &TIM_OCInitStructure);//(第1通道)TIM_SetCounter(TIM2, 197);//同步预装TIM_Cmd(TIM2, DISABLE);//等待软件开定时器2
}

为了保证两个定时的PWM脉冲尽量对齐,在主程序中依次开启两个定时器,

int main()
{   TIMER1_INIT();TIMER2_INIT();TIM_Cmd(TIM1, ENABLE);//曲轴信号TIM_Cmd(TIM2, ENABLE);//凸轮轴信号TIM_SetCompare1(TIM1, 0);TIM_SetCompare1(TIM2, 0);while(1){}
}

考虑到曲轴和凸轮轴信号并非单纯的脉冲,其存在大周期,所以两定时器比较器的装载值在定时器1中断服务中根据脉冲计数值来给定。

这里有一些需要注意的地方:

PWM是硬件动作,软件对比较器装载值的实时修改有时是“不及时”的。具体来讲,以向上计数,上溢中断为例,当计数器周期为100,比较器装载50,我们将得到0.5占空比的PWM,当完成58个脉冲输出后,我们需要在下个中断服务中将比较器装载值改为1,或直接关PWM,这里就体现的软件“不及时”的问题,如下图

可以看出,原本是完全低电平的最后两个周期出现了两个窄脉冲,这是因为由上溢中断到来至配置比较器装置(或关PWM),程序执行需要时间,而在这段时间中比较器值大于计数器,所以PWM会出高电平。考虑到上述问题,本次实验采用向下计数,这样当更新(下溢)中断到来时,比较器值小于计数器,PWM不会出高电平。如下图所示

对于曲轴信号,脉冲计数器值58,59和118,119为全周期低电平,大于119则归零复位(曲轴转2圈,凸轮轴转1圈,进入下一周期)。

凸轮轴信号通过通过定时器2的PWM来模拟,曲轴完成两个60-2,凸轮轴完成一个4脉冲,+一个1后30°单脉冲,所以定时器1的PWM频率时定时器2的30倍,通过设置分频及计数器周期可以对定时器2的PWM周期灵活调整;通过定时器2计数器的预装值来微调其相位。最后对于1缸上止点后30°的单脉冲,可通过在中断服务中修改定时器2比较器装载值来实现,如下图,

这里30°可以通过曲轴脉冲数来确定,凸轮轴30°对应曲轴60°,即第10脉冲,至于凸轮轴脉冲宽度,可以自定。中断服务如下

void TIM1_UP_IRQHandler(void)//定时器1中断服务函数
{static uint16_t num;//曲轴脉冲计数器if(TIM_GetITStatus(TIM1, TIM_IT_Update)==SET)//查定时器1中断标志位{  TIM_CtrlPWMOutputs(TIM1, ENABLE);//开pwm主使能(高级定时器独有)num++;if(num>=10&&num<=12){TIM_SetCompare1(TIM2, 100);}else if(num==58|num==59|num==118|num==119){TIM_SetCompare1(TIM2, 20);TIM_CtrlPWMOutputs(TIM1, DISABLE);//关pwm主使能(高级定时器独有)}else if(num>119){num = 0;TIM_SetCompare1(TIM2, 20);TIM_SetCompare1(TIM1, 50);}else {TIM_SetCompare1(TIM2, 20);TIM_SetCompare1(TIM1, 50);}TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清定时器1中断标志位}
}

最终效果如下,

介于本人水平有限,本次实验目的仅仅是抛砖引玉,希望大家能够贴上更简单的代码。

四缸汽油机曲轴及凸轮轴信号生成(基于STM32)相关推荐

  1. stm32采集交流电压信号_基于STM32的交流电压检测.pdf

    第24卷第13期 电子设计工程 2016年7月 V01.24 No.13 Electronic Jul.2016 DesignEngineering 基于STM32的交流电压检测 任宏斌,冷建伟 (天 ...

  2. VVC学习之五:帧内预测——67个模式预测信号生成 predIntraAng()

    文章目录 简介 predIntraAng() xPredIntraDc() xPredIntraPlanar() xPredIntraAng() 简介 帧内共有67种预测模式,包括 65种角度+DC+ ...

  3. python实现给定信号生成任意信噪比的带噪声信号

    python实现给定信号生成任意信噪比的带噪声信号 产生叠加高斯白噪声的带噪语音 功能: 输入x为需加噪的信号,是一个numpy的1D张量 输入snr为设定信噪比,单位为dB,是一个32为的float ...

  4. matlab数字信号处理(1)——正弦信号生成与时域分析

    写在前面 最近一直在用matlab在所信号处理算法的仿真工作,这一系列博客主要会分详一下遇到的一些问题及解决办法,和一些常用的功能模块的实现以及分分享. 一.正弦信号生成 一段正弦信号,主要设计这些参 ...

  5. 雷达PRI变化信号生成Matlab仿真

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 雷达PRI变化信号生成 1.PRI参差信号 2.PRI抖动信号 3.PRI滑变 4.部分代码 雷达PRI变化信号生成 在信号 ...

  6. 信号生成和可视化——周期性/非周期性波形

    信号生成和可视化--周期性/非周期性波形 目录 信号生成和可视化--周期性/非周期性波形 周期性波形 sawtooth 函数生成锯齿波 square 函数生成方波 非周期性波形 tripuls.rec ...

  7. 高斯随机信号matlab,高斯随机信号生成初探.ppt

    高斯随机信号生成初探 BPSK误码率仿真(n=30) QPSK误码率仿真(n=10) QPSK误码率仿真(n=30) 分析~3 在低SNR部分,三种方法产生的噪声对系统性能影响不大,而在高SNR部分, ...

  8. LimeSDR 信号生成发射与接收分析

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 本文利用LimeSDR和GNU Radio生成正弦波.余弦波.方波.三角波.锯齿波等信号,并能够利用设备同步接收这些信号,能够对接收到的信号 ...

  9. 四菱天线怎么加强_自制四菱天线接收地面数字电视信号

    本文所述的四菱天线适合接收地面数字电视信号.经实际测试四菱天线接收效果优于五单元八木天线,加装反射板的四菱天线接收效果优于七单元八木天线.因此在当地电视信号不是太弱的情况下最好自制四菱天线来接收,相对 ...

最新文章

  1. GDAL Data Model(转)
  2. RH5.4下安装samba服务器(1)
  3. 【贪心】畜栏预定(ybtoj 贪心-1-3)
  4. IOS模拟器调试ANE
  5. LeetCode 1197. 进击的骑士(BFS)
  6. android jni 调用java_Android 基于NDK的JNI开发 C调用java和java调用C
  7. 云服务的可服务性经典6问
  8. 企业微信3.0版本发布:客户朋友圈功能正式上线
  9. 高分选手讲解:如何突破思维圈限,从NLP角度挖掘新的解题思路
  10. Python3中的md5加密
  11. . mindoc linux amd64,搭建minDoc文件接口服务器
  12. 乐高无限自己地图无法服务器,乐高无限地图制作攻略 建造的小细节不要错过...
  13. How the System Finds and Loads Drivers
  14. 现在做外卖CPS晚吗?应该怎样做效果好一点?
  15. 2.5 射频辐射电磁场抗扰度试验【电磁兼容EMC原理、设计与故障排除】
  16. vue单击li变色,点谁谁亮
  17. 自动弹窗加QQ群代码
  18. 游戏开发41课 unity 目录分析
  19. Python我的世界小游戏源代码
  20. 试卷自动生成系统(JSP+MySQL)

热门文章

  1. 58同城 反爬虫机制及处理
  2. stm32开发3D打印机(二)——方向、相关资料链接
  3. 如何解决 Windows 实例出现身份验证错误
  4. HTML5创建热点区域
  5. pycharm中使用chatgpt
  6. Android launcher 桌面抽屉切换动画
  7. 利用Python 回归分析,四步预测广告收入 (附数据集与代码)
  8. VC中_T()的作用
  9. mysql acid
  10. 学习c/c++ 推荐学习什么书籍?