前期工作准备

Mac OS X + Windows 7虚拟机
安装STM32 ST-LINK Unity。用于烧录程序。
安装STM32 ST-LINK所需要的驱动
安装Keil UVision 5,这是IDE,可以生成Hex文件,也可以烧录到板子上。
安装USB-TTL所以需要的驱动。
安装PUTTY,Windows下查看串口。

器材准备

STM32F103板子一个
杜邦线、面包线若干
ST-LINK V2
USB-TTL
按钮两个、面包板两个

Hex文件生成

切换成MDK-ARM

一定要选择Reset and Run。Build选项: Create HEX File选项,如下图所示。其实不使用ST-LINK Unity,直接使用Keil也是能够烧录下板的,但是需要使用Patch Installer下载一个Algorithm,经常会出现各种bug,我和队友在这里都出现了很多问题,所以用ST-LINK烧录是一个不错的选择。

烧录程序示意

连接方式

打开选择将要烧录的文件,然后
1、Erase Chip 擦出所有数据
2、Program & Verify

串口通信

实验步骤

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

配置UART0

改动的代码

结果如图所示

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

连接面包板

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

去抖动,其中MASK为0xFF,说明采集的区间为0xFF。

void anti_jitter(int *bit, int state){*bit <<= 1;*bit&= MASK;*bit|=state;
}

处理思路如下:
当State == 1时表示接通。
当State == 2时表示断开。

anti_jitter(&Pin_11_Bitcount,state_11);
anti_jitter(&Pin_12_Bitcount,state_12);
//如果位不全为0,而且现在的状态为0,那么转化为断开。
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;
}
//如果状态发生改变,我们就观察一下PIN11和PIN12哪个是正常的。
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);
}

没有用Press。而是分别对两个按钮进行去抖动。观察是否有异常。

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

配置下降沿

配置中断

//定义两个全局变量int T_Flag = 0;
int T_Count = 0;//配置见上图void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_12) {T_FLAG = 1 ;} else {UNUSED(GPIO_Pin);}
}int main(void){
......while (1) {…int count;if (T_Flag==1) {T_Flag = 0;T_Count++;count = sprintf(str,"Pin 12:%d\r\n",Pin_12_State);HAL_UART_Transmit(&UartHandle, (uint8_t*)str, count, 500); }}
}

这一步的结果跟第三部没什么两样,所以图就不截了。

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

//定义两个全局变量int T_Flag = 0;
int T_Count = 0;void TIM_Init()
{T_Handler.Instance = TIM3;//时钟每1ms会被调用1次T_Handler.Init.Prescaler = 8000;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);
}
//在中断触发时
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{T_Flag = 1;
}
int main(void){
......total = 0; bitcount = MAX_BITCOUNT;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)}}
}

效果图如下所示

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

思路:PA11和PA12都采用时间中断,下降沿触发。PA11能够切换模式,PA12触发的时候则能够记录车子走了多少圈。而时钟中断能够帮助我们统计时间。所以我们在主循环只需要每隔相应的时间输出特定模式下距离的值和速度的值。上面两个子问题的全局变量。一个用于记录是否到达一个时钟周期。另一个用于记录总的距离之和。

测试距离

测试速度

/********************************************************************************* 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 3char 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;T_Count = 0;Distance = 0;mode = 0;HAL_UART_Init(UartHandle);
}void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&T_Handler);
}void TIM_Init()
{T_Handler.Instance = TIM3;//输出慢一点T_Handler.Init.Prescaler = 8000*10;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);
}
//时间中断回调
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{T_Flag = 1;T_Count++;
}
//PIN12和PIN11的回调
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);}
}/* 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****/

