STM32F103实现自行车里程计

本文详细介绍了如何使用STM32F103开发板实现自行车里程计,包括环境搭建、元器件测试、软件配置、时间中断和里程计的实现。通过STM32 CubeMX配置芯片,Keil UVision 5编写代码,结合中断和串口通信,最终创建了一个基于按钮的简单自行车里程计系统。
摘要由CSDN通过智能技术生成

STM32F103实现自行车里程计

器材准备

  • STM32F103板子一个
  • 杜邦线、面包线、面包板若干
  • ST-LINK V2 一个(烧录程序)
  • USB-TTL 一个(做串口输出测试)
  • 按钮两个
  • Win电脑一台(建议不要在mac下开发,实在太难受了)

连接

  • usb to ttl 和 stm32开发板连接图
    [id](#Table 1)
USB STM32
3.3V 3.3V
GND GND
TXD A10
RXD A9

- stm32和st-link直接按照对应的接口相连即可

环境搭建

软件安装

软件使用

开始之前记得一定要先将驱动都安装好!

STM32 CubeMX

​ 进入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即可生成代码。

Keil UVision 5

使用上面的工具 设置好引脚之后就可以开始写代码了,直接在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进行烧录的方法。

这里写图片描述

  • Flash->Configure->Utilities在Add Output File to Group选定Application/MDK-ARM,不然在目录下找不到对应的HEX文件。

这里写图片描述

  • Flash->Configure->Utilities->Settings选定Reset and Run,在STM32上使用的是ISP编程,烧录时要对芯片中Flash原有的数据全部抹除,烧进自己的数据,然后重新启动,bootloader起来后会跑对应的指令(在使用Keil下板时有用)。

这里写图片描述

  • 注意!每次重新打开Keil一定要记得将上面的流程全部都走一遍,不然就会出错,真是想吐槽这个IDE,一旦重启原来的设定就都不见了。
  • 将ST-LINK撤下,换上USB-TTL并接入PC(记得提前装好驱动),打开ST-LINK,导入一个HEX文件,如果像上面使用Keil建好的工程,则HEX文件在Project name/MDK-ARM/Project name下

这里写图片描述

  • 点击connect to the target,如果报错了说明是你的线路没接对或者驱动没装好
  • 点击Target->Erase Chip将芯片内Flash的数据全部擦除
  • 点击Target->Program & Verify,烧录数据,完成后烧录成功,芯片会执行对应的功能

元器件测试以及简单逻辑代码框架

闪烁小灯

  • 芯片引脚设置(PA9作为输出)
    这里写图片描述

  • 线路连接

    先使用STM32的3.3V输出检验二极管的方向,然后如下图所示小灯一个脚接GND,一个脚接A9,这样当A9输出高电平时小灯就会亮了。

这里写图片描述

这里写图片描述FullSizeRender

小灯在成功点亮之后说明杜邦线和小灯都是正常的(否则小灯可能就是坏的,或者线是坏的,只是极有可能的,我们连续测了三个小灯全是坏的,开始还以为是烧录少错了,查了好久,换成蜂鸣器做测试的时候居然响了。。。)。然后就可以使用面包板给小灯串联一个按钮,检测按钮和面包板的好坏,盒子里的器材中,我们又检测出一个按钮是坏的(按与不按小灯都会有信号)。

  • 代码

​ 我们之前对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开发的流程,之后的开发按照这个模板来就可以了。

串口通信

  • 芯片引脚设置

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是当下的
  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值