前 言
这是我在嵌入式学习的第二阶段——M4理论的学习过程中完成的一个练习,因为内容较多,所以分成几篇文章来发布,如果对您有帮助的话,可以点赞,收藏,关注哦,有其他问题可以私聊交流。
项目还有需要改进优化的地方,也可以添加其他有趣的功能,期待各位大佬的指点和交流。
目 录
一、项目简介
项 目 名:智能手环项目
芯片型号:STM32F411CEU6
功 能:
①指示灯 (LED灯)
②按键功能和振动反馈 (垂直按键,五方向按键ADC和电机)
③图片,字符,汉字显示 (OLED屏幕)
④显示时间 (RTC)
⑤温湿度测量 (SHT20)
⑥血压心率测量 (HP6)
⑦抬手亮屏 (MPU6050)
⑧定时息屏 (定时器---定时中断)
二、项目工程demo
demo已经创建好,放在资源中,可以到PC端该页面下载。
三、基本功能---1
1.垂直按键
因为机械按键有机械抖动,所以要延时15ms后重新检测。
①.c文件
#include "stm32f4xx.h" // Device header
#include "key.h"
/**************************************************************************
* 函数名 : Key_Init
* 函数功能 : 对按键初始化配置
* 函数参数 : void
* 函数返回值: void
* 函数说明 :
* KEY_OK :PA0 通用输入 高电平表示按键按下
*************************************************************************/
void Key_Init(void)
{
//时钟使能
RCC->AHB1ENR |= (1<<0);
//端口模式 --- 输入
GPIOA->MODER &= ~(3<<0);
//上下拉寄存器 --- 浮空
GPIOA->PUPDR &= ~(3<<0);
}
/**************************************************************************
* 函数名 : Key_Scanf
* 函数功能 : 按键扫描
* 函数参数 : void
* 函数返回值: u8
* 函数说明 :
* KEY_OK :PA0 通用输入 高电平表示按键按下
*************************************************************************/
u8 Key_Scanf(void)
{
u8 key = 0xff; //按键对应值
static u8 key_flag = 1; //按键标志位
if(KEY_OK && key_flag) //当按键按下时且标志位解锁
{
Delay_Ms(15); //延时15ms
if(KEY_OK) //重新检测
{
key = 1;
key_flag = 0;
}
}
if(!KEY_OK)
{
key_flag = 1;
}
return key;
}
/**************************************************************************
* 函数名 :Delay_Ms
* 函数功能 :延时函数
* 函数参数 :void
* 函数返回值:void
* 函数说明 :
*************************************************************************/
static void Delay_Ms(u32 ms)
{
u32 i = 100/4*1000*ms; //时钟主频为100MHZ,即1us频率为100HZ,1us可以执行大概4条汇编程序
while(i)
{
i--;
}
}
②.h文件
#ifndef _KEY_H
#define _KEY_H
#include "stm32f4xx.h" // Device header
//宏定义
#define KEY_OK (GPIOA->IDR & (1<<0))
//函数声明
void Key_Init(void);
u8 Key_Scanf(void);
static void Delay_Ms(u32 ms);
#endif
2.LED灯
①.c文件
#include "stm32f4xx.h" // Device header
#include "led.h"
/**************************************************************************
* 函数名 : Led_Init
* 函数功能 : 对led灯初始化配置(led灯所连接GPIO口)
* 函数参数 : void
* 函数返回值: void
* 函数说明 :
* PA7 通用输出 低电平点亮,高电平关闭
*************************************************************************/
void Led_Init(void)
{
//打开GPIOC控制器时钟
RCC->AHB1ENR |= (1 << 0);
//配置GPIO口
//PA7
//端口模式寄存器 --- 模式
GPIOA->MODER &= ~(3 << 14);
GPIOA->MODER |= (1 << 14);
//端口输出类型寄存器 --- 输出类型
GPIOA->OTYPER &= ~(1 << 7);
//端口输出速度寄存器 --- 速度大小
GPIOA->OSPEEDR &= ~(3 << 14);
//端口上拉/下拉寄存器 --- 上拉电阻/下拉电阻
GPIOA->PUPDR &= ~(3 << 14);
//关闭led灯
LED1_OFF;
}
②.h文件
#ifndef _LED_H
#define _LED_H
#include "stm32f4xx.h" // Device header
//宏定义
#define LED1_OFF (GPIOA->ODR |= (1<<7))
#define LED1_ON (GPIOA->ODR &= ~(1<<7))
//函数声明
void Led_Init(void);
#endif
3.电机
①.c文件
#include "stm32f4xx.h" // Device header
#include "motor.h"
/**************************************************************************
* 函数名 : Motor_Init
* 函数功能 : 对电机初始化配置
* 函数参数 : void
* 函数返回值: void
* 函数说明 :
* PB10 通用输出 高电平点开,低电平关闭
*************************************************************************/
void Motor_Init(void)
{
//时钟使能
RCC->AHB1ENR |= (1<<1);
//端口模式
GPIOB->MODER &= ~(3<<20);
GPIOB->MODER |= (1<<20);
//端口输出类型寄存器 --- 输出类型 --- 推挽
GPIOB->OTYPER &= ~(1<<10);
//端口输出速度寄存器 --- 速度大小 --- 2M
GPIOB->OSPEEDR &= ~(3<<20);
//端口上拉/下拉寄存器 --- 浮空
GPIOB->PUPDR &= ~(3<<20);
MI_OFF;
}
②.h文件
#ifndef _MOTOR_H
#define _MOTOR_H
#include "stm32f4xx.h" // Device header
//宏定义
#define MI_ON (GPIOB->ODR |= (1<<10))
#define MI_OFF (GPIOB->ODR &= ~(1<<10))
//函数声明
void Motor_Init(void);
#endif
4.主函数测试
#include "stm32f4xx.h" // Device header
#include "led.h"
#include "motor.h"
#include "key.h"
int main(void)
{
u8 key; //按键扫描变量值
u8 cont = 0; //按键次数变量
Key_Init(); //按键初始化
Led_Init(); //LED灯初始化
Motor_Init(); //电机初始化
//死循环
while(1)
{
//轮询按键扫描函数
key = Key_Scanf();
//垂直按键按下次数
if(key == 1)
{
cont++;
}
switch(cont)
{
case 1:LED1_ON; break; //LED开
case 2:LED1_OFF; break; //LED关
case 3:MI_ON; break; //电机开
case 4:MI_OFF;cont=0; break; //电机关
}
}
return 0;
}