版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
STM32单片机测量方波频率方法总结一、测周法:通过一个方波的两个上升沿或下降沿触发中断,然后定时器计数,计数的总个数乘以计数单位时间即该方波的周期,具体可通过单片机输入捕获功能实现,以下为参考代码//输入捕获初始化函数voidinput_frequent_init(void)//采用TIM4的Channel」通道作为输入捕获通道{//声明结构体变量,用来初始化定时器TIM_TimeBaseInitTypeDefTIM4_TimeBaseInitStrueture;TIM_ICInitTypeDefTIM4_ICInitStrueture;NVIC_InitTypeDefTIM4_NVIC_InitStrueture;/*开启定时器4时钟*/RCC_APBlPeriphClockCmd(RCC_APBlPeriph_TIM4,ENABLE);TIM_ClearITPendingBit(TIM4,TIM_IT_Update|TIM_IT_CCl);//清除捕获和中断标志位TIM4_TimeBaseInitStrueture.TIM_Period=Oxffff;//设定计数器自动重装值(设置为最大)
TIM4_TimeBaseInitStrueture.TIM_Prescaler=1;//设置分频系数TIM4_TimeBaseInitStrueture.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分割:TDTS=Tck_timTIM4_TimeBaseInitStrueture.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数模式TIM_TimeBaseInit(TIM4,&TIM4_TimeBaseInitStrueture);//根据结构体参量初始化定时器TIM4_ICInitStrueture.TIM_Channel=TIM_Channel_l;//选择输入捕获的输入端,IC1映射到TI1上TIM4_ICInitStrueture.TIM_ICPolarity=TIM_ICPolarity—Rising;//设置为上升沿捕获TIM4_ICInitStrueture.TIM_ICSelection=TIM_ICSelection_DireetTI;//映射到TI1上TIM4_ICInitStrueture.TIM_ICPrescaler=TIM_ICPSC_DIV1;//配置输入分频,不分频TIM4_ICInitStrueture.TIM_ICFilter=0x00;//IC1F=0000配置输入滤波器,此处不滤波
TIM_ICInit(TIM4,&TIM4_ICInitStrueture);//初始化TIM4通道1//中断分组初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);TIM4_NVIC_InitStrueture.NVIC_IRQChannel二TIM4_IRQn;//打开TIM4的全局中断TIM4_NVIC_InitStrueture.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级配置为1TIM4_NVIC_InitStrueture.NVIC_IRQChannelSubPriority=1;//响应优先级配置为1TIM4_NVIC_InitStrueture.NVIC_IRQChannelCmd=ENABLE;//使能NVIC_Init(&TIM4_NVIC_InitStrueture);//初始化中断TIM_Cmd(TIM4,ENABLE);//使能中断TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC1,ENABLE);//使能捕获和更新中断
}需要注意的是,如果所测信号中存在尖峰干扰信号,则TIM4_ICInitStrueture.TIM_ICFilter=0x00;//IC1F=0000配置输入滤波器,此处不滤波这一行应根据干扰信号的高电平时间来赋予合适的滤波器的值,具体计算方法参考芯片手册或自行百度。voidTIM4_IRQHandler()//输入捕获中断函数{staticu8state;//存储捕获状态,state=0表示未捕获到第一个上升沿,state=1表示已经捕获到第一个上升沿staticu32TIM4CH1_CAPTURE;//存储TIM4计数寄存器溢出次数u32timecount;//存储总的计数次数if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)//发生计数器溢出更新中断elseif(state==1)elseif(state==1)//已经捕获到第一个上升沿TIM_ClearITPendingBit(TIM4,TIM_IT_CC1|TIM_IT_Update);//清除中断标志位if(state==1)//在捕获到第一个上升沿后TIM4CH1_CAPTURE++;//溢出次数加一}if(TIM_GetITStatus(TIM4,TIM_IT_CCl)!=RESET)//产生输入捕获中断{TIM_ClearITPendingBit(TIM4,TIM_IT_CC1|TIM_IT_Update);//清除中断标志位if(state==0)//未捕获到第一个上升沿{state=1;//置1TIM_SetCounter(TIM4,0);//将计数器清零}
state=0;//置0timecount二TIM_GetCapturel(TIM4)+TIM4CHl_CAPTURE*65536;//计算两个上升沿之间的总计数TIM4CH1_CAPTURE=0;//清零溢出次数TIM_SetCounter(TIM4,0);//清零计数器frequent_input二36000000.0/timecount;//计算频率}}}注意:根据所测频率大致范围来配置定时器(可提高测量精度)该方法可精确测量较低频率,本人测试lk以下精确度高达0.1%,但随着频率的增加,误差也越来越大,故测低频时推荐此方法接下来的程序还可测量占空比,思路是先设置为上升沿捕获,然后设置为下降沿捕获,在设置为上升沿捕获,根据两次捕获中计数次数算出占空比duty二捕获高电平时间/(捕获高电平时间+捕获低电平时间)
定时器输入捕获配置同上(改用TIM5,TIM分频系数改为143,TIM_Prescaler=143),不在重复,直接看中断函数voidTIM5_IRQHandler(){if((TIM5CHl_CAPTURE_STA&0X80)==0)//还未成功捕获{if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET){if(TIM5CHl_CAPTURE_STA&0X20)//已经捕获到高电平{if((TIM5CHl_CAPTURE_STA&0xlf)==0x1f)//高电平时间太长了{TIM5CHl_CAPTURE_STA|=0x80;//标记成功捕获一次
else{TIM5CH1_CAPTURE_STA++;//溢出次数加1}}}}if(TIM_GetITStatus(TIM5,TIM_IT_CC4)!=RESET)//发生捕获事件{if((TIM5CH1_CAPTURE_STA&0X20)&&(!(TIM5CH1_CAPTURE_STA&0X40)))//已经捕获到上升沿{TIM5CH1_CAPTURE_STA|=0X40;//标记成功捕获一次下降沿
TIM5CH1_CAPTURE_VAL1二TIM_GetCapture4(TIM5)+(TIM5CH1_CAPTURE_STA&0Xlf)*65536;//获得TIM5捕获通道一的捕获值(对应高电平时间)TIM_SetCounter(TIM5,0);//清零计数器TIM_0C4PolarityConfig(TIM5,TIM_ICPolarity_Rising);//设置为上升沿捕获TIM5CH1_CAPTURE_STA&=0Xe0;//溢出次数清零}elseif((TIM5CHl_CAPTURE_STA&0X20)==0)//未捕获到上升沿{TIM5CH1_CAPTURE_STA=0;//清零标志位及溢出次数TIM5CH1_CAPTURE_VAL1=0;//清零高电平计数TIM5CH1_CAPTURE_VAL2=0;//清零低电平计数TIM_SetCounter(TIM5,0);TIM_SetCounter(TIM5,0);//清零TIM5计}}数寄存器TIM5CH1_CAPTURE_STA|=0X20;//置标志位TIM_0C4PolarityConfig(TIM5,TIM_ICPolarity_Falling);//设置为下降沿捕获}elseif((TIM5CHl_CAPTURE_STA&0X40)&&(!(TIM5CH1_CAPTURE_STA&0X80)))//已经捕获到下降沿{TIM5CH1_CAPTURE_VAL2二TIM_GetCapture4(TIM5)+(TIM5CH1_CAPTURE_STA&0Xlf)*65536;//低电平计数(对应低电平时间)TIM5CH1_CAPTURE_STA|=0X80;//置标志位}}TIM_ClearITPendingBit(TIM5,TIM_IT_CC4|TIM_IT_Update);//清中断标志位}}主函数u8TIM5CH1_CAPTURE_STA;//u16TIM5CH1_CAPTURE_VAL1;//u16TIM5CH1_CAPTURE_VAL2;//floatfrequent;floatduty;intmain(){input_duty_init();while(l){if((TIM5CHl_CAPTURE_STA&0x80))//{duty=(float)TIM5CHl_CAPTURE_VALl/(TIM5CH1_CAPTURE_VAL1+TIM5CH1_CAPTURE_VAL2);//计算占空比frequent+=500000.0/(TIM5CHl_CAPTURE_VAL1+TIM5CH1_CAPTURE_VAL2);//计算频率TIM5CH1_CAPTURE_STA=0;//清零标志位
}这个程序中变量TIM5CH1_CAPTURE_STA的高三位作为输入捕获状态的标志位,具体每一位的作用不在详细解释,凭借自学能力完全可以解决。该方法测量误差同样在频率比较低时精确度很高,但随着频率的增大误差也越来越大。二、测频法通过在一定时间内检测跳边沿的个数可计算出频率频率=上升沿或下降沿个数/统计时间具体实现有两种方法。1.利用外部中断统计跳边沿个数,配置一个定时器每隔一定时间对频率进行计算,部分代码如下voidexti_init()//外部中断初始化函数{GPI0_InitTypeDefGPI0_InitStrueture;EXTI_InitTypeDefEXTI_InitStrueture;NVIC_InitTypeDefNVIC_InitStrueture;/*开启GPIO和管脚复用时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFI0,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPI0C,ENABLE);/*GPIO配置*/GPIO_InitStructure.GPIO_Pin二GPI0_Pin_2;GPIO_InitStructure.GPIO_Mode二GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed二GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPI0_PinSource2);//选择GPIO引脚用作外部中段线路//此处一定要记住给端口管脚加上中断外部线路/*设置外部中断模式*/EXTI_InitStructure.EXTI_Line二EXTI_Line2;EXTI_InitStructure.EXTI_Mode二EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿进中断EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStrueture);/*设置NVIC参数*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_l);NVIC_InitStrueture.NVIC_IRQChannel=EXTI2_IRQn;//打开EXTI2的全局中断NVIC_InitStrueture.NVIC_IRQChannelPreemptionPriority=1;//设置优先级NVIC_InitStrueture.NVIC_IRQChannelSubPriority二1;NVIC_InitStrueture.NVIC_IRQChannelCmd=ENABLE;//使能NVIC_Init(&NVIC_InitStrueture);}外部中断中断函数voidEXTI2_IRQHandler(){if(EXTI_GetITStatus(EXTI_Line2)==SET)
EXTI_ClearITPendingBit(EXTI_Line0);//清中断if(GPIO_ReadInputDataBit(GPI0C,GPI0_Pin_2)==Bit_RESET)//确定沿{ent++;}}}定时器中断函数voidTIM3_IRQHandler(){frequent二ent;//定时器设置时间为Is时ent=0;//清零计数entTIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清标志位
该方法在实测300K以下频率误差很小,大概在0-20Hz左右,根据规律可以进行线性分段补偿,补偿后误差可控制在0-2Hz,但是随着频率升高,误差将越来越大不可弥补。2.采用定时器外部计数的方法,另外一个定时器负责每隔一段时间计算频率,部分代码如下voidtime_init(){GPI0_InitTypeDefGPI0_InitStrueture;TIM_TimeBaseInitTypeDefTIM2_TimeBaseInitStrueture;TIM_TimeBaseInitTypeDefTIM3_TimeBaseInitStrueture;NVIC_InitTypeDefNVIC_InitStrueture;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPI0A,ENABLE);RCC_APBlPeriphClockCmd(RCC_APBlPeriph_TIM3,ENABLE);RCC_APBlPeriphClockCmd(RCC_APBlPeriph_TIM2,ENABLE);GPIO_InitStrueture.GPIO_Pin二GPIO_Pin_0;GPIO_InitStrueture.GPIO_Mode二GPIO_Mode_IPU;
GPIO_InitStrueture.GPIO_Speed二GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStrueture);TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIM2中断标志位TIM2_TimeBaseInitStrueture.TIM_Period=0xFFFF;//设置自动重装载值TIM2_TimeBaseInitStrueture.TIM_Prescaler=0;//设置分频TIM2_TimeBaseInitStrueture.TIM_ClockDivision=TIM_CKD_DIV1;TIM2_TimeBaseInitStrueture.TIM_CounterMode=TIM_CounterMode_Up;//向上计数TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseInitStrueture);TIM_ETRClockModelConfig(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);//设置为采用外部时钟计数,可设定滤波参数消除信号干扰=0;=0;TIM_Cmd(TIM2,ENABLE);TIM_ClearITPendingBit(TIM3,TIM_IT_Update);TIM3_TimeBaseInitStrueture.TIM_Period=999;TIM3_TimeBaseInitStrueture.TIM_Prescaler=3599;TIM3_TimeBaseInitStrueture.TIM_ClockDivision=TIM_CKD_DIV1;TIM3_TimeBaseInitStrueture.TIM_CounterMode=TIM_Cou
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年冬天语言说课说课稿
- 2025-2026学年化学氧气的制取说课稿
- 微生物学和寄生虫学质量控制
- 2025-2026学年二年级数学说课稿下册六单
- 各年龄学前儿童心理发展的主要特征
- 2025-2026学年传统民间技艺说课稿
- 土壤与农业可持续发展
- 高二(2027届)地理人口分布教学设计
- 初中地理九年级一轮复习教学设计:北方地区主要分区专题研讨
- 初中八年级道德与法治教学设计:党领导人民制定宪法
- T-CECS 486-2017《数据中心供配电设计规程》
- 儿科护理工作压力管理
- 员工调动管理制度
- 链家员工合同
- 四不伤害及反三违安全培训课件
- 建筑工程技术课程
- 量力而行议论文
- 《心灯录》完整版
- 2026届新高考英语热点冲刺复习:定语从句
- 《盗窃案件的侦查》课件
- 小学生英语规范书写课件
评论
0/150
提交评论