dedecms网站制作教程,机械英语网站,男女做暧暧试看网站49,建筑公司排名前100这里写目录标题 STM32资料包#xff1a; 百度网盘下载链接#xff1a;链接#xff1a;https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码#xff1a;8888 一、任务描述二、任务实施1、工程文件夹创建2、函数编辑#xff08;1#xff09;主函数编辑#… 这里写目录标题 STM32资料包 百度网盘下载链接链接https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码8888 一、任务描述二、任务实施1、工程文件夹创建2、函数编辑1主函数编辑2USART1初始化函数(usart1_init())3USART数据发送函数 USART1_Send_Data4USART数据发送函数 USART1_IRQHandler(5定时器5通道1输入捕获配置函数 TIM5_Cap_Init(uint16_t arr,uint16_t psc)6定时器5通道1输入捕获配置函数 TIM5_Cap_Init(uint16_t arr,uint16_t psc) 3、宏定义输入捕获头文件编辑 4、知识链接1输入捕获基础知识2输入捕获通俗理解 5、工程测试 STM32资料包 百度网盘下载链接链接https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码8888
一、任务描述 二、任务实施
观察电路图: TXD(底板) ———————— PA10 RXD(底板) ———————— PA9 DK1 (底板) ———————— PA0 使用USB-AB型数据线连接15核心板USB口,串口发送接收到的数据。实现了STM32定时器的输入捕获功能用于捕获外部信号的时间戳。
1、工程文件夹创建
步骤1复制工程模板“1_Template”重命名为“13_PassiveBeep”。 步骤2修改项目工程名先删除projects文件夹内除了Template.uvprojx文件外的所有内容并修改为“.uvprojx”。并删除output/obj和output/lst中的所有文件。 步骤3运行“PassiveBeep.uvprojx”打开目标选项“Options for Target”中的“Output”输出文件并修改可执行文件名称为“PWM”点击“OK”保存设置。最后点击“Rebuild”编译该工程生成Usart文件。 步骤4复制2_LEDTest中的1_LED和文件复制到hardware中。 步骤5在system文件夹中新建一个input文件夹并在该文件夹下新建input.c和input.h两个文件。 步骤5工程组文件中添加“led”文件夹内的所有文件。 步骤6工程组文件中添加“input”文件夹内的所有文件。 步骤6目标选项添加添加头文件路径。
2、函数编辑
1主函数编辑
基于STM32的输入捕获功能通过定时器5捕获外部信号的下降沿并计算低电平的总时间然后通过USART1串口打印输出。 步骤2实现一个简单的计时器并在每秒打印一次计时信息。利用LED状态的改变来指示系统正在运行。
while(1) {if(TIM5CH1_CAPTURE_STA0X80) // 检查TIM5CH1_CAPTURE_STA的最高位是否为1表示成功捕获到了一次下降沿{tempTIM5CH1_CAPTURE_STA0X3F; // 获取TIM5CH1_CAPTURE_STA的低6位即溢出计数temp*65536; // 将溢出计数左移16位即乘以65536得到溢出时间总和tempTIM5CH1_CAPTURE_VAL; // 将总的溢出时间总和与当前捕获值相加得到总的低电平时间printf(LOW:%d us\r\n,temp); // 打印总的低电平时间单位为微秒TIM5CH1_CAPTURE_STA0; // 清零TIM5CH1_CAPTURE_STA准备开启下一次捕获} }2USART1初始化函数(usart1_init())
配置了 PA9 为复用推挽输出用于 USART1 的 TXD并配置了 PA10 为浮空输入用于 USART1 的 RXD。并配置了 USART1 的参数包括波特率、数据位长度、停止位数、校验位、硬件流控制和工作模式。
/*********************************************************************Function : USART1初始化Parameter : bound : 波特率 Return : N/A
**********************************************************************/
void usart1_init(uint32_t bound)
{GPIO_InitTypeDef GPIO_InitStructure; // 定义 GPIO 初始化结构体USART_InitTypeDef USART_InitStructure; // 定义 USART 初始化结构体NVIC_InitTypeDef NVIC_InitStructure; // 定义 NVIC 初始化结构体/* 时钟使能启用 USART1 和 GPIOA 的时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);/* 引脚复用配置 */ // 配置 PA9 为复用推挽输出用于 USART1 的 TXDGPIO_InitStructure.GPIO_Pin GPIO_Pin_9; // 设置 GPIO 端口GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; // 设置 GPIO 速度GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; // 设置 GPIO 模式为复用推挽GPIO_Init(GPIOA, GPIO_InitStructure); // 初始化 GPIO// 配置 PA10 为浮空输入用于 USART1 的 RXDGPIO_InitStructure.GPIO_Pin GPIO_Pin_10; // 设置 GPIO 端口GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; // 设置 GPIO 模式为浮空输入GPIO_Init(GPIOA, GPIO_InitStructure); // 初始化 GPIO/* NVIC 中断配置 */ NVIC_InitStructure.NVIC_IRQChannel USART1_IRQn; // 设置中断通道为 USART1NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 3; // 设置抢占优先级为3NVIC_InitStructure.NVIC_IRQChannelSubPriority 3; // 设置子优先级为3NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; // 使能中断通道NVIC_Init(NVIC_InitStructure); // 初始化 NVIC/* USART1 配置 */ USART_InitStructure.USART_BaudRate bound; // 设置波特率USART_InitStructure.USART_WordLength USART_WordLength_8b; // 设置数据位长度为8位USART_InitStructure.USART_StopBits USART_StopBits_1; // 设置停止位为1位USART_InitStructure.USART_Parity USART_Parity_No; // 设置校验位为无校验USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; // 设置硬件流控制为无USART_InitStructure.USART_Mode USART_Mode_Rx | USART_Mode_Tx; // 设置工作模式为接收和发送USART_Init(USART1, USART_InitStructure); // 初始化 USART1/*中断配置*/USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开接受中断 USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //开空闲中断USART_ITConfig(USART1,USART_IT_TXE,ENABLE); //开发送中断 USART_Cmd(USART1, ENABLE); //启用USART1USART_DataTypeStr.Usart_Tc_State SET; //置位发送允许标志
}3USART数据发送函数 USART1_Send_Data
初始化PD14端口并为推挽输出。
/*********************************************************************Function : USART数据发送函数Parameter : Data 要发送的数据缓存.Lenth 发送长度Return : 发送状态 1 失败 0 成功
**********************************************************************/
char USART1_Send_Data(char* Data,uint8_t Lenth)
{uint8_t uNum 0;if(USART_DataTypeStr.Usart_Tc_State 1) //判断发送标志位是否置1{USART_DataTypeStr.Usart_Tc_State 0; //将发送标志位清零表示数据已经成功放入缓存等待发送USART_DataTypeStr.Usart_Tx_Len Lenth; //获取需要发送的数据的长度 for(uNum 0;uNum USART_DataTypeStr.Usart_Tx_Len;uNum ) //将需要发送的数据放入发送缓存{USART_DataTypeStr.Usart_Tx_Buffer[uNum] Data[uNum];}USART_ITConfig(USART1,USART_IT_TXE,ENABLE); //数据放入缓存后打开发送中断数据自动发送}return USART_DataTypeStr.Usart_Tc_State; //返回放数据的状态值为1表示发送失败为0表示发送成功了
} 4USART数据发送函数 USART1_IRQHandler(
/*********************************************************************Function : USART1中断服务函数Parameter : N/A Return : N/A
**********************************************************************/
void USART1_IRQHandler(void)
{uint8_t Clear Clear; // 定义清除标志的变量并初始化为自身static uint8_t uNum 0; // 静态变量用于循环计数if(USART_GetITStatus(USART1,USART_IT_RXNE) ! RESET) // 判断读数据寄存器是否为非空{USART_ClearFlag(USART1, USART_IT_RXNE); // 清零读数据寄存器其实硬件也可以自动清零USART_DataTypeStr.Usart_Rx_Buffer[USART_DataTypeStr.Usart_Rx_Num ] \(uint16_t)(USART1-DR 0x01FF); // 将接收到的数据存入接收缓冲区(USART_DataTypeStr.Usart_Rx_Num) 0xFF; // 防止缓冲区溢出} else if(USART_GetITStatus(USART1,USART_IT_IDLE) ! RESET) // 检测空闲{Clear USART1 - SR; // 读SR位Clear USART1 - DR; // 读DR位USART_DataTypeStr.Usart_Rx_Len USART_DataTypeStr.Usart_Rx_Num; // 获取数据长度for(uNum 0; uNum USART_DataTypeStr.Usart_Rx_Len; uNum ) {USART_DataTypeStr.Usart_Rx_Data[uNum] USART_DataTypeStr.Usart_Rx_Buffer[uNum]; // 将接收到的数据复制到接收数据缓冲区}USART_DataTypeStr.Usart_Rx_Num 0; // 清空接收计数器USART_DataTypeStr.Usart_Rc_State 1; // 数据读取标志位置1读取串口数据}if(USART_GetITStatus(USART1,USART_IT_TXE) ! RESET) // 判断发送寄存器是否为非空{USART1-DR \((USART_DataTypeStr.Usart_Tx_Buffer[USART_DataTypeStr.Usart_Tx_Num ]) (uint16_t)0x01FF); // 发送数据(USART_DataTypeStr.Usart_Tx_Num) 0xFF; // 防止缓冲区溢出if(USART_DataTypeStr.Usart_Tx_Num USART_DataTypeStr.Usart_Tx_Len){ USART_ITConfig(USART1,USART_IT_TXE,DISABLE); // 发送完数据关闭发送中断USART_DataTypeStr.Usart_Tx_Num 0; // 清空发送计数器USART_DataTypeStr.Usart_Tc_State 1; // 发送标志置1可以继续发送数据了} }}5定时器5通道1输入捕获配置函数 TIM5_Cap_Init(uint16_t arr,uint16_t psc)
/*********************************************************************Function : 定时器5通道1输入捕获配置Parameter : arr自动重装值。psc时钟预分频数Return : N/A
**********************************************************************/
void TIM5_Cap_Init(uint16_t arr,uint16_t psc)
{ GPIO_InitTypeDef GPIO_InitStructure; // GPIO初始化结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 定时器时间基准初始化结构体TIM_ICInitTypeDef TIM5_ICInitStructure; // 定时器输入捕获初始化结构体NVIC_InitTypeDef NVIC_InitStructure; // 中断向量表初始化结构体/* 时钟使能 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // 使能TIM5的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA的时钟/* 端口配置 */GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; // 使用PA0引脚 GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; // 上拉输入 GPIO_Init(GPIOA, GPIO_InitStructure); // 初始化GPIOAGPIO_SetBits(GPIOA,GPIO_Pin_0); // 上拉/* TIM配置 */ TIM_TimeBaseStructure.TIM_Period arr; // 自动重装值 TIM_TimeBaseStructure.TIM_Prescaler psc; // 时钟预分频器 TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; // 时钟分频TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; // 向上计数TIM_TimeBaseInit(TIM5, TIM_TimeBaseStructure); // 初始化TIM5输入捕获/* 输入捕获配置 */ TIM5_ICInitStructure.TIM_Channel TIM_Channel_1; // IC1映射到TI1上TIM5_ICInitStructure.TIM_ICPolarity TIM_ICPolarity_Falling; // 下降沿捕获TIM5_ICInitStructure.TIM_ICSelection TIM_ICSelection_DirectTI; // 映射到TI1TIM5_ICInitStructure.TIM_ICPrescaler TIM_ICPSC_DIV1; // 不分频 TIM5_ICInitStructure.TIM_ICFilter 0x00; // 不滤波TIM_ICInit(TIM5, TIM5_ICInitStructure); // 初始化TIM5输入捕获/* NVIC 配置 */NVIC_InitStructure.NVIC_IRQChannel TIM5_IRQn; // 中断向量表为TIM5NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; // 先占优先级2NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; // 从优先级0NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; // 使能中断NVIC_Init(NVIC_InitStructure); // 初始化NVIC/* 允许中断 */TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE); // 允许更新中断、CC1IE捕获中断 /* 使能TIMx */TIM_Cmd(TIM5,ENABLE);
} 6定时器5通道1输入捕获配置函数 TIM5_Cap_Init(uint16_t arr,uint16_t psc) /*********************************************************************Function : 定时器5中断服务程序 Parameter : N/AReturn : N/A
**********************************************************************/
void TIM5_IRQHandler(void)
{ if((TIM5CH1_CAPTURE_STA0X80)0) // 检查是否成功捕获{ if (TIM_GetITStatus(TIM5,TIM_IT_Update)! RESET) { if(TIM5CH1_CAPTURE_STA0X40) // 如果已经捕获到低电平{if((TIM5CH1_CAPTURE_STA0X3F)0X3F) // 检查低电平是否太长{TIM5CH1_CAPTURE_STA|0X80; // 标记成功捕获了一次TIM5CH1_CAPTURE_VAL0XFFFF; // 设置捕获值为最大值}elseTIM5CH1_CAPTURE_STA; // 低电平时间累加} }if (TIM_GetITStatus(TIM5, TIM_IT_CC1) ! RESET) // 捕获1发生捕获事件{ if(TIM5CH1_CAPTURE_STA0X40) // 如果已经捕获到一个上升沿 { TIM5CH1_CAPTURE_STA|0X80; // 标记成功捕获到一次低电平脉宽TIM5CH1_CAPTURE_VALTIM_GetCapture1(TIM5); // 记录捕获值TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); // 设置为下降沿捕获}else // 如果还未开始第一次捕获下降沿{TIM5CH1_CAPTURE_STA0; // 清空捕获状态TIM5CH1_CAPTURE_VAL0; // 清空捕获值TIM_SetCounter(TIM5,0); // 清空定时器计数器TIM5CH1_CAPTURE_STA|0X40; // 标记捕获到了下降沿TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); // 设置为上升沿捕获} } }TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); // 清除中断标志位
}3、宏定义
步骤1主函数添加所需的头文件主源文件部分报错消失
//头文件包含
/*************SYSTEM*****************/
/*#include .\sys\sys.h*/
#include .\delay\delay.h
#include .\usart\usart.h
#include .\timer\timer.h
#include .\input\input.h/***********Hardweare***************/
#include led.h 步骤2添加函数声明 uint32_t temp0; delay_init(); //启动滴答定时器usart1_init(9600); //USART1初始化LED_Init(); //板载LED初始化SystemTinerInit(1000-1,7200-1); //系统时间初始化 定时100msTIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数printf(初始化成功\r\n);步骤2添加中断源文件所需的头文件
#include stm32f10x_tim.h
#include stm32f10x_rcc.h
#include stm32f10x_gpio.h
#include misc.h
#include .\input\input.huint8_t TIM5CH1_CAPTURE_STA0; //输入捕获状态
uint16_t TIM5CH1_CAPTURE_VAL; //输入捕获值步骤3添加串口通信宏定义
#define USART_RX_LEN 200 // 接收缓冲区最大长度
#define USART_TX_LEN 200 // 发送缓冲区最大长度
#define UART_NUM 10 // 串口结构体最大对象数量步骤4添加函数声明
void usart1_init(uint32_t bound);
extern USART_DataTypeDef USART_DataTypeStr;
char USART1_Send_Data(char* Data,uint8_t Lenth);步骤5添加数据类型和宏的头文件
//定义串口数据结构体
typedef struct USART_DataType
{uint8_t Usart_Rx_Len; // 接收缓冲区长度uint8_t Usart_Tx_Len; // 发送缓冲区长度uint8_t Usart_Rx_Num; // 接收数据计数uint8_t Usart_Tx_Num; // 发送数据计数uint8_t Usart_Rc_State; // 接收状态标志位uint8_t Usart_Tc_State; // 发送状态标志位char Usart_Rx_Buffer[USART_RX_LEN]; // 接收缓冲区char Usart_Tx_Buffer[USART_TX_LEN]; // 发送缓冲区char Usart_Rx_Data[USART_RX_LEN]; // 接收数据char Usart_Tx_Data[USART_TX_LEN]; // 发送数据
} USART_DataTypeDef;步骤6定义一个串口数组变量
USART_DataTypeDef USART_DataTypeStr{0};输入捕获头文件编辑
步骤1创建一个宏定义保护
#ifndef __INPUT_H_
#define __INPUT_H_#endif步骤2添加函数声明
//函数声明
void TIM5_Cap_Init(uint16_t arr,uint16_t psc);步骤3添加数据类型和宏的头文件
#include stdint.h extern uint8_t TIM5CH1_CAPTURE_STA;
extern uint16_t TIM5CH1_CAPTURE_VAL; 4、知识链接
1输入捕获基础知识 2输入捕获通俗理解
输入捕获就像是在厨房里用计时器来测量不同食材烹饪的时间。比如你可以用计时器来记录水煮沸的时间、面团发酵的时间或者烤箱中食物的烹饪时间。这样你就可以根据时间来控制不同的烹饪过程确保食物煮熟或者烤熟得恰到好处。输入捕获就像是厨房里的计时器一样可以帮助你测量外部信号的特征比如脉冲宽度、频率或时间间隔用于控制和监测不同的烹饪过程。
5、工程测试