USB | STM32 |
---|---|
3.3V | 3.3V |
GND | GND |
TXD | A10 |
RXD | A9 |
- stm32和st-link直接按照对应的接口相连即可
开始之前记得一定要先将驱动都安装好!
进入STM32 CubeMX之后就可以使用了,我们选择STM32F103 - LQFP48 - 64Flash - 20RAM(老师提供的板子)进行配置。
STM32F103只是一块板子,我们先需要对板子进行简单的设计,比如哪个引脚做输入,哪个引脚做输出等等,直接使用STM32实现自行车里程计可能会出现一些完全想不到的错误,实现一些简单的功能对所用的器件进行简单测试(譬如是不是能正常工作的)。
由于我们使用的板子是STM32F103,直接使用CubeMX会去下载这个库,但是它自己下载速度超级慢,这里可以使用浏览器下载到1.3.0版本的库,然后使用CubeMX下一个补丁就可以了,速度会快很多。
然后Project->Settings修改工程设置,将Toolchain修改成MDK-ARM V5(否则默认是EWARM),这样我们之后才可以使用Keil进行项目管理。最后,Project -> Generate Code即可生成代码。
使用上面的工具 设置好引脚之后就可以开始写代码了,直接在CubeMX中选择OpenProject就可以打开工程文件。
将ST-LINK与STM32对应的借口连起来,然后调好设置:Flash->Configure Flash Tools->Debug->Settings查看连接是否正确,连接成功将如下图所示。
使用Keil生成HEX文件然后利用ST-LINK烧录进STM32中,需要在Flash->Configure Flash Tools->Output中勾选Create HEX File选项,如下图所示。其实不使用ST-LINK Unity,直接使用Keil也是能够烧录下板的,但是需要使用Patch Installer下载一个Algorithm,下载速度特别慢,因此这里还是使用生成HEX文件再利用ST-LINK Unity进行烧录的方法。
小灯在成功点亮之后说明杜邦线和小灯都是正常的(否则小灯可能就是坏的,或者线是坏的,只是极有可能的,我们连续测了三个小灯全是坏的,开始还以为是烧录少错了,查了好久,换成蜂鸣器做测试的时候居然响了。。。)。然后就可以使用面包板给小灯串联一个按钮,检测按钮和面包板的好坏,盒子里的器材中,我们又检测出一个按钮是坏的(按与不按小灯都会有信号)。
我们之前对A9进行了设置,这个在工程中的main.c函数内有具体的体现。
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct; //定义初始化结构
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9; //对端口9进行初始化
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
}
自己写代码实现小灯闪烁
while(1) {
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_9); //转换A9的输出状态
HAL_Delay(1000);
}
至此,我们实现使用STM32开发板完成了闪烁小灯的任务,通过以上的步骤,可以将所有的坏的元器件过滤掉,避免之后的bug大串联到焦头烂额,并且整体跑通了STM32开发的流程,之后的开发按照这个模板来就可以了。
将PA9,PA10设置为串口通信用的TX和RX(对应接法已经在上面的表格中表达出来了),注意要在CubeMX中将USART1设置为半双工(Cortex-M3的单线程半双工模式),将PA12和PA11设为Input,我们将两个按钮分别接到这两个引脚和GND,这样芯片可以根据两个引脚的输入进行交互。
线路连接
原谅我这鬼畜的波浪线,如图所示,直接将两个USB口全部接到电脑上,就可以不用重复的插拔插拔了(共用了电源线)。A11,A12分别接上两个button用来监测按钮的状态,将A11,A12内部设置为上拉到输入模式(接一个上拉电阻),在main()函数内进行循环检测,并在其中一个按钮按下时,输出两个按钮的状态信息。
按键已经去抖动,上方是按键状态后得到的输出。
main.c中进行修改
/*-------------------------------main.c------------------------------------*/
//....
void UART0_Init(UART_HandleTypeDef* UartHandle){
UartHandle->Instance = USART1;
UartHandle->Init.BaudRate = 9600;
UartHandle->Init.WordLength = UART_WORDLENGTH_8B;
UartHandle->Init.StopBits = UART_STOPBITS_1;
UartHandle->Init.Parity = UART_PARITY_NONE;
UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle->Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(UartHandle); //初始化UART
}
//根据输入对给定的端口进行初始化,设置波特率等等
#define MASK 0xFF
//给按钮去抖动检测的长度(8bit)
void anti_jitter(int *bit, int state)
{
*bit <<= 1;
*bit&= MASK;
*bit|=state;
}
//按钮不只是在开合的时候会有抖动,不按下的时候线路都会时断时续,所以去抖动一定要加上
int main(void)
{
//...
char str[30];
int Pin_11_Bitcount = 0,Pin_12_Bitcount=0;
int Pin_11_State=0,Pin_12_State=0;
int Change_Flag=1;
UART_HandleTypeDef UartHandle;
UART0_Init(&UartHandle);
//设置变量,并对UART0进行初始化
HAL_UART_Transmit(&UartHandle, (uint8_t*)"Hello, World!\r\n", 16, 500);
//在Reset之后立刻向串口输出信息Hello, World! 这里记得要加入\r\n,否则输出的全是糊的
while(1)
{
int count;
GPIO_PinState state_11;
GPIO_PinState state_12;
state_11 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
state_12 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
//读取11、12的端口的状态,但是直接使用这些状态会有抖动的情况
HAL_Delay(5);
//延迟五秒用来延长读取状态的间隔,用来去抖动
anti_jitter(&Pin_11_Bitcount,state_11);
anti_jitter(&Pin_12_Bitcount,state_12);
//对两个端口去抖动,state_11,state_12是当下的状态,Pin_11,Pin_12是去抖动自后的真实状态
if(Pin_11_Bitcount != 0 && Pin_11_State == 0)
{
Pin_11_State = 1;
Change_Flag = 1;
}
if(Pin_12_Bitcount !=0 && Pin_12_State == 0)
{
Pin_12_State = 1;
Change_Flag = 1;
}
if(Pin_11_Bitcount == 0 && Pin_11_State == 1)
{
Pin_11_State = 0;
Change_Flag = 1;
}
if(Pin_12_Bitcount == 0 && Pin_12_State == 1)
{
Pin_12_State = 0;
Change_Flag = 1;
}
//当其中某一个端口的状态发生改变的时候设定Change_Flag标记,用来作为输出的标记
if(Change_Flag == 1)
{
Change_Flag = 0;
count = sprintf(str,"Pin 11:%d\r\n",Pin_11_State);
HAL_UART_Transmit(&UartHandle, (uint8_t*)str, count, 500);
count = sprintf(str,"Pin 12:%d\r\n",Pin_12_State);
HAL_UART_Transmit(&UartHandle, (uint8_t*)str, count, 500);
//向串口输出11和12端口的状态信息
}
}
}
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pins : PA11 PA12 */
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
//GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pull = GPIO_PULLUP;
//添加上拉电阻
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
在老师提供的攻略中需要在stm32f1xx_hal_msp.c中进行端口配置,但是使用CubeMX后生成的文件中已经做好了基本的配置,这里就可以不做额外的配置了,如果使用GCC进行裸配也是可以的,之前已经搭好了ARM的交叉编译环境,但是引脚的配置等等实在太繁琐了,这里还是使用CubeMX配置了。
/*---------------------------------main.c----------------------------------*/
TIM_HandleTypeDef T_Handler;
int T_Flag = 0;
int T_Count = 0;
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&T_Handler);
}
//攻略中说在msp中设定这个,但是由于在msp中没有办法传递参数,只能够用extern来做全局变量,用起来实在太奇怪,所以就干脆将相关的初始化函数全部搬到main.c中来写,感觉反而自然一些。
void TIM_Init()
{
T_Handler.Instance = TIM3;
T_Handler.Init.Prescaler = 8000;
T_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
T_Handler.Init.Period = 199;
//设定时间中断的参数,每8000唤醒回调一次,总共唤醒199次
HAL_TIM_Base_Init(&T_Handler);
HAL_TIM_Base_Start_IT(&T_Handler);
//初始化并启用时间中断的检测
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
T_Flag = 1;
}
//这个就是时间中断会调用的回调函数,每次调用就设置一次标记
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
UART_HandleTypeDef UartHandle;
UART0_Init(&UartHandle);
TIM_Init();
//初始化时间、端口
HAL_UART_Transmit(&UartHandle, (uint8_t*)"Hello, World!\r\n", 16, 500);
while (1)
{
int count;
if(T_Flag == 1) //每次时间标志被中断置位后,就计数一次,然后输出
{
T_Flag = 0;
T_Count++;
count = sprintf(str,"Time clicks: %d\r\n",T_Count);
HAL_UART_Transmit(&UartHandle,(uint8_t *)str,count,500);
}
}
}
//上面的函数完成了利用时间中断规律性计数
/*----------------------stm32f1xx_hal_msp.c---------------------------*/
//在HAL_MspInit函数中增加下面两条,用来设定时间中断的优先级以及时间中断的回调函数
HAL_NVIC_SetPriority(TIM3_IRQn,0,0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
//增加以下两条函数,用来在开始和关闭的时候启动和关闭时钟
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim)
{
__TIM3_CLK_ENABLE();
}
void HAL_TIME_Base_MspDeInit(TIM_HandleTypeDef* htim)
{
__TIM3_CLK_DISABLE();
}
上面使用了时间中断来对计数器不断累加
上方使用了时间中断,这里将PA11、PA12也改造成时间中断,使用下降沿唤醒中断,实现前后台系统的自行车里程计。总共有两个按钮对应两个端口,按钮1每次按下时表示自行车轮已经转过一圈,按钮2每次按下表示在两个不同的模式间切换(显示总路程还是显示平均速度)。由于STM32自带RESET键,这里就不添加RESET按钮清零了。使用时间中断的相关说明在上面解释了。
代码
/*---------------------------main.c-------------------------------------*/
/** ****************************************************************************** * File Name : main.c * Description : Main program body ****************************************************************************** * * COPYRIGHT(c) 2016 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
#define MASK 0xFF
#define DELAYTIME 5
#define SPDMODE 1
#define DISMODE 0
#define CHANGEMODE(M) (M = 1-M) //
#define Tire_Perimeter 2.3 //轮胎周长
char str[30];
int Pin_12_Count = 0,Pin_12_Flag = 0; //一个计数器,一个标记
TIM_HandleTypeDef T_Handler;
int mode=0;
float Distance = 0; //记录行驶总距离
int T_Flag = 0;
int T_Count = 0;
int Change_Mode_Flag = 0;
void UART0_Init(UART_HandleTypeDef* UartHandle){
UartHandle->Instance = USART1;
UartHandle->Init.BaudRate = 9600;
UartHandle->Init.WordLength = UART_WORDLENGTH_8B;
UartHandle->Init.StopBits = UART_STOPBITS_1;
UartHandle->Init.Parity = UART_PARITY_NONE;
UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle->Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(UartHandle);
}
//与前面的一样,对UART端口做初始化
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&T_Handler);
}
void TIM_Init()
{
T_Handler.Instance = TIM3;
T_Handler.Init.Prescaler = 8000*5;
T_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
T_Handler.Init.Period = 199;
HAL_TIM_Base_Init(&T_Handler);
HAL_TIM_Base_Start_IT(&T_Handler);
}
//上面对于时间中断的处理仍然一样,不过把间隔时间设为原来的5倍
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
T_Flag = 1;
T_Count++;
}
//后台时间中断处理,每次时间中断唤醒都会置标记, 前台while循环检测到之后对其进行处理
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_12) {
Distance+=Tire_Perimeter;
} else if(GPIO_Pin == GPIO_PIN_11)
{
Change_Mode_Flag = 1;
} else {
UNUSED(GPIO_Pin);
}
}
//后台处理引脚电平下降沿造成的中断,PA12用来记录里程的增加,PA11用来做模式改变的标记
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
char str[30];
int Pin_11_Bitcount = 0,Pin_12_Bitcount=0;
int Pin_11_State=0,Pin_12_State=0;
int Change_Flag=1;
UART_HandleTypeDef UartHandle;
UART0_Init(&UartHandle);
TIM_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_UART_Transmit(&UartHandle, (uint8_t*)"Hello, World!\r\n", 16, 500);
while (1)
{
int count;
/* USER CODE END WHILE */
//前台检测是否需要改变模式
if(Change_Mode_Flag == 1)
{
Change_Mode_Flag = 0;
CHANGEMODE(mode);
//根据不同的模式来显示状态,串口传送信息
if(mode == SPDMODE)
count = sprintf(str,"Changed Into Speed Mode\r\n");
else count = sprintf(str,"Changed into Distance Mode\r\n");
HAL_UART_Transmit(&UartHandle,(uint8_t *)str,count,500);
}
//前台检测到时间中断产生了,信息更新
if(T_Flag == 1)
{
T_Flag = 0;
//根据模式的不同串口传输不同的数据
if(mode == SPDMODE)
count = sprintf(str,"Speed : %f\r\n",Distance/T_Count);
else count = sprintf(str,"Distance : %f\r\n",Distance);
HAL_UART_Transmit(&UartHandle,(uint8_t *)str,count,500);
}
}
/* USER CODE END 3 */
}
/** System Clock Configuration */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_HalfDuplex_Init(&huart1);
}
/** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pins : PA11 PA12 */
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
#ifdef USE_FULL_ASSERT
/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/** * @} */
/** * @} */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/*------------------------------stm32f1xx_hal_msp.c-----------------------------*/
/** ****************************************************************************** * File Name : stm32f1xx_hal_msp.c * Description : This file provides code for the MSP Initialization * and de-Initialization codes. ****************************************************************************** * * COPYRIGHT(c) 2016 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/** * Initializes the Global MSP. */
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_AFIO_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
/* BusFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
/* UsageFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* USER CODE BEGIN MspInit 1 */
HAL_NVIC_SetPriority(EXTI15_10_IRQn,0,0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
HAL_NVIC_SetPriority(TIM3_IRQn,0,0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
//设置时间中断和引脚电平下降沿引发的中断,优先级
/* USER CODE END MspInit 1 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
/**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; //对引脚进行设置,使用下降沿触发
GPIO_InitStruct.Pull = GPIO_PULLUP; //上拉电阻
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
}
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
/* USER CODE BEGIN 1 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim)
{
__TIM3_CLK_ENABLE();
}
void HAL_TIME_Base_MspDeInit(TIM_HandleTypeDef* htim)
{
__TIM3_CLK_DISABLE();
}
/* USER CODE END 1 */
/** * @} */
/** * @} */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/*----------------------------stm32f1xx_it.c----------------------------*/
/** ****************************************************************************** * @file stm32f1xx_it.c * @brief Interrupt Service Routines. ****************************************************************************** * * COPYRIGHT(c) 2016 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "stm32f1xx.h"
#include "stm32f1xx_it.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/******************************************************************************/
/* Cortex-M3 Processor Interruption and Exception Handlers */
/******************************************************************************/
/** * @brief This function handles Non maskable interrupt. */
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/** * @brief This function handles Hard fault interrupt. */
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
}
/** * @brief This function handles Memory management fault. */
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 1 */
}
/** * @brief This function handles Prefetch fault, memory access fault. */
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 1 */
}
/** * @brief This function handles Undefined instruction or illegal state. */
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 1 */
}
/** * @brief This function handles Debug monitor. */
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/** * @brief This function handles System tick timer. */
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
void EXTI15_10_IRQHandler(void) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
}
//引脚引发的中断
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
上方使用了前后台的系统实现了自行车里程计,后台响应时间中断和按钮设置标记,前台根据标记进行处理并串口传送信号。