STM32F103C8T6实现简易密码锁(CubeMax配置)(一),Oled显示。

简介: 项目功能:实现设置密码,登陆密码,后期还可以通过E2PROM实现掉电不丢失数据。通过Oled的显示去判断我们是否设置或者登陆成功。

 目录

所用硬件原理图:

OLED.c源码

逻辑思维导图:

实现效果:


此次用的板子是普中的精灵板一,如图:

image.gif 编辑

项目功能:实现设置密码,登陆密码,后期还可以通过E2PROM实现掉电不丢失数据。通过Oled的显示去判断我们是否设置或者登陆成功。

所用硬件原理图:

image.gif 编辑

image.gif 编辑

image.gif 编辑

image.gif 编辑

分别是矩阵按键、LED灯、OLED,以及原理接口图。

首先是矩阵按键的原理:

我们有16个按键,但是只有8个IO口,所以我们要通过高低电平去判断单个按键返回什么。

一般的矩阵按键都是按列和行去进行分配IO口的,例如我这个板子就是P8-P11是行的IO口,

P12-P15是列的IO口。此时我们把P8电平进行拉高,P9-P11全部拉低,然后此时判断的按键就是第一行的按键,此时去判断列上按键的按下就可以成功判断单个按键。剩下的可以依次类推,想要判断第二行九八P9拉高,其他全部拉低即可。

OLED是通过IIC进行一个读写操作,所以在CubeMax配置时我们需要把IIC通道打开。

我这边是调用的 一个OLED的库函数去进行显示,但本质是通过IIC的读和写进行操作。

如果大家不太懂IIC这里可以给大家提供一个IIC的链接

IIC详解,包括原理、过程,最后一步步教你实现IIC_iic协议-CSDN博客

转载于 shaguahaha大佬~

OLED.c源码

