打印
[其他ST产品]

stm32按键控制定时流水灯

[复制链接]
969|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kqh11a|  楼主 | 2024-1-29 15:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
任务一:按键控制定时流水灯
任务要求
通过Systick实现流水灯频率控制,要求循环一次流水灯耗时1s。

使用外部中断功能,用按键控制流水灯。按下按键一开启流水灯,再按下按键一关闭流水灯,按下按键二暂停流水灯。

实现思路
为了实现同一个按键控制开启关闭的功能,用exti监测按键按下次数,return CountSensor_Count返回按下按键数量,并在OLED上显示(便于调试);在返回值为奇数时开启流水灯,偶数时关闭流水灯.

视频展示
关键代码#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "EXTI.h"
#include "LED.h"

int        main(void)
{  
    CountSensor_Init();
        LED_Init();
        OLED_Init();
        OLED_ShowString(1,1,"Count:");
        GPIO_SetBits(GPIOA,GPIO_Pin_All);
        while(1)
        {
         OLED_ShowNum(1,7,CountSensor_Get(),5);
         OLED_ShowNum(2,7,Countting_Get(),5);
         uint16_t key_count = CountSensor_Get();
         int16_t key_Countting = Countting_Get();
                if((key_Countting+1)%2==0){
          if((key_count+1)%2==0)
{
            GPIO_Write(GPIOA, ~0x0001);        //0000 0000 0000 0001
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0002);        //0000 0000 0000 0010
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0004);        //0000 0000 0000 0100
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0008);        //0000 0000 0000 1000
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0010);        //0000 0000 0001 0000
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0020);        //0000 0000 0010 0000
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0040);        //0000 0000 0100 0000
                Delay_ms(100);
                GPIO_Write(GPIOA, ~0x0080);        //0000 0000 1000 0000
                Delay_ms(100);
}
                }
        else {
                        GPIO_SetBits(GPIOA,GPIO_Pin_All);
                }
        }
       
}

使用特权

评论回复
沙发
kqh11a|  楼主 | 2024-1-29 15:36 | 只看该作者
#include "stm32f10x.h"      // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

        //配置GPIO

        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        //配置AFIO
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource11);
       
        //配置EXTI
        EXTI_InitTypeDef EXTI_InitStruct;
        EXTI_InitStruct.EXTI_Line=EXTI_Line11;
        EXTI_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
        //下降沿触发,按实际需求
        EXTI_Init(&EXTI_InitStruct);
       
        //配置NVIC
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//根据实际
        NVIC_InitTypeDef NVIC_InitStruct;
        NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(&NVIC_InitStruct);
       
}

uint16_t CountSensor_Get(void)
{
   return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line11)== SET)
        {
                CountSensor_Count ++;
          EXTI_ClearITPendingBit(EXTI_Line11);
        }
}

使用特权

评论回复
板凳
kqh11a|  楼主 | 2024-1-29 15:36 | 只看该作者
//.h
#ifndef _BSP_SYSTICK_H
#define        _BSP_SYSTICK_H
#include "stm32f10x.h"
#include "core_cm3.h"
void systick_delay_us(uint32_t us);
void systick_delay_ms(uint32_t ms);
#endif /*_BSP_SYSTICK_H*/

//.c


#include "stm32f10x.h"
#include "bsp_systick.h"
#include "core_cm3.h"

void systick_delay_us(uint32_t us)
{
        SysTick_Config(72);
       
        uint32_t i;
        for(i=0;i<us;i++)
        {
                while(!((SysTick->CTRL)&1<<16));
        }
       
        //当结束计时的时候,我们要关掉计时器,把它的使能关掉~取反
        SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
       
       
}


void systick_delay_ms(uint32_t ms)
{
        SysTick_Config(72000);
       
        uint32_t i;
        for(i=0;i<ms;i++)
        {
                while(!((SysTick->CTRL)&1<<16));
        }
       
        //当结束计时的时候,我们要关掉计时器,把它的使能关掉~取反
        SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
       
       
}

使用特权

评论回复
地板
kqh11a|  楼主 | 2024-1-29 15:37 | 只看该作者
任务二:阅读手册
任务要求
了解参考手册和数据手册的区别和联系

找到 GPIO 的功能框图,知道哪部分是 GPIO 输出、GPIO 输入、外设复用功能,并将 GPIO 的各种模式和它们联系起来

找到系统时钟树,简单介绍各部分的挂载

