实验三:自行车码表

实验器材

硬件

  • STM32F103 核心板一块;
  • microUSB线一根;
  • STLink板一块;
  • USB to TTL一个;
  • PCWindows/MacOS/Linux)一台;
  • 杜邦线若干;
  • 面包板一块

软件

  • STM32CubeMX
  • Keil uVision4
  • STLink串口驱动;
  • USB to TTL驱动;
  • PC上的串口终端软件putty
实验步骤

1、下载并配置STM32CubeMX

              (1)下载STM32CubeMX。

              (2)打开软件,出现如图的界面。

              (3)点击“New Project”,并按照如图进行选择。

              (4)点击“OK”,出现下图的界面。

5)选择“Project”——“GenerateCode”,在弹出的设置框中填入项目名称和保存路径。

              (6)点击“ok“,出现如下警告框,缺少依赖,点击”Yes“开始下载并自动安装。

(7)等待下载完成,点击“OK”,就完成了STM32CubeMX的流程。

 

2、下载并安装Keil uVision4

 

3、下载并安装STLink-V2驱动

 

4、下载并安装USB to TTL驱动

 

5、小灯闪烁尝试

              (1)根据1中的步骤新建工程,由于依赖包已经下载成功,新建工程后会出现如下提示,表示生成成功。

              (2)点击“Open Project”,发现还有需要下载的依赖包,下载好之后,看到生成的代码界面,如图。

       (3)在main函数中调用GPIO初始化函数后会持续输出高电平。为了使小灯闪烁,需要交替输出高低电平。代码如下:

              (4)选择“Project”——“Build Target”或F7编译代码。

              (5)选择“Flash”——“Download”或F8将代码下载到板子上。如图连接好板子后会看到小灯闪烁。

ST-Link和STM32板子连接方法:

3.3V——3.3V

GND——GND

SWDIO  ——DIO

SWCLK  ——DCLK


     6、实验连线

USB to TTL和STM32:

3.3V——3.3V

GND——GND

ST-Link和STM32:

3.3V——3.3V

GND——GND

SWDIO  ——DIO

SWCLK  ——DCLK


7、准备工作

stm32f1xx_hal_conf.h中解除对PWRTIMUART模块宏定义的注释



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

1)如图,在芯片中设置四个串口,PA9TXPA10RXPA11PA12是输入(按钮).

              (2)将左侧的配置中USART1的模式更改为Single Wire(Half-Duplex)

              (3)生成代码,并写下如下代码:

其中HAL_UART_Transmit有4个参数,第一个参数是串口的句柄,第二个参数是一个二进制数组(char*),第三个参数是要发送的数据长度,第四个是发送超时的判定时间。

              (4)编译并下载代码

              (5)打开putty,设置串口,打开终端查看串口输出信息。

9、通过面包板在PA11PA12各连接一个按钮开关到地;

 

10、编写Cube程序,配置PA11PA12为内部上拉到输入模式,在main()函数循环检测PA11按钮按下,并在按钮按下时在串口输出“Pressed”

1)如图,修改代码

主程序做如下修改:

即在PA11端口检测到低电平时输出一个“Pressed”。

       (2)编译并下载。

       (3)通过终端查看结果

我发现的确实现了按一下按钮输出一个“Pressed”的效果,但偶尔会出现按一下输出两次的情况,这应该是由于没有对按键执行去抖动操作。

 

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

       (1)修改main.c

/*Includes ------------------------------------------------------------------*/

#include"stm32f1xx_hal.h"

 

/*USER CODE BEGIN Includes */

#defineMAX_BITCOUNT 0xff

#definePERIMETER 1.8       //unit: meter

/*USER CODE END Includes */

 

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

UART_HandleTypeDefhuart1;

 

/*USER CODE BEGIN PV */

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

 

/*USER CODE END PV */

 

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

voidSystemClock_Config(void);

staticvoid MX_GPIO_Init(void);

staticvoid MX_USART1_UART_Init(void);

voidUART0_Init(void);

voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

voidTIM3_IRQHandler(void);

voidTIM_Init(void);

/*USER CODE BEGIN PFP */

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

 

/*USER CODE END PFP */

 

/*USER CODE BEGIN 0 */

 

intbitcount, state = 0;

intPA11_Count, PA11_Flag;

intPA12_Count, PA12_Flag;