#include "oledfont.h"
#include "oled.h"
#define OLED_ADD 0x78 
static void oled_cmd(uint8_t i2c_cmd)
{
    uint8_t *cmd;
    cmd = &i2c_cmd;
    HAL_I2C_Mem_Write(&hi2c1, OLED_ADD, 0x00, 
                      I2C_MEMADD_SIZE_8BIT, cmd, 1,
                      100);
}
static void oled_data(uint8_t i2c_data)
{
    uint8_t *data;
    data = &i2c_data;
    HAL_I2C_Mem_Write(&hi2c1, OLED_ADD, 0x40, 
                      I2C_MEMADD_SIZE_8BIT, data, 1,
                      100);
}
static void oled_origin(uint8_t x, uint8_t y) 
{
    oled_cmd(0xb0+y);
  oled_cmd(((x&0xf0)>>4)|0x10);
  oled_cmd((x&0x0f)|0x01);
}
void oled_clear()
{
  uint8_t i,n;        
  for(i=0;i<8;i++)  
  {  
    oled_cmd(0xb0+i);
    oled_cmd (0x00); 
    oled_cmd (0x10); 
    for(n=0;n<128;n++)
      oled_data(0);
  } 
}
void oled_full(uint8_t data)//0xff
{
    uint8_t m,n;
  for(m=0;m<8;m++)
  {
    oled_cmd(0xb0+m);   //page0-page1
    oled_cmd(0x00);   //low column start address
    oled_cmd(0x10);   //high column start address
    for(n=0;n<128;n++)
      {
        oled_data(data);
      }
  }
}
void oled_init(void)
{
    HAL_Delay(100);
  
  oled_cmd(0xAE); //display off
  oled_cmd(0x20); //Set Memory Addressing Mode  
  oled_cmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
  oled_cmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
  oled_cmd(0xc8); //Set COM Output Scan Direction
  oled_cmd(0x00); //---set low column address
  oled_cmd(0x10); //---set high column address
  oled_cmd(0x40); //--set start line address
  oled_cmd(0x81); //--set contrast control register
  oled_cmd(0xff); //áá?èμ÷?ú 0x00~0xff
  oled_cmd(0xa1); //--set segment re-map 0 to 127
  oled_cmd(0xa6); //--set normal display
  oled_cmd(0xa8); //--set multiplex ratio(1 to 64)
  oled_cmd(0x3F); //
  oled_cmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
  oled_cmd(0xd3); //-set display offset
  oled_cmd(0x00); //-not offset
  oled_cmd(0xd5); //--set display clock divide ratio/oscillator frequency
  oled_cmd(0xf0); //--set divide ratio
  oled_cmd(0xd9); //--set pre-charge period
  oled_cmd(0x22); //
  oled_cmd(0xda); //--set com pins hardware configuration
  oled_cmd(0x12);
  oled_cmd(0xdb); //--set vcomh
  oled_cmd(0x20); //0x20,0.77xVcc
  oled_cmd(0x8d); //--set DC-DC enable
  oled_cmd(0x14); //
  oled_cmd(0xaf); //--turn on oled panel
    
    oled_full(0x00);
}
void oled_display_char(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{       
  unsigned char c=0,i=0;  
    c=chr-' ';//得到偏移后的值     
    if(x>128-1){x=0;y=y+2;}
    if(Char_Size == 16)
      {
      oled_origin(x,y); 
      for(i=0;i<8;i++)
      oled_data(F8X16[c*16+i]);
      oled_origin(x,y+1);
      for(i=0;i<8;i++)
      oled_data(F8X16[c*16+i+8]);
      }
      else {  
        oled_origin(x,y);
        for(i=0;i<6;i++)
        oled_data(F6x8[c][i]);
        
      }
}
void oled_show_string(uint8_t x, uint8_t y, char ch[], uint8_t TextSize)
{
    uint8_t c = 0,i = 0,j = 0;
  switch(TextSize)
  {
    case 1:
    {
      while(ch[j] != '\0')
      {
        c = ch[j] - 32;
        if(x > 126)
        {
          x = 0;
          y++;
        }
        oled_origin(x,y);
        for(i=0;i<6;i++)
          oled_data(F6x8[c][i]);
        x += 6;
        j++;
      }
    }break;
    case 2:
    {
      while(ch[j] != '\0')
      {
        c = ch[j] - 32;
        if(x > 120)
        {
          x = 0;
          y++;
        }
        oled_origin(x,y);
        for(i=0;i<8;i++)
          oled_data(F8X16[c*16+i]);
        oled_origin(x,y+1);
        for(i=0;i<8;i++)
          oled_data(F8X16[c*16+i+8]);
        x += 8;
        j++;
      }
    }break;
  }
}

image.gif

image.gif 编辑

image.gif 编辑

这是cubeMax配置的整体图,其中PA0-PA7是LED的,PA13-PA14是烧录口,PA10-PA9是串口通信,PB7-PB6是OLED所需的IIC通信。PB12-PB15是我们矩阵按键的列按键,PB8-PB11是行按键。

逻辑思维导图:

整体逻辑我做了一个思维导图 大家可以借鉴一下~

image.gif 编辑

实现效果:

image.gif 编辑

image.gif 编辑

image.gif 编辑

image.gif 编辑

主要是运用了一个矩阵按键还有OLED。

源码地址

微信关注嵌入式工程之家发送 门锁源码  即可获得完整源码包哦~

相关文章
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
694 0
|
4月前
STM32CubeMX FreeRTOS 互斥锁
STM32CubeMX FreeRTOS 互斥锁
162 12
|
4月前
STM32CubeMX OLED驱动
STM32CubeMX OLED驱动
65 10
|
5月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
674 2
|
5月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
552 1
|
4月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
156 0
|
5月前
|
芯片
【STM32】详解RTC实时时钟的概念和配置&示例代码
【STM32】详解RTC实时时钟的概念和配置&示例代码
|
6月前
STM32CubeMX配置时钟无法使用高速外部时钟HSE
STM32CubeMX配置时钟无法使用高速外部时钟HSE
240 0
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
428 2
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结