使用特权

评论回复
5
kqh11a|  楼主 | 2024-1-29 15:37 | 只看该作者
参考手册和数据手册的区别和联系
区别:
内容:参考手册主要提供了STM32微控制器的整体架构、功能模块、时钟配置、引脚定义、寄存器描述等方面的信息。数据手册则更加详细地描述了每个功能模块的工作原理、寄存器的位定义、时序要求、电气特性等技术细节。

用途:参考手册主要用于整体了解STM32微控制器的特性和功能,为系统设计提供指导。数据手册则更多地用于硬件和软件开发工程师进行具体的设计、编程和调试。

使用特权

评论回复
6
kqh11a|  楼主 | 2024-1-29 15:37 | 只看该作者
联系:
信息补充:参考手册和数据手册通常是相互关联的。参考手册提供了STM32微控制器的总体架构和功能描述,而数据手册提供了更为详细的技术细节。两者合起来可以提供全面的信息,帮助开发人员更好地理解和应用STM32微控制器。

相互引用:参考手册中通常会引用数据手册中的相关章节和内容,以便读者可以在需要更深入了解的时候去查阅数据手册。

使用特权

评论回复
7
kqh11a|  楼主 | 2024-1-29 15:37 | 只看该作者
GPIO 的功能框图

使用特权

评论回复
8
kqh11a|  楼主 | 2024-1-29 15:38 | 只看该作者
GPIO输入输出的8种模式

使用特权

评论回复
9
kqh11a|  楼主 | 2024-1-29 15:38 | 只看该作者
系统时钟树

使用特权

评论回复
10
kqh11a|  楼主 | 2024-1-29 15:38 | 只看该作者
时钟信号能够防止逻辑门判断波动,只有当方波的上升信号到达边沿触发器时才会写入寄存器,故运行前必须先打开时钟,时钟对程序的运行至关重要。由时钟源产生方波信号,又由时钟树传递到芯片的各个地方。

HSE时钟:高速外部时钟

LSE时钟:高速内部时钟

sysclk时钟:系统时钟

使用特权

评论回复
11
kqh11a|  楼主 | 2024-1-29 15:38 | 只看该作者
任务三:debug控制单个LED
任务要求
进入 Debug 模式,了解 复位,四种运行(单步,全速等),断点,Watch 窗口的使用

在debug模式下控制LED的亮灭(修改寄存器值或变量值)

提示:使用 Debug 的断点,Watch,Call Stack + Locals 等功能,分析变量的值和程序运行的流程

Dubug

使用特权

评论回复
12
kqh11a|  楼主 | 2024-1-29 15:39 | 只看该作者
1. 复位和五种运行模式


从左到右依次:reset,全速运行,停止全速运行,单步运行,跳过当前行单步运行,跳出当前函数单步运行,跳到光标指定行单步运行.

reset键:复位键,使程序回到初始位置

全速运行:程序会全速运行直到停在设置的断点

停止全速运行:顾名思义

单步运行:执行黄色光标指示的行

跳过当前行单步运行:顾名思义

跳出当前函数单步运行:顾名思义

跳到光标指定行单步运行:跳到蓝色光标指示行运行

鼠标左键设置断点,右键设置蓝色光标

使用特权

评论回复
13
kqh11a|  楼主 | 2024-1-29 15:39 | 只看该作者
2. 窗口


从左到右依次:命令窗口(commend),反汇编窗口,符号窗口(symbol),registers,memory,watch



另可以在外设菜单栏的系统资源查看中看到所有寄存器端口的值.

调试模式下不能直接修改程序,需要退出调试模式修改后重新编译

使用特权

评论回复
14
kqh11a|  楼主 | 2024-1-29 15:40 | 只看该作者
快捷键
通用快捷键

使用特权

评论回复
15
kqh11a|  楼主 | 2024-1-29 15:40 | 只看该作者
自定义快捷键
keil中的快捷键可以自己设置,以下设置最常用的注释快捷键为例:

1、点击“扳手”

使用特权

评论回复
16
kqh11a|  楼主 | 2024-1-29 15:40 | 只看该作者
2、点击“Shortcut Keys”,拖动“滚动条”,找到“注释选择”,点击“创建快捷方式” ,按键盘确定自己需要的快捷键,它会自动显示在1框中,点击“OK”,完成设置。设置其他功能的快捷键以此类推。

3、点击“OK”,完成设置。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

315

帖子

0

粉丝