intTIM_Count, TIM_Flag;

intdist[5] = {0};

UART_HandleTypeDefUartHandle;

TIM_HandleTypeDefTIM_Handle;

TIM_ClockConfigTypeDefsClockSourceConfig;

TIM_MasterConfigTypeDefsMasterConfig;

voidanti_jitter(int *bitcount, int state);

/*USER CODE END 0 */

 

intmain(void)

{

 

  /* USER CODE BEGIN 1 */

   

  /* USER CODE END 1 */

 

  /* MCUConfiguration----------------------------------------------------------*/

 

  /* Reset of all peripherals, Initializes theFlash 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 */  

    bitcount = MAX_BITCOUNT;

   

    UART0_Init();

    TIM_Init();

  /* USER CODE END 2 */

 

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

       int len, TIM_Len;

       char str[32], TIM_Str[32];

      

       PA11_Flag = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);

       anti_jitter(&bitcount, PA12_Flag);

      

       if(!PA11_Flag)

       {

           state = 1 - state;

           HAL_UART_Transmit(&UartHandle,(uint8_t*)"Pressed.\r\n", 10, 500);

       }

      

       if(TIM_Flag)

       {

           TIM_Flag = 0;

           TIM_Count++;

          

           if(state == 0) len = sprintf(str,"Distance: %.2f meters\r\n", PA12_Count * PERIMETER);

           else len = sprintf(str, "Speed:%.2f m/s\r\n", (PA12_Count - dist[TIM_Count % 5])* PERIMETER);

           HAL_UART_Transmit(&UartHandle,(uint8_t*)str, len, 500);

           dist[TIM_Count % 5] = PA12_Count;

       }

      

       if(bitcount)

       {

           PA12_Flag = 0;

       }

      

       HAL_Delay(100);

  }

  /* USER CODE END 3 */

 

}

 

/**System Clock Configuration

*/

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

voidMX_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

*/

voidMX_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_InitStruct.Mode = GPIO_MODE_INPUT;

  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_NOPULL;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

 

voidanti_jitter(int *bitcount, int state){

    *bitcount <<= 1;

    *bitcount &= MAX_BITCOUNT;

    *bitcount += state & 1;

}

 

voidUART0_Init(void)

{

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

}

 

voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

    if(GPIO_Pin == GPIO_PIN_12)

    {

       PA12_Flag = 1;

       PA12_Count++;

    }else

    {

       UNUSED(GPIO_Pin);

    }

}

 

 

voidTIM3_IRQHandler(void)

{

    HAL_TIM_IRQHandler(&TIM_Handle);

}

 

voidTIM_Init(void)

{

    TIM_Handle.Instance = TIM3;

    TIM_Handle.Init.Prescaler = 8000;

    TIM_Handle.Init.CounterMode =TIM_COUNTERMODE_UP;

    TIM_Handle.Init.Period = 199;

    sClockSourceConfig.ClockSource =TIM_CLOCKSOURCE_INTERNAL;

    sMasterConfig.MasterOutputTrigger =TIM_TRGO_RESET;

    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(TIM3_IRQn);

    HAL_TIM_Base_Init(&TIM_Handle);

    HAL_TIM_Base_Start_IT(&TIM_Handle);

}

 

voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){

    TIM_Flag = 1;

}

 

/*USER CODE END 4 */

 

#ifdefUSE_FULL_ASSERT

 

/**

   * @brief Reports the name of the source fileand the source line number

   * where the assert_param error has occurred.

   * @param file: pointer to the source filename

   * @param line: assert_param error linesource number

   * @retval None

   */

voidassert_failed(uint8_t* file, uint32_t line)

{

  /* USER CODE BEGIN 6 */

  /* User can add his own implementation toreport 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


计算瞬时速度采用1s内的平均速度来计算:

(PA12_Count- dist[TIM_Count % 5])* PERIMETER)

dist[TIM_Count% 5] = PA12_Count

              (2)在stm32f1xx_hal_msp.c中增加如下代码:

              (3)在stm32f1xx_it.c中增加如下代码:

              (4)通过终端查看输出结果

每按一次PA12会增加一圈的距离(1.8米),按下PA11时输出“Pressed.”并切换显示模式到输出速度,再按一次PA11输出“Pressed.”并切换显示模式到输出路程。

每隔0.2s会输出一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值