GD32F103输入捕获

GD32F103输入捕获程序,经过多次测试,终于完成了。本程序将TIMER2_CH2通道映射到PB0引脚,捕获PB0引脚低电平脉冲时间宽度。PB0是一个按钮,第1次按下采集一个值保存到TIMER2_CountValue1中,第2次按下采集一个值保存到TIMER2_CountValue2中,然后计算其低电平时间宽度。

网上也有人写了测试案例,但好像能用,但不是很完善。

我喜欢直奔主题,程序如下:

#include "Timer2_InputCapture.h"
#include "stdio.h"  //使能printf(),sprintf()

uint16_t TIMER2_CountValueMAX = 65535;//设定最大捕获计数器值为65535
uint32_t TIMER2_CLKFrequence;
uint16_t TIMER2_OverValue = 0;//溢出次数
uint32_t TIMER2_CountValue1=0;
uint32_t TIMER2_CountValue2=0;
uint32_t TIMER2_CountResult=0;
uint8_t TIMER2_CaptchStatus=0;
float MyPeriod=0;
float MyFrequence=0;

void TIMER2_Input_Init(void);

//函数功能:将TIMER2_CH2通道映射到PB0引脚,捕获PB0引脚低电平脉冲时间宽度
//Tout=(65535+1)*(107+1)/108000000=0.065536秒
//TIMER2输入时钟频率:108000000/(107+1)=1000000Hz
void TIMER2_Input_Init(void)
{
	timer_parameter_struct      TimerParameterStruct;   //TIMER0初始化结构体
	timer_ic_parameter_struct   timer_icinitpara; //TIMER0输入捕获结构体
  rcu_periph_clock_enable(RCU_TIMER2);     //使能TIMER0时钟
  rcu_periph_clock_enable(RCU_GPIOB);      //使能GPIOB时钟
	rcu_periph_clock_enable(RCU_AF);         //使能复用时钟
	gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
	//将TIMER2_CH2通道映射到PB0引脚

	timer_deinit(TIMER2);
  timer_struct_para_init(&TimerParameterStruct);  //将初始化结构体参数变为初始值
	TimerParameterStruct.period            = TIMER2_CountValueMAX;   //定时器装载值,计数值超出后会产生溢出中断
  TimerParameterStruct.prescaler         = 107; //设置用来作为TIMx时钟频率除数的预分频值(APB2时钟分频值)
//Tout= ((arr+1)(psc+1))/Tclk;
//Tclk:TIM的输入时钟频率(单位为Hz),在这里是108000000Hz
//psc为定时器预分频值,在这里是107
//arr为重装载值,在程序中为65535
//Tout:TIM溢出时间(单位为s),Tout=(65535+1)*(107+1)/108000000=0.065536秒
	TimerParameterStruct.clockdivision     = TIMER_CKDIV_DIV1;   //设置时钟分母值为1

	TimerParameterStruct.counterdirection  = TIMER_COUNTER_UP;   //设置计数方向为"向上计数"
	TimerParameterStruct.alignedmode       = TIMER_COUNTER_EDGE; //设置为无中央对齐计数模式(边沿对齐模式)
  TimerParameterStruct.repetitioncounter = 0;                  //重复计数,重复溢出多少次才会溢出中断,此处配置为0,不重复
	timer_init(TIMER2,&TimerParameterStruct);//根据TimerParameterStruct所指向的参数初始化TIMERx的时间基数单位
 
	timer_channel_input_struct_para_init(&timer_icinitpara);    //将输入捕获结构体参数变为初始值
	timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_FALLING;    //通道输入极性
	timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; //通道输入模式选择"通道直连"
	timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;           //通道输入预分频器
	timer_icinitpara.icfilter    = 0;                         //通道输入捕获滤波
	timer_input_capture_config(TIMER2,TIMER_CH_2,&timer_icinitpara);

  timer_counter_value_config(TIMER2,0);//设置TIMER2的计数器初始值为0
	timer_auto_reload_shadow_enable(TIMER2); //自动重装载使能
/
  timer_flag_clear(TIMER2,TIMER_FLAG_UP);               //清除"TIMERx更新标志位"
  timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_UP); //清除"TIMERx更新中断标志位"
	timer_interrupt_enable(TIMER2,TIMER_INT_UP);          //使能"TIMERx更新"产生中断
	timer_internal_clock_config(TIMER2);//设置"内部时钟"作为定时器时钟
	TIMER2_CLKFrequence=SystemCoreClock/(TimerParameterStruct.prescaler+1);
	//SystemCoreClock=108000000MHz