嵌入式 LAB 3:自行车码表相关推荐

  1. 基于51单片机自行车码表设计

    [毕设课设]基于51单片机自行车码表设计 ​效果图 Proteus仿真: 功能简介: 文件内容: 程序框架: 网盘链接: ​效果图 更多内容请关注@WENJIE电子科技 ​ 基于51单片机proteu ...

  2. 嵌入式中文输入法字码表

    a=啊阿吖嗄腌锕 ai=爱矮唉碍哀癌霭挨哎艾隘蔼锿嫒暧捱嗳嗌埃皑砹瑷 ae=哦噢 an=安暗按案岸俺鞍黯氨庵谙鹌铵犴桉揞埯胺 ang=昂肮盎 ao=傲熬遨鳌奥澳翱凹坳袄拗獒鏖骜廒媪聱敖螯嗷岙懊鏊 ah ...

  3. 《痞子衡嵌入式半月刊》 第 50 期

    痞子衡嵌入式半月刊: 第 50 期 这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期. 本期刊是开源项目(GitHub: JayHeng/pz ...

  4. Garmin Edge 1030 Plus GPS 骑行码表今日立减 300 美元

    Prime 会员日已全面生效,甚至山地自行车手和其他骑自行车的人也可以参加 Prime 会员日优惠 .Garmin Edge 1030 Plus自行车电脑在Prime Day的价格降至400美元,如果 ...

  5. 智能可穿戴平台,你更看好谁?

    随着可穿戴设备大潮来袭,众巨头纷纷布局可穿戴.6月,苹果发布了Healthkit平台,谷歌则发布了AndroidWare平台,日前,腾讯(微信)的智能硬件计划曝光.前两者从系统层面出发,都希望自己成为 ...

  6. 从 B 站火到 GitHub,国人开发者又一黑科技面世!

    点击上方"Github爱好者社区",选择星标 回复"资料",获取小编整理的一份资料月石一 发自 凹非寺本文经AI新媒体量子位(ID:QbitAI)授权转载,转载 ...

  7. c语言单片机停车场收费系统,基于51单片机停车场车位引导系统设计

    ?周明彬 曾伊玲 摘要:在很多人流量大的地方,因为车辆集中的情况,所以每次经过停车场时都需要工作人员来指挥车辆,告诉车主停车场那些地方还有空余车位可以泊车.所以很多地方的旧停车场使用的管理方式,是十分 ...

  8. 自制车速记录仪「GitHub 热点速览 v.21.31」

    作者:HelloGitHub-小鱼干 如果你有一辆普通的自行车,那么就可以使用下 X-TRACK 这个项目制作一个自己的测速器,记录你的行驶轨迹还有车速,体验一把硬件发烧友的乐趣.如果你有一个非 ma ...

  9. 基于单片机的压力流量报警器(附代码+仿真+论文)

    基于单片机的压力流量报警器(附代码+仿真+论文) **==完整论文+代码+仿真可关注我在主页私我==** 摘要 关键字 第一章绪论 1.1课题背景及其意义 1.2 国内外的研究状况 1.3本文的主要研 ...

  10. Edge 705试用

    Edge 705是早就听说过的玩意,特别是在环法自行车赛中出尽了风头,那时候在想我要是有一个Edge 705那该多好啊.现在,我终于有了一个Edge 705,是英文版的,不过有已经不错了.只是由于平时 ...

最新文章

  1. iMeta:西农韦革宏团队焦硕等-土壤真菌驱动细菌群落的构建(全文翻译/PPT/视频解读)...
  2. Elasticsearch: 索引别名Aliases
  3. spring aop 申明了切面类之后,如何申明切入点呢?
  4. 5.IA-32寄存器
  5. 博弈论 斯坦福game theory stanford week 5.0_
  6. 征战蓝桥 —— 2016年第七届 —— C/C++A组第2题——生日蜡烛
  7. java中XPATH操作xml,非常便捷
  8. 基础编程题目集 6-5 求自定类型元素的最大值 (10 分)
  9. WOW超大规模场景资源管理方法的尝试
  10. python爬虫怎么赚钱-如何用爬虫技术赚钱?
  11. 数据库下午怎么插入_数据库中日期时间用法
  12. Activator.CreateInstance 方法 (Type) 的用法
  13. JS获取指定月的前N个月数据
  14. 曼昆《经济学原理》-微观经济学-随记(一)
  15. 充电识别过程及QC2.0
  16. Canvas 原生实现图片涂抹打马赛克功能
  17. 第21节--非线性回归(下)
  18. 如何在Debian系统下搭建SVN
  19. Dynamics 365Online 使用Xrm.WebApi.online.execute执行自定义Action
  20. EF实体类种的Virtual关键字作用

热门文章

  1. bzoj 2827 千山鸟飞绝
  2. python web游戏实例_Python实现小黑屋游戏的完整实例
  3. 将国际标准时间和时间戳转换成年月日时分秒
  4. 【产品功能】弹性网卡支持私网多IP
  5. 小程序---宿主环境(常用组件、api)---02
  6. 2021夏令营全记录·厦大信院SE
  7. MapReduce学习笔记(二)——Mapper、Reducer和Driver
  8. C#正则验证车牌、新能源车牌
  9. 鼠标右键多余菜单的清理
  10. LVM 扩容---LVM扩展系统的根分区