您的位置:首页 > 运维架构 > Linux

自行车码表

2016-06-15 20:47 477 查看
一、      实验目的和要求

1.    理解MCU上电启动过程;

2.    掌握使用Cube库来编写STM32裸机程序的方法;

3.    掌握使用Cube库来编写GPTO和UART程序的方法;

4.    掌握使用Cube库来编写中断响应程序的方法;

5.    理解前后台程序模式

6.    掌握在STM32F103上编写裸机程序并下载运行的方法。

 

二、      实验器材

1.    STM32F103核心板一块;

2.    MicroUSB线一根;

3.    STLink板或USB串口板一块;

4.    交叉编译软件

 

三、      实验内容和原理

1.编写Cube程序,配置UART0为9600,8n1,上电后向串口输出“Hello”,在PC上通过串口软件观察结果

2.通过面包板在PA11和PA12各连接一个按钮开关到地

3.编写Cube程序,配置PA11和PA12为内部上拉到输入模式,在main()函数循环检测PA11按钮按下,并在按钮按下时在串口输出Pressed。

4.编写Cube程序,配置PA12下降沿触发中断,程序中设置两个全局变量,一个为计数器,一个为标识。当中断触发时,计数器加1,并设置标识。在主循环中判断标识,如果标识置位则清除标识并通过串口输出计数值;

5.编写Cube程序,开启定时器为200ms中断一次,中断触发时设置标识,主循环根据这个标识来做串口输出(取消4的串口输出);

6.编写完整的码表程序,PA12的按钮标识车轮转了一圈,通过计数器可以得到里程,通过定时器中断得到的时间可以计算出速度;PA的按钮切换模式,模式一在串口输出里程,模式二在串口输出速度。

四、      实验过程和数据记录

1.    下列图片为实物连接图



其中串口使用PA9,PA10;GPIO使用PA11,PA12,分别连接按钮。黑线接地。

 

2.    在Cube软件中配置UART0的波特率为9600, 8n1,然后向串口输出Hello,通过Mac上的串口软件观察结果。

a.    下图为配置图片,将波特率设置为9600,8n1.





b.    配置完成后,我们就可以用HAL_UART_Transmit和HAL_UART_Receive两个函数来进行串口的收发数据。使用GNUC需要重写__io_putchar和fputc函数,我们通过宏定义来完成。



c.    测试串口输出,在while循环前添加printf函数来输出Hello



d.    下面是实验结果展示图



3.    编写Cube程序,配置PA11和PA12为内部上拉到输入模式,在main()函数循环检测PA11按钮按下,并在按钮按下时在串口输出Pressed
a.    首先配置PA11和PA12为内部上拉到输入模式,如下图所示





 

b.    在while循环中写出如果按下按钮,则在串口输出Pressed字样,循环代码如下图所示



c.    下面是输出图示



4.    编写Cube程序,配置PA12下降沿触发中断,程序中设置两个全局变量,一个为计数器,一个为标识。当中断触发时,计数器加1,并设置标识。在主循环中判断标识,如果标识置位则清除标识并通过串口输出计数值
a.    配置PA12下降沿触发中断,配置过程如下







b.    设置两个全局变量stopwatch_counter和stopwatch_flag,并且实现HAL_GPIO_EXTI_Callback(unit16_tGPIO_Pin)函数,函数实现如下



c.    在while循环中,通过判断全局变量stopwatch_flag的值,来判断中断是否发生,代码实现如下



d.    成功编译之后下载到板子上,运行结果如下图所示


 

5.    编写Cube程序,开启定时器为200ms中断一次,中断触发时设置标识,主循环根据这个标识来做串口输出(取消4的串口输出)

a.    配置时钟信息如下







b.    实现HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数,用来设置标识符



c.    在main函数初始化定时器,并且根据stopwatch_flag来判断中断是够发生。实现代码如下



d.    在串口软件监测到如下结果



 

6.    编写完整的码表程序,PA12的按钮标识车轮转了一圈,通过计数器可以得到里程,通过定时器中断得到的时间可以计算出速度;PA的按钮切换模式,模式一在串口输出里程,模式二在串口输出速度。

a.    在计算速度和里程的过程中,里程默认中断一次为1m,速度计算公式为stopwatch_mile*18/stopwatch_time,stopewatch_time为添加的全局变量,表示定时器的中断次数。

b.    完整代码如下

/**

  ******************************************************************************

  * 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 ---------------------------------------------------------*/