/
	timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH2); //清除CH2的中断标志位
	timer_interrupt_enable(TIMER2,TIMER_INT_FLAG_CH2); //CH2通道中断使能
  nvic_irq_enable(TIMER2_IRQn,1,0); //使能中断线
	timer_enable(TIMER2);
}

/*
KEY==0
TIMER2_OverValue=11,  TIMER2_CountValue1=19395,  TIMER2_CountValue2=30890,  TIMER2_CountResult=732380
MyPeriod=0.732380s
MyFrequence=1.365411Hz
KEY==0
*/
//TIMER2中断服务函数
void TIMER2_IRQHandler(void)
{
	if( SET == timer_interrupt_flag_get(TIMER2,TIMER_INT_FLAG_UP) )// 读取更新中断标志位
	{
		if(1 == TIMER2_CaptchStatus) TIMER2_OverValue++;
		timer_flag_clear(TIMER2,TIMER_FLAG_UP);               //清除"TIMER0更新标志位"
		timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_UP); //清除"更新中断标志位"
//		printf("\r\nTIMER2 Interrupt");
	}
	if(timer_interrupt_flag_get(TIMER2,TIMER_INT_FLAG_CH2) != RESET)
	{
		timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH2);
    if(0 == TIMER2_CaptchStatus)
		{
			TIMER2_OverValue=0;//清除溢出计数器
			TIMER2_CountValue1 = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_2);
			TIMER2_CaptchStatus = 1;
		}
		else if(1 == TIMER2_CaptchStatus)
		{
			TIMER2_CountValue2 = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_2);
			TIMER2_CountResult	=	(TIMER2_OverValue*TIMER2_CountValueMAX-TIMER2_CountValue1)+TIMER2_CountValue2;

			MyPeriod=(float)TIMER2_CountResult/TIMER2_CLKFrequence;
			MyFrequence = (float)TIMER2_CLKFrequence/ TIMER2_CountResult;
			
			printf("\r\nTIMER2_OverValue=%u,  TIMER2_CountValue1=%u,  TIMER2_CountValue2=%u",TIMER2_OverValue,TIMER2_CountValue1,TIMER2_CountValue2);
			printf(",  TIMER2_CountResult=%u",TIMER2_CountResult);
			printf("\r\nMyPeriod=%fs",MyPeriod);
			printf("\r\nMyFrequence=%fHz",MyFrequence);
      TIMER2_OverValue = 0;//溢出次数
      TIMER2_CountValue1=0;
      TIMER2_CountValue2=0;
      TIMER2_CountResult=0;
			TIMER2_CaptchStatus = 0;
		}
	}
}
#include "KEY.h"

void KEY_Init(void);

//函数功能:初始化KEY
void KEY_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOB);//使能GPIOB时钟,enable GPIO clock
	gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);//将GPIOB0设置为浮空输入
}
#ifndef __KEY_H
#define __KEY_H

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t

#define KEY  PBin(0)   		//读取PB0的输入状态值
#define Read_KEY_Value()  gpio_input_bit_get(GPIOB, GPIO_PIN_0) //读取PB0的输入状态值

extern void KEY_Init(void);

#endif
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()
#include "KEY.h"
#include "Timer2_InputCapture.h"

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{
	//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
	//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
	//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
	//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
	//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
	UART3_Init(115200);//初始化UART3
	printf("%s",CPU_Reset_REG);//调试串口输出"\r\nCPU reset!\r\n"

  INTX_ENABLE();//开启所有中断

	KEY_Init();//初始化KEY
	TIMER2_Input_Init();//将TIMER2_CH2通道映射到PB0引脚,捕获PB0引脚低电平脉冲时间宽度

	while(1)
	{
		if(KEY==0)
    {
		  printf("\n\rKEY==0");
			while(KEY==0);//等待按键释放
		}
	}
}
#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()

void UART3_Init(unsigned int bound);

//函数功能:初始化串口3,这个和STM32F103VET6的UART4兼容
void UART3_Init(unsigned int bound)
{
	rcu_periph_clock_enable(RCU_GPIOC); //使能GPIOC时钟,enable GPIO clock 
	rcu_periph_clock_enable(RCU_UART3); //使能UART3时钟,enable USART clock

	gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
	//将GPIOC10设置为AFIO口(复用IO口),输出上拉

	gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	//将GPIOC11设置为浮空输入口

	usart_deinit(UART3);                         //复位UART3,USART configure
	usart_baudrate_set(UART3, bound);          //设置UART3的波特率
	usart_word_length_set(UART3, USART_WL_8BIT); //设置UART3数据传输格式为8位
	usart_stop_bit_set(UART3, USART_STB_1BIT);   //设置UART3停止位为1位
	usart_parity_config(UART3, USART_PM_NONE);   //设置UART3无需奇偶校验
	usart_hardware_flow_rts_config(UART3, USART_RTS_DISABLE); //设置不使能UART3的RTS引脚功能
	usart_hardware_flow_cts_config(UART3, USART_CTS_DISABLE); //设置不使能UART3的CTS引脚功能
	usart_receive_config(UART3, USART_RECEIVE_ENABLE);   //使能UART3接收
	usart_transmit_config(UART3, USART_TRANSMIT_ENABLE); //使能UART3发送
	usart_enable(UART3); //使能UART3
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
	usart_data_transmit(UART3, (uint8_t) ch);
	while( RESET == usart_flag_get(UART3, USART_FLAG_TBE) )
	{//等待串口0发送结束
	}

	return ch;
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/62532.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NGZORRO:动态表单/模型驱动 的相关问题

官网的demo的[nzFor]"control.controlInstance"&#xff0c;似乎是靠[formControlName]"control.controlInstance"来关联的。 <form nz-form [formGroup]"validateForm" (ngSubmit)"submitForm()"><nz-form-item *ngFor&quo…

Ctfshow web入门 JWT篇 web345-web350 详细题解 全

CTFshow JWT web345 先看题目&#xff0c;提示admin。 抓个包看看看。 好吧我不装了&#xff0c;其实我知道是JWT。直接开做。 在jwt.io转换后&#xff0c;发现不存在第三部分的签证&#xff0c;也就不需要知道密钥。 全称是JSON Web Token。 通俗地说&#xff0c;JWT的本质…

idea运行web老项目

idea打开老项目 首先你要用idea打开老项目&#xff0c;这里看我之前发的文章就可以啦 运行web项目 1. 编辑配置 2. 添加tomcat项目 3. 设置tomcat参数 选择本地tomcat&#xff0c;注意有的tomcat版本&#xff0c;不然运行不了设置-Dfile.encodingUTF-8 启动&#xff0c;这样…

vue 列表|表格环境中的下拉菜单

elementui组件为vue提供了各式各样的ui组件&#xff0c;但均为各类最为基本的控件&#xff0c;没有提供业务级的使用案例&#xff0c;为此进行扩展补充。 vue-elementui 基本入门使用 一、下拉菜单 下拉菜单与html中的select控件有所差距&#xff0c;select为表单控件的一员页…

Hi,运维,你懂Java吗--No.9:线程池

作为运维&#xff0c;你不一定要会写Java代码&#xff0c;但是一定要懂Java在生产跑起来之后的各种机制。 本文为《Hi&#xff0c;运维&#xff0c;你懂Java吗》系列文章 第九篇&#xff0c;敬请关注后续系列文章 欢迎关注 龙叔运维&#xff08;公众号&#xff09; 持续分享运维…

VectorDBBench向量数据库性能评测工具

目录 一、背景和意义 二、特点和优势 三、应用场景和实际效果 四、总结 摘要: VectorDBBench.com是一个基于云计算的向量数据库基准测试平台,旨在评估不同向量数据库的性能和可扩展性。本文介绍了VectorDBBench的背景和意义,分析了VectorDBBench的特点和优势,并从多个方…

Java个人博客系统--基于Springboot的设计与实现

目录 一、项目概述 应用技术 接口实现&#xff1a; 数据库定义&#xff1a; 数据库建表&#xff1a; 博客表数据库相关操作&#xff1a; 添加项⽬公共模块 加密MD5 页面展示&#xff1a;http://121.41.168.121:8080/blog_login.html 项目源码&#xff1a;https://gitee…

selenium 和 chromedriver 使用的一些总结

1 selenium 下载地址 selenium PyPIhttps://pypi.org/project/selenium/ 2 chromedriver 下载地址 &#xff0c;可以下载最新版的 chromedriver ChromeDriver - WebDriver for Chrome - Downloadshttps://chromedriver.chromium.org/downloadsChrome for Testing availabi…

Android 刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…

Redis实战(5)——Redis实现消息队列

消息队列&#xff0c;顾名思义&#xff0c;就是一个存放消息的队列。最简单的消息队列包含3个角色 生产者&#xff1a;将消息存入队列中队列&#xff1a;存放和管理消息消费者&#xff1a; 将消息从队列中取出来并做业务处理 R e d i s 提供了三种实现消息队列的方式&#x…

Linux性能学习(4.5):网络_TCP四次挥手内核参数优化

文章目录 1 四次挥手2 参数优化2.1 tcp_orphan_retries--->FIN报文重传次数2.2 tcp_max_orphans--->孤儿连接最大数量2.3 tcp_fin_timeout--->FINE_WAIT2状态等待时间2.4 tcp_max_tw_buckets2.5 tcp_tw_reuse--->复用未释放的端口 3 总结 参考资料&#xff1a; 1. …

星图按转化线索回传对接思路与示例

一、什么是星图&#xff1f;二、什么是线索转化&#xff1f;三、对接中的一些疑问&#xff1f;四、如何对接开发&#xff1f;五、星图侧如何联调测试&#xff1f; 一、什么是星图&#xff1f; 抖音星图是抖音电商蓝图下&#xff0c;为品牌方、MCN公司和明星/达人服务并收取分…

【DFS】17. 电话号码的字母组合

【DFS】17. 电话号码的字母组合 Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我bua&#xff01; TOC 题目: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rikjhVFD-1691333891079)(C:\Us…

IAR开发环境的安装、配置和新建STM32工程模板

IAR到环境配置到新建工程模板-以STM32为例 一、 简单介绍一下IAR软件1. IAR的安装&#xff08;1&#xff09; 下载IAR集成开发环境安装文件&#xff08;2&#xff09; 安装 2. 软件注册授权 二、IAR上手使用(基于STM32标准库新建工程)1、下载标准库文件2、在IAR新建工程&#x…

华为云交付

文章目录 一、华为云-公有云架构华为公有云的主要服务1.华为云服务—计算类2.华为云服务——存储类3.华为云服务—网络类4.华为云服务—管理和监督类5.华为云数据库 二、待续 一、华为云-公有云架构 华为公有云的主要服务 ECS&#xff1a;弹性云服务器&#xff08; Elastic Cl…

交互流程图设计软件都有哪些?

交互流程图是设计行业信息流、观点流或组件流的图形代表。但是市场上应该如何选择各种交互流程图软件呢&#xff1f;如何使用高质量的交互流程图软件来绘制高端氛围的高档流程图&#xff1f;今天&#xff0c;小边给您带来了十个超级实用的交互流程图软件&#xff0c;我希望能帮…

解决宝塔面板升级获取更新包失败,请稍后更新或联系宝塔运维

宝塔Linux面板执行升级命令后失败&#xff0c;提示“获取更新包失败&#xff0c;请稍后更新或联系宝塔运维”如何解决&#xff1f;新手站长分享宝塔面板升级失败的解决方法&#xff1a; 宝塔面板升级失败解决方法 1、使用root账户登录到你的云服务器上&#xff0c;宝塔Linux面…

亿欧智库:2023中国宠物行业新趋势洞察报告(附下载)

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 户外赛道本质上迎合了全球共性需求的增长&#xff0c;从养宠意愿的转化到养宠生活的需求&#xff0c;多层次的需求推动行业发展新趋势 从需求端进行分析&#xff0c;可以将养宠意愿的转化分为三个层…

Python语法:... for ... in ... if ...

Python中&#xff0c;for...in...[if]...语句是一种简洁的构建List的方法&#xff0c;从for给定的List中选择出满足if条件的元素组成新的List&#xff0c;其中if是可以省略的。下面举几个简单的例子进行说明 [for in ]: ...for ....in..... 语句. 实例如下&#xff1a; (1) …

零知识证明技术概述

简述 隐私泄露问题给企业带来了巨大的损失&#xff0c;本文简述零知识证明技术并且给出对应的应用示例&#xff1a; 什么是零知识证明&#xff1f; 零知识证明又被称为零知识协议&#xff0c;利用数学知识在双方不需要直接传递信息本身的前提下来验证信息的正确性。这个思想…
最新文章