TIM_HandleTypeDef htim2;

 

UART_HandleTypeDef huart1;

 

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

 

int stopwatch_counter;

int stopwatch_flag;

int stopwatch_time;

int stopwatch_mode;

 

/* USER CODE END PV */

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_USART1_UART_Init(void);

static void MX_TIM2_Init(void);

 

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

#ifdef __GNUC__

/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf

   set to 'Yes') calls __io_putchar() */

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif /* __GNUC__ */

 

/* USER CODE END PFP */

 

/* USER CODE BEGIN 0 */

 

/* 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();

  MX_TIM2_Init();

 

  /* USER CODE BEGIN 2 */

            GPIO_PinState key;

            HAL_TIM_Base_Start_IT(&htim2);

            printf("Hello\n\r");

           

            double mile = 0;

            double speed = 0;

           

 

  /* USER CODE END 2 */

 

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

           

  while (1)

  {

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

                       

                        key = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);

                        if (key == GPIO_PIN_RESET)

                        {

                                    stopwatch_mode = !stopwatch_mode;

                        }

                        if (stopwatch_flag == 1)

                        {

                                    stopwatch_flag = 0;

                                   

                                    mile = stopwatch_counter * 1;

                                    if (stopwatch_mode == 0)

                                    {

                                                printf("Current Mile: %f\n\r", mile);

                                    }

                                    else

                                    {

                                                speed = stopwatch_counter  / stopwatch_time;

                                                printf("Current Speed: %1f\n\r", speed);

                                    }

                        }

                        HAL_Delay(100);

                       

 

  }

  /* 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);

}

 

/* TIM2 init function */

void MX_TIM2_Init(void)

{

 

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

 

  htim2.Instance = TIM2;

  htim2.Init.Prescaler = 8000;

  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim2.Init.Period = 199;

  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  HAL_TIM_Base_Init(&htim2);

 

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

 

}

 

/* USART1 init function */

void MX_USART1_UART_Init(void)

{

 

  huart1.Instance = USART1;

  huart1.Init.BaudRate = 9600;

  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_UART_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 pin : PA11 */

  GPIO_InitStruct.Pin = GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

  /*Configure GPIO pin : PA12 */

  GPIO_InitStruct.Pin = GPIO_PIN_12;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

  /* EXTI interrupt init*/

  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

 

}

 

/* USER CODE BEGIN 4 */

PUTCHAR_PROTOTYPE

{

  /* Place your implementation of fputc here */

  /* e.g. write a character to the USART1 and Loop until the end of transmission */

  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

 

  return ch;

}

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

            if (GPIO_Pin == GPIO_PIN_12)

            {

                        stopwatch_counter += 1;

//                      stopwatch_flag = 1;

            }

}

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

            if (htim->Instance == TIM2)

            {

                        stopwatch_flag = 1;

                        stopwatch_time += 1;

            }

           

}

 

 

/* 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****/

c.    下面是实验结果图展示



 

7.    扩展内容

a.    扩展内容由于工程具有完整性,故统一完成如下

b.    Main函数中代码较为简单,为休眠操作,由于SysTick中断也会终止休眠,故应该关掉中断。

int main(void)

{

  HAL_Init();

 

  /* Configure the system clock */

  SystemClock_Config();

 

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_USART1_UART_Init();

  MX_TIM2_Init();

 

  /* USER CODE BEGIN 2 */

            GPIO_PinState key;

            HAL_TIM_Base_Start_IT(&htim2);

            printf("Hello\n\r");

           

  /* USER CODE END 2 */

  while (1)

  {

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

                       

                        HAL_SuspendTick();

                        __HAL_RCC_PWR_CLK_ENABLE();

                        HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

                        HAL_ResumeTick();

  }

  /* USER CODE END 3 */

 

}

c.    下面是中断处理函数的修改

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

           

           

            double mile = 0;

            double speed = 0;

           

           

            if (htim->Instance == TIM2)

            {

//                      stopwatch_flag = 1;

                        stopwatch_time += 1;

                       

                        mile = stopwatch_counter*1;

                        if (stopwatch_mode == 0)

                        {

                                    printf("Current Mile: %f\n\r", mile);

                        }

                        else

                        {

                                    speed = (double)stopwatch_counter / stopwatch_time;

                                    printf("Current Speed: %1f\n\r", speed);

                        }

            }

           

}

           

d.    下面是实验结果图



可以看出和之前实验的输出结果相类似,实验成功。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  嵌入式系统 linux