基于STM32的传送带系统

这篇具有很好参考价值的文章主要介绍了基于STM32的传送带系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 

 

功能

设计一个传送带系统,能够实现传送带的开始/停止,正转/反转,加/减速,对传送带的物品计数。

按钮/app功能控制,oled屏幕/app显示。

 

设计框图

基于STM32的传送带系统

 

原理图

基于STM32的传送带系统

 

软件构建阶段

利用STM32CubeMX生成模板

MCU选型:STM32F103C8T6,双击打开。

Ststem Core->SYS:Serial Wire。Timebase Source:TIM1(供Freertos实时操作系统使用)。

Ststem Core->RCC:HSE、LSE--Crystal/Ceramic Resonator(不考虑低功耗,默认打开)。

Ststem Core->IWDG:Activated。psc--64、reload--625。(独立看门狗1s定时喂狗,判断系统正常运行)。

Connectivity->USART1:Asynchronous(蓝牙模块、调试输出所需)、9600-8-N-1、开中断。

基于STM32的传送带系统

搜索GPIO位置,选择IO模式,取别名。

PC13--推挽输出--SysLED。 

PB9----推挽输出--BEEP。

PB12--推挽输出--AIN2。

PB13--推挽输出--AIN1。

PB14--推挽输出--STBY。

PB15--上拉输入--KEY_1。

PB11--上拉输入--KEY_2。

PB10--上拉输入--KEY_3。

PB1----上拉输入--KEY_4。

PB0----上拉输入--KEY_5。

PA3----上拉输入--Photoelectric_detector1。

PA4----上拉输入--Photoelectric_detector2。

PA0-WKUP----GPIO_EXIT0--Encoder。

基于STM32的传送带系统

配置时钟树。

基于STM32的传送带系统

配置I2C1(OLED屏幕通讯接口)。

配置TIM3、4(一个采集速度,一个PWM)。

基于STM32的传送带系统

配置FreeRTOS系统。

基于STM32的传送带系统

Project Manager->project:Toolchain/IDE:MDK-ARM。

Project Manager->Code Generator:勾上Generate peripheral initialization as a pair of '.c/.h' files per peripheral。

GENERATE CODE生成工程模板。

 

工程目录个人规范

在生成的文件夹中建立UserCode文件夹,存放用户代码。

在UserCode文件夹中建立一系列文件(文件多的话可以再划分Drivers、Applications文件夹,此处不纠结)。

app_applications:主要功能实现。

app_guard:守护任务。定时喂狗。

drive_it:中断调用回调。

driver_oled:屏幕显示驱动。

drive_fonts:字体定义。

drive_picture:存放图片数组。

打开MDK,添加新建的一系列文件进来(记得引入头文件)。

勾选上Use MicroLIB。

基于STM32的传送带系统

 

usart支持重定向

usart.c文件

/* USER CODE BEGIN 1 */
//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);    
    return (ch);
}
//重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{        
    int ch;
    HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);    
    return (ch);
}
/* USER CODE END 1 */

usart.h文件

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* USER CODE BEGIN Prototypes */
int fputc(int ch, FILE *f);
int fgetc(FILE *f);
/* USER CODE END Prototypes */

 

守护任务

app_guard.c文件

#include "app_guard.h"
#include "cmsis_os.h"
#include "main.h"
#include "iwdg.h"
/* Private includes ----------------------------------------------------------*/
#include "gpio.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Private user code ---------------------------------------------------------*/

/**
  * @brief  守护任务循环入口
  * @note   None
  * @param  argument : NULL
  * @retval None
  */
void StartGuardTask(void *argument)
{ 
    for(;;)
    {
#ifndef DEBUG        
        HAL_IWDG_Refresh(&hiwdg);        
#endif        
        HAL_GPIO_TogglePin(Sys_LED_GPIO_Port, Sys_LED_Pin);
        osDelay(500);
    }
}

app_guard.h文件

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_GUARD_H
#define __APP_GUARD_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/

/* Exported macro ------------------------------------------------------------*/

/* Exported functions prototypes ---------------------------------------------*/

/* Private defines -----------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* __APP_GUARD_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

定时器部分

tim.c文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    tim.c
  * @brief   This file provides code for the configuration
  *          of the TIM instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "tim.h"

/* USER CODE BEGIN 0 */
typedef struct {
    float SetSpeed;       //设定值
    float ActualSpeed;    //实际值
    float err;            //偏差
    float err_last;       //上一个偏差
    float err_last_last;  //最上一个偏差 
    float Kp, Ki, Kd;     //比例 积分 微分
} PID;
PID pid;

float P_NUMS = 0.05, I_NUMS = 0.01, D_NUMS = 0.01;    //PID参数
/* USER CODE END 0 */

TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;

/* TIM2 init function */
void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 280;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1000;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);    //打开PWM信号,TIM1的通道1
  /* USER CODE END TIM2_Init 2 */
  HAL_TIM_MspPostInit(&htim2);

}
/* TIM3 init function */
void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 36000-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1000-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
  HAL_TIM_Base_Start_IT(&htim3);                //启动定时器中断模式计数,2s
  /* USER CODE END TIM3_Init 2 */

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspInit 0 */

  /* USER CODE END TIM2_MspInit 0 */
    /* TIM2 clock enable */
    __HAL_RCC_TIM2_CLK_ENABLE();
  /* USER CODE BEGIN TIM2_MspInit 1 */

  /* USER CODE END TIM2_MspInit 1 */
  }
  else if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspInit 0 */

  /* USER CODE END TIM3_MspInit 0 */
    /* TIM3 clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();

    /* TIM3 interrupt Init */
    HAL_NVIC_SetPriority(TIM3_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
  /* USER CODE BEGIN TIM3_MspInit 1 */

  /* USER CODE END TIM3_MspInit 1 */
  }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspPostInit 0 */

  /* USER CODE END TIM2_MspPostInit 0 */

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM2 GPIO Configuration
    PA2     ------> TIM2_CH3
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM2_MspPostInit 1 */

  /* USER CODE END TIM2_MspPostInit 1 */
  }

}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspDeInit 0 */

  /* USER CODE END TIM2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM2_CLK_DISABLE();
  /* USER CODE BEGIN TIM2_MspDeInit 1 */

  /* USER CODE END TIM2_MspDeInit 1 */
  }
  else if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspDeInit 0 */

  /* USER CODE END TIM3_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM3_CLK_DISABLE();

    /* TIM3 interrupt Deinit */
    HAL_NVIC_DisableIRQ(TIM3_IRQn);
  /* USER CODE BEGIN TIM3_MspDeInit 1 */

  /* USER CODE END TIM3_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
void PID_init(void)           //初始化
{
    pid.SetSpeed = 0.0;
    pid.ActualSpeed = 0.0;
    pid.err = 0.0;
    pid.err_last = 0.0;
    pid.err_last_last = 0.0;
    pid.Kp = P_NUMS;               
    pid.Ki = I_NUMS;            
    pid.Kd = D_NUMS;                         
}

float PID_realize(float Speed,float vot)          //预设值  实际值
{
    float incrementSpeed;        
    pid.SetSpeed = Speed;                         //把预设值赋值    
    pid.ActualSpeed = vot;                        //实际值幅值
    pid.err = pid.SetSpeed - pid.ActualSpeed;     //计算偏差
    incrementSpeed = pid.Kp*(pid.err - pid.err_last) + 
                     pid.Ki*pid.err + 
                     pid.Kd*(pid.err - 2 * pid.err_last_last + pid.err_last);  
    /*反馈速度量  =    P *( 偏差 - 上一个偏差 ) +
                    I * 偏差 +
                    D *( 偏差 - 2 * 最上一个偏差 + 上一个偏差 )*/
    return incrementSpeed;
}
/* USER CODE END 1 */

tim.h文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    tim.h
  * @brief   This file contains all the function prototypes for
  *          the tim.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TIM_H__
#define __TIM_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern TIM_HandleTypeDef htim2;

extern TIM_HandleTypeDef htim3;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_TIM2_Init(void);
void MX_TIM3_Init(void);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

/* USER CODE BEGIN Prototypes */
void PID_init(void);
float PID_realize(float Speed,float vot);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __TIM_H__ */

 

中断处理

弱定义HAL_TIM_PeriodElapsedCallback函数,在driver_it实现真正的回调。

main.c文件

/* USER CODE BEGIN 4 */
__weak
/* USER CODE END 4 */

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM1 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

drive_it.c文件

/* Includes ------------------------------------------------------------------*/
#include "drive_it.h"
#include "cmsis_os.h"
#include "main.h"
#include "usart.h"
#include "tim.h"
/* Private includes ----------------------------------------------------------*/
#include "app_application.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
extern char Rcv_flag;
extern uint16_t revolving_speed, gyrograph;    //转速,转速记录器

/* Private function prototypes -----------------------------------------------*/

/* Private user code ---------------------------------------------------------*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == Encoder_Pin)
    {
        revolving_speed++;        //每次经过编码器就++,固定时间清零
    }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart == &huart1)
    {
    }
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart == &huart1)
    {
        HAL_UART_Receive_IT(&huart1,(uint8_t *)&Rcv_flag,1);
    }    
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM1) 
    {
        HAL_IncTick();
    }
    
    if(htim == &htim3)
    {
        gyrograph = revolving_speed;    //固定时间记录经过编码器的次数
        revolving_speed = 0;
    }
}

drive_it.h文件

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DRIVE_IT_H
#define __DRIVE_IT_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* Private includes ----------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/

/* Exported macro ------------------------------------------------------------*/

/* Exported functions prototypes ---------------------------------------------*/

/* Private defines -----------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* __DRIVE_IT_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

应用相关

app_application.c文件

#include "app_application.h"
#include "cmsis_os.h"
#include "main.h"
/* Private includes ----------------------------------------------------------*/
#include "usart.h"
#include "tim.h"
#include "drive_oled.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
uint8_t show_buf[20];            //供oled显示的缓冲区
uint16_t preset_speed = 200, revolving_speed = 0, gyrograph = 0, count = 0, flag = 0;    //预设速度,转速, 转速记录器, 物品数量
char     Rcv_flag;                //接收标志
uint8_t motor_status = 0;        //电机状态
uint8_t motor_direction = 0;    //电机方向

uint16_t pwmval = 300;            //方波初值,最大1000
extern float P_NUMS, I_NUMS, D_NUMS;    //PID参数
extern const unsigned char gImage_a[1024];
extern const unsigned char gImage_b[][1024];
int real_speed;
extern const unsigned char ikun[1024];
extern const unsigned char gImage_b[][1024];
/* Private function prototypes -----------------------------------------------*/
unsigned char BMP[1024];
/* Private user code ---------------------------------------------------------*/
/**
  * @brief  应用任务循环入口
  * @note   None
  * @param  argument : NULL
  * @retval None
  */
void StartApplicationTask(void *argument)
{          
    HAL_UART_Receive_IT(&huart1,(uint8_t *)&Rcv_flag,1);

    for(;;)
    {    
        if(motor_status == 0)    //未启动
        {
            __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);        //输出方波,方波为低电平
        }else                    //启动了
        {
            if( (HAL_GPIO_ReadPin(Photoelectric_detector2_GPIO_Port, Photoelectric_detector2_Pin) == GPIO_PIN_RESET) &&
                (motor_direction == 1))        //正转是避障被挡住
            {
                __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);    //输出方波,方波为低电平
                if(flag == 0)
                {
                    flag = 1;    //计数标志
                    count++;
                    beepDi();
                }
            }else if( (HAL_GPIO_ReadPin(Photoelectric_detector1_GPIO_Port, Photoelectric_detector1_Pin) == GPIO_PIN_RESET) &&
                (motor_direction == 0))        //反转时避障被挡住
            {    
                __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);    //输出方波
                if(flag == 0)
                {
                    flag = 1;
                    count++;
                    beepDi();
                }
            }else
            {
                pwmval += PID_realize(preset_speed + 5 , real_speed);    //预设  实际        
                if(pwmval < 1)
                    pwmval = 1;
                else if(pwmval > 1000)
                    pwmval = 1000;
                
                flag = 0;
                
                __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, pwmval);        //输出方波
            }        
        }    
        osDelay(100);
    }           
}    

/**
  * @brief  按键扫描任务循环入口
  * @note   None
  * @param  argument : NULL
  * @retval None
  */
void StartKeyScanTask(void *argument)
{      
    SSD1306_GotoXY(0, 0);
    sprintf((char *)show_buf, "P:%.2f", P_NUMS);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    SSD1306_GotoXY(0, 20);
    sprintf((char *)show_buf, "I:%.2f", I_NUMS);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    SSD1306_GotoXY(0, 40);
    sprintf((char *)show_buf, "D:%.2f", D_NUMS);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    
    SSD1306_GotoXY(56, 0);
    sprintf((char *)show_buf, "PreS:%d", preset_speed);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    SSD1306_GotoXY(56, 20);
    sprintf((char *)show_buf, "revS:%3d", real_speed);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    SSD1306_GotoXY(56, 40);
    sprintf((char *)show_buf, "cnt:%d", count);
    SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
    SSD1306_UpdateScreen();
    
    for(;;)
    {    
        real_speed = (float)gyrograph / 1.0;    //拿到转速
        SSD1306_GotoXY(56, 20);
        sprintf((char *)show_buf, "revS:%3d", real_speed);
        SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
        SSD1306_UpdateScreen();
        
        //启动/暂停
        if(HAL_GPIO_ReadPin(KEY_1_GPIO_Port,KEY_1_Pin) == GPIO_PIN_RESET || Rcv_flag == 'Q')
        {    
            osDelay(200);    //软件消抖,一般需要20ms。硬件消抖体现在电路图上,如加入电容。
            beepDi();
            motor_status = !motor_status;
            osDelay(1000);
        }
        
        //加速
        if(HAL_GPIO_ReadPin(KEY_2_GPIO_Port, KEY_2_Pin) == GPIO_PIN_RESET || Rcv_flag  == 'J')
        {    
            preset_speed += 5;
            if(preset_speed > 600)
                preset_speed = 600;
            SSD1306_GotoXY(56, 0);
            sprintf((char *)show_buf, "PreS:%d", preset_speed);
            SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
            SSD1306_UpdateScreen();
            beepDi();
        }
        
        //减速
        if(HAL_GPIO_ReadPin(KEY_3_GPIO_Port, KEY_3_Pin) == GPIO_PIN_RESET || Rcv_flag == 'H')
        {    
            preset_speed -= 5;
            if(preset_speed < 200)    
                preset_speed = 200;
            SSD1306_GotoXY(56, 0);
            sprintf((char *)show_buf, "PreS:%d", preset_speed);
            SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
            SSD1306_UpdateScreen();
            beepDi();
        }
            
        //反转
        if(HAL_GPIO_ReadPin(KEY_4_GPIO_Port, KEY_4_Pin) == GPIO_PIN_RESET || Rcv_flag == 'F')
        {    
            motor_direction = 0;
            motorReverse();
            beepDi();
        }
        
        //正转
        if(HAL_GPIO_ReadPin(KEY_5_GPIO_Port, KEY_5_Pin) == GPIO_PIN_RESET || Rcv_flag == 'Z')
        {    
            motor_direction = 1;
            motorForward();
            beepDi();
        }
        
        SSD1306_GotoXY(56, 40);
        sprintf((char *)show_buf, "cnt:%d", count);
        SSD1306_Puts((char *)show_buf, &TM_Font_7x10, SSD1306_COLOR_WHITE);
        SSD1306_UpdateScreen();
        
        Rcv_flag = NULL;    
        printf("s %d %d %d ", (int)revolving_speed, preset_speed, count);    //发送转速、预设和数量数据给上位机
//        for(uint16_t i=0; i<13; i++)
//            OLED_DrawBMP(0, 0, 127, 63, gImage_b[i]);
        osDelay(100);
    }           
}    

void beepDi(void)
{
    HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);
    osDelay(200);
    HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET);
}

void motorForward(void)
{
    HAL_GPIO_WritePin(AIN1_GPIO_Port, AIN1_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(AIN2_GPIO_Port, AIN2_Pin, GPIO_PIN_RESET);
}

void motorReverse(void)
{
    HAL_GPIO_WritePin(AIN1_GPIO_Port, AIN1_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(AIN2_GPIO_Port, AIN2_Pin, GPIO_PIN_SET);
}

app_application.h文件

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_APPLICATION_H
#define __APP_APPLICATION_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/

/* Exported macro ------------------------------------------------------------*/

/* Exported functions prototypes ---------------------------------------------*/
void beepDi(void);
void motorForward(void);
void motorReverse(void);
/* Private defines -----------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* __APP_APPLICATION_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

屏幕相关

driver_oled.c(SSD1315驱动)

/* Includes ------------------------------------------------------------------*/
#include "drive_oled.h"
#include "cmsis_os.h"
#include "main.h"
#include "i2c.h"
/* Private includes ----------------------------------------------------------*/
#include "string.h"
/* Private typedef -----------------------------------------------------------*/
typedef struct {
    uint16_t     CurrentX;
    uint16_t     CurrentY;
    uint8_t     Inverted;
    uint8_t     Initialized;
} OLED_t;
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/
/* 128Column * 8Page */
#define SSD1306_WIDTH            128    //SSD1306 width in pixels
#define SSD1306_HEIGHT           64        //SSD1306 LCD height in pixels
#define ABS(x)   ((x) > 0 ? (x) : -(x))    //Absolute value
/* Private variables ---------------------------------------------------------*/
static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8];    //SSD1306 data buffer
static OLED_t SSD1306;

/* Private function prototypes -----------------------------------------------*/
static void SSD1306_I2C_Write(uint8_t reg, uint8_t data);
static void SSD1306_Write_Cmd(uint8_t cmd);
static void SSD1306_Write_Data(uint8_t data);
static void SSD1306_Write_MultiData(uint8_t *data, uint16_t size);

/* Private user code ---------------------------------------------------------*/
/*
 * 函数作用    : 通过I2C接口发送一个字节数据给SSD1306
 * 参数  reg   : 发送数据之前,需要先发送一个字节数据用于区分发送的是命令还是数据。其中先发送0x00,表示发送命令;先发送0x40,表示发送数据
 * 参数  data  : 要发送的一字节数据
 * 返回值      : 无
 */
static void SSD1306_I2C_Write(uint8_t reg, uint8_t data)
{
    uint8_t tmp_array[2] = {reg, data};
    HAL_I2C_Master_Transmit(&hi2c1, 0x78, tmp_array, sizeof(tmp_array), 1);
}

static void SSD1306_Write_Cmd(uint8_t cmd)        //写命令
{
    SSD1306_I2C_Write(0x00, cmd);
}

static void SSD1306_Write_Data(uint8_t data)    //写数据
{
    SSD1306_I2C_Write(0x40, data);
}

static void SSD1306_Write_MultiData(uint8_t *data, uint16_t size)
{
    uint8_t tmp_array[SSD1306_WIDTH + 1] = {0x40, 0};

    memcpy(&tmp_array[1], data, size);
    
    HAL_I2C_Master_Transmit(&hi2c1, 0x78, tmp_array, sizeof(tmp_array), 10);
}

/* 打开显示 */
void SSD1306_ON(void) 
{
    SSD1306_Write_Cmd(0x8D);    //设置电荷泵
    SSD1306_Write_Cmd(0x14);    //开启电荷泵
    SSD1306_Write_Cmd(0xAF);    //OLED唤醒
}

/* 关闭显示 */
void SSD1306_OFF(void) 
{
    SSD1306_Write_Cmd(0x8D);    //设置电荷泵
    SSD1306_Write_Cmd(0x10);    //关闭电荷泵
    SSD1306_Write_Cmd(0xAE);    //OLED休眠
}

void SSD1306_Init(void) 
{
    /* A little delay */
    HAL_Delay(100);

    /* Init LCD */
    SSD1306_Write_Cmd(0xAE); //display off
    SSD1306_Write_Cmd(0x20); //Set Memory Addressing Mode
    SSD1306_Write_Cmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    SSD1306_Write_Cmd(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
    SSD1306_Write_Cmd(0xC8); //Set COM Output Scan Direction
    SSD1306_Write_Cmd(0x00); //---set low column address
    SSD1306_Write_Cmd(0x10); //---set high column address
    SSD1306_Write_Cmd(0x40); //--set start line address
    SSD1306_Write_Cmd(0x81); //--set contrast control register
    SSD1306_Write_Cmd(0xFF); //亮度调节 范围0x00~0xff
    SSD1306_Write_Cmd(0xA1); //--set segment re-map 0 to 127
    SSD1306_Write_Cmd(0xA6); //--set normal display
    SSD1306_Write_Cmd(0xA8); //--set multiplex ratio(1 to 64)
    SSD1306_Write_Cmd(0x3F); //MUX=63 显示63行
    SSD1306_Write_Cmd(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    SSD1306_Write_Cmd(0xD3); //-set display offset
    SSD1306_Write_Cmd(0x00); //-not offset
    SSD1306_Write_Cmd(0xD5); //--set display clock divide ratio/oscillator frequency
    SSD1306_Write_Cmd(0xF0); //--set divide ratio
    SSD1306_Write_Cmd(0xD9); //--set pre-charge period
    SSD1306_Write_Cmd(0x22); 
    SSD1306_Write_Cmd(0xDA); //--set com pins hardware configuration
    SSD1306_Write_Cmd(0x12); //启用左右反置
    SSD1306_Write_Cmd(0xDB); //--set vcomh
    SSD1306_Write_Cmd(0x20); //0x20,0.77xVcc
    SSD1306_Write_Cmd(0x8D); //--set DC-DC enable
    SSD1306_Write_Cmd(0x14); //
    SSD1306_Write_Cmd(0xAF); //--turn on SSD1306 panel

    /* Clear screen */
    SSD1306_Fill(SSD1306_COLOR_BLACK);    

    /* Update screen */
    SSD1306_UpdateScreen();
    
    /* Set default values */
    SSD1306.CurrentX = 0;
    SSD1306.CurrentY = 0;
    
    /* Initialized OK */
    SSD1306.Initialized = 1;
}

/* 填充显存 */
void SSD1306_Fill(SSD1306_COLOR_t color) 
{
    /* Set memory */
    memset(SSD1306_Buffer, (color == SSD1306_COLOR_BLACK) ? 0x00 : 0xff, sizeof(SSD1306_Buffer));
}


/* 更新屏幕显示,当我们把显示缓冲区数据改写了之后,必须调用这个函数才能在屏幕更新显示 */
void SSD1306_UpdateScreen(void) 
{
    for (uint8_t page = 0; page < 8; page++)     //每页写数据
    {
        SSD1306_Write_Cmd(0xB0 + page);            //Page0-Page7
        SSD1306_Write_Cmd(0x00);                //设置列起始地址低位
        SSD1306_Write_Cmd(0x10);                //设置列起始地址高位

        /* Write multi data */
        SSD1306_Write_MultiData(&SSD1306_Buffer[SSD1306_WIDTH * page], SSD1306_WIDTH);
    }
}

/* 反转屏幕显示(就是黑白颜色对调) */
void SSD1306_ToggleInvert(void) 
{
    /* Toggle invert */
    SSD1306.Inverted = !SSD1306.Inverted;

    /* Do memory toggle */
    for (uint16_t i = 0; i < sizeof(SSD1306_Buffer); i++) 
    {
        SSD1306_Buffer[i] = ~SSD1306_Buffer[i];
    }
}

void SSD1306_GotoXY(uint16_t x, uint16_t y) 
{
    /* Set write pointers */
    SSD1306.CurrentX = x;
    SSD1306.CurrentY = y;
}

/* 绘制任意点的像素,所有绘图函数的基础 */
void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color) 
{
    if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) 
    {
        return;    /* Error */
    }

    /* Check if pixels are inverted */
    if (SSD1306.Inverted) 
    {
        color = (SSD1306_COLOR_t)!color;
    }

    /* Set color */
    if (color == SSD1306_COLOR_WHITE) 
    {
        SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);    //(y/8)*SSD1306_WIDTH表示第几页,x+(y/8)*SSD1306_WIDTH表示第几页第几偏移
    }
    else 
    {
        SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));    //(y/8)*SSD1306_WIDTH表示第几页,x+(y/8)*SSD1306_WIDTH表示第几页第几偏移
    }
}

/*
 * 函数作用  : 在屏幕上显示一个字符
 * 参数ch    : 要显示的字符
 * 参数Font  : 字体
 * 参数color : 颜色
 * 返回值    : ch
 */
char SSD1306_Putc(char ch, TM_FontDef_t* Font, SSD1306_COLOR_t color) 
{
    uint32_t y, b, x;

    /* 检查屏幕的可用空间 */
    if (SSD1306_WIDTH <= (SSD1306.CurrentX + Font->FontWidth) || SSD1306_HEIGHT <= (SSD1306.CurrentY + Font->FontHeight)) 
    {
        return 0;    /* 越界 */
    }

    /* Go through font */
    for (y = 0; y < Font->FontHeight; y++) 
    {
        //ascii码表sp在32位置,ch-32表示字符的偏移,Font->data以字符的偏移开始。b依次指向该字符的每个数值
        //如字符为'A',b依次等于0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000
        b = Font->data[(ch - 32) * Font->FontHeight + y];    
        for (x = 0; x < Font->FontWidth; x++) 
        {
            if ((b << x) & 0x8000) 
            {
                SSD1306_DrawPixel(SSD1306.CurrentX + x, (SSD1306.CurrentY + y), (SSD1306_COLOR_t) color);
            } 
            else 
            {
                SSD1306_DrawPixel(SSD1306.CurrentX + x, (SSD1306.CurrentY + y), (SSD1306_COLOR_t)!color);
            }
        }
    }

    /* Increase pointer */
    SSD1306.CurrentX += Font->FontWidth;

    /* Return character written */
    return ch;
}

/*
 * 函数作用  : 在屏幕上显示一个字符串
 * 参数str   : 要显示的字符串
 * 参数Font  : 字体
 * 参数color : 颜色
 * 返回值    : 无
 */
char SSD1306_Puts(char* str, TM_FontDef_t* Font, SSD1306_COLOR_t color) 
{
    /* Write characters */
    while (*str) 
    {
        /* Write character by character */
        if (SSD1306_Putc(*str, Font, color) != *str) 
        {
            return *str;    /* Return error */
        }

        str++;                /* Increase string pointer */
    }

    /* Everything OK, zero should be returned */
    return *str;
}

/*
 * 函数作用  : 在屏幕上绘制任意线
 * 参数x0、y0: 起点坐标
 * 参数x1、y1: 终点坐标
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t color) 
{
    int16_t dx, dy, sx, sy, err, e2, i, tmp;

    /* 坐标溢出检查 */
    if (x0 >= SSD1306_WIDTH) 
    {
        x0 = SSD1306_WIDTH - 1;
    }
    if (x1 >= SSD1306_WIDTH) 
    {
        x1 = SSD1306_WIDTH - 1;
    }
    if (y0 >= SSD1306_HEIGHT) 
    {
        y0 = SSD1306_HEIGHT - 1;
    }
    if (y1 >= SSD1306_HEIGHT) 
    {
        y1 = SSD1306_HEIGHT - 1;
    }

    dx = (x0 < x1) ? (x1 - x0) : (x0 - x1);    //横距
    dy = (y0 < y1) ? (y1 - y0) : (y0 - y1);    //纵距
    sx = (x0 < x1) ? 1 : -1;                //1表示x1在右
    sy = (y0 < y1) ? 1 : -1;                //1表示y1在下
    err = ((dx > dy) ? dx : -dy) / 2;

    if (dx == 0)                             //竖直线
    {
        if (y1 < y0) 
        {
            tmp = y1;
            y1 = y0;
            y0 = tmp;
        }                                    //永远y1在下

        if (x1 < x0) 
        {
            tmp = x1;
            x1 = x0;
            x0 = tmp;
        }                                    //永远x1在右

        /* Vertical line */
        for (i = y0; i <= y1; i++) 
        {
            SSD1306_DrawPixel(x0, i, color);
        }

        /* Return from function */
        return;
    }

    if (dy == 0)                             //横直线
    {
        if (y1 < y0) 
        {
            tmp = y1;
            y1 = y0;
            y0 = tmp;
        }                                    //永远y1在下

        if (x1 < x0) 
        {
            tmp = x1;
            x1 = x0;
            x0 = tmp;
        }                                    //永远x1在右

        /* Horizontal line */
        for (i = x0; i <= x1; i++) 
        {
            SSD1306_DrawPixel(i, y0, color);
        }

        /* Return from function */
        return;
    }

    while (1)     //非横线或竖线
    {
        SSD1306_DrawPixel(x0, y0, color);
        if (x0 == x1 && y0 == y1)             //一个点
        {
            break;
        }
        e2 = err;
        if (e2 > -dx) 
        {
            err -= dy;
            x0 += sx;
        }
        if (e2 < dy) 
        {
            err += dx;
            y0 += sy;
        }
    }
}

/*
 * 函数作用  : 在屏幕上绘制四边形
 * 参数  x、y: 起点坐标
 * 参数  w、h: 宽度、高度
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c) 
{
    /* Check input parameters */
    if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) 
    {
        /* Return error */
        return;
    }

    /* Check width and height */
    if ((x + w) >= SSD1306_WIDTH) 
    {
        w = SSD1306_WIDTH - x;
    }
    if ((y + h) >= SSD1306_HEIGHT) 
    {
        h = SSD1306_HEIGHT - y;
    }

    /* Draw 4 lines */
    SSD1306_DrawLine(x, y, x + w, y, c);         /* Top line */
    SSD1306_DrawLine(x, y + h, x + w, y + h, c); /* Bottom line */
    SSD1306_DrawLine(x, y, x, y + h, c);         /* Left line */
    SSD1306_DrawLine(x + w, y, x + w, y + h, c); /* Right line */
}

/*
 * 函数作用  : 四角形填充
 * 参数  x、y: 起点坐标
 * 参数  w、h: 宽度、高度
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawFilledRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c) 
{
    uint8_t i;

    /* Check input parameters */
    if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) 
    {
        /* Return error */
        return;
    }

    /* Check width and height */
    if ((x + w) >= SSD1306_WIDTH) 
    {
        w = SSD1306_WIDTH - x;
    }
    if ((y + h) >= SSD1306_HEIGHT) 
    {
        h = SSD1306_HEIGHT - y;
    }

    /* Draw lines */
    for (i = 0; i <= h; i++) 
    {
        /* Draw lines */
        SSD1306_DrawLine(x, y + i, x + w, y + i, c);
    }
}

/*
 * 函数作用  : 绘制三角形
 * 参数x1、y1: 三点坐标之一
 * 参数x2、y2: 三点坐标之一
 * 参数x3、y3: 三点坐标之一
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color) 
{
    /* Draw lines */
    SSD1306_DrawLine(x1, y1, x2, y2, color);
    SSD1306_DrawLine(x2, y2, x3, y3, color);
    SSD1306_DrawLine(x3, y3, x1, y1, color);
}

/*
 * 函数作用  : 三角形填充
 * 参数x1、y1: 三点坐标之一
 * 参数x2、y2: 三点坐标之一
 * 参数x3、y3: 三点坐标之一
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawFilledTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color) 
{
    int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
            yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
            curpixel = 0;

    deltax = ABS(x2 - x1);
    deltay = ABS(y2 - y1);
    x = x1;
    y = y1;

    if (x2 >= x1) 
    {
        xinc1 = 1;
        xinc2 = 1;
    } 
    else 
    {
        xinc1 = -1;
        xinc2 = -1;
    }

    if (y2 >= y1) 
    {
        yinc1 = 1;
        yinc2 = 1;
    } 
    else 
    {
        yinc1 = -1;
        yinc2 = -1;
    }

    if (deltax >= deltay) 
    {
        xinc1 = 0;
        yinc2 = 0;
        den = deltax;
        num = deltax / 2;
        numadd = deltay;
        numpixels = deltax;
    } 
    else 
    {
        xinc2 = 0;
        yinc1 = 0;
        den = deltay;
        num = deltay / 2;
        numadd = deltax;
        numpixels = deltay;
    }

    for (curpixel = 0; curpixel <= numpixels; curpixel++) 
    {
        SSD1306_DrawLine(x, y, x3, y3, color);

        num += numadd;
        if (num >= den) 
        {
            num -= den;
            x += xinc1;
            y += yinc1;
        }
        x += xinc2;
        y += yinc2;
    }
}

/*
 * 函数作用  : 绘制圆形
 * 参数x0、y0: 圆心坐标
 * 参数        r: 圆半径
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c) 
{
    int16_t f = 1 - r;
    int16_t ddF_x = 1;
    int16_t ddF_y = -2 * r;
    int16_t x = 0;
    int16_t y = r;

    SSD1306_DrawPixel(x0, y0 + r, c);
    SSD1306_DrawPixel(x0, y0 - r, c);
    SSD1306_DrawPixel(x0 + r, y0, c);
    SSD1306_DrawPixel(x0 - r, y0, c);

    while (x < y) 
    {
        if (f >= 0) 
        {
            y--;
            ddF_y += 2;
            f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;

        SSD1306_DrawPixel(x0 + x, y0 + y, c);
        SSD1306_DrawPixel(x0 - x, y0 + y, c);
        SSD1306_DrawPixel(x0 + x, y0 - y, c);
        SSD1306_DrawPixel(x0 - x, y0 - y, c);

        SSD1306_DrawPixel(x0 + y, y0 + x, c);
        SSD1306_DrawPixel(x0 - y, y0 + x, c);
        SSD1306_DrawPixel(x0 + y, y0 - x, c);
        SSD1306_DrawPixel(x0 - y, y0 - x, c);
    }
}

/*
 * 函数作用  : 圆形填充
 * 参数x0、y0: 圆心坐标
 * 参数        r: 圆半径
 * 参数c     : 绘制的颜色
 * 返回值    : 无
 */
void SSD1306_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c) 
{
    int16_t f = 1 - r;
    int16_t ddF_x = 1;
    int16_t ddF_y = -2 * r;
    int16_t x = 0;
    int16_t y = r;

    SSD1306_DrawPixel(x0, y0 + r, c);
    SSD1306_DrawPixel(x0, y0 - r, c);
    SSD1306_DrawPixel(x0 + r, y0, c);
    SSD1306_DrawPixel(x0 - r, y0, c);
    SSD1306_DrawLine(x0 - r, y0, x0 + r, y0, c);

    while (x < y) 
    {
        if (f >= 0) 
        {
            y--;
            ddF_y += 2;
            f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;

        SSD1306_DrawLine(x0 - x, y0 + y, x0 + x, y0 + y, c);
        SSD1306_DrawLine(x0 + x, y0 - y, x0 - x, y0 - y, c);

        SSD1306_DrawLine(x0 + y, y0 + x, x0 - y, y0 + x, c);
        SSD1306_DrawLine(x0 + y, y0 - x, x0 - y, y0 - x, c);
    }
}

/*
 * 函数作用      : 水平滚动
 * 参数direction: 水平滚动方向
 * 参数可选项     :右-0x26、左-0x27
 * 返回值        : 无
 */
void ssd1306_HorizontalScrolling(uint8_t direction)
{
    SSD1306_Write_Cmd(0x2E);        //关闭滚动
    SSD1306_Write_Cmd(direction);   //水平向左或者右滚动
    SSD1306_Write_Cmd(0x00);        //虚拟字节
    SSD1306_Write_Cmd(0x00);        //起始页 0
    SSD1306_Write_Cmd(0x07);        //滚动时间间隔
    SSD1306_Write_Cmd(0x07);        //终止页 7
    SSD1306_Write_Cmd(0x00);        //虚拟字节
    SSD1306_Write_Cmd(0xFF);        //虚拟字节
    SSD1306_Write_Cmd(0x2F);        //开启滚动
}

/*
 * 函数作用      : 垂直滚动
 * 参数direction: 垂直滚动方向
 * 参数可选项     :右+垂直-0x29、左+垂直-0x2A
 * 返回值        : 无
 */
void ssd1306_VerticalScrolling(uint8_t direction)
{
    SSD1306_Write_Cmd(0x2E);        //关闭滚动
    SSD1306_Write_Cmd(direction);   //滚动+左右
#if Drive_SSD1315
    SSD1306_Write_Cmd(0x01);        // 0x00 水平滚动关闭,0x01 水平滚动开启
#else    
    SSD1306_Write_Cmd(0x00);        //虚拟字节
#endif
    
    SSD1306_Write_Cmd(0x00);        //起始页 0
    SSD1306_Write_Cmd(0x07);        //滚动时间间隔
    SSD1306_Write_Cmd(0x07);        //终止页 7
    SSD1306_Write_Cmd(0x01);        //垂直滚动偏移量
    
#if Drive_SSD1315
    SSD1306_Write_Cmd(0x00);        // 第0列开始
    SSD1306_Write_Cmd(0x7F);        // 第127列结束
#endif
    SSD1306_Write_Cmd(0x2F);        //开启滚动
}

/*
 * 函数作用  : 指定位置绘制图片
 * 参数x0、y0: 起点坐标
 * 参数x1、y1: 终点坐标
 * 参数 color: 颜色。0-反白显示、1-正常显示    
 * 参数        p: 图片存储地址
 * 返回值    : 无
 */
void OLED_Draw_Picture(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, SSD1306_COLOR_t color, unsigned const char pictureBuf[])
{
    char         temp, t;
    uint32_t     buf_pos = 0;
    uint8_t     x, y;
  
    //y轴8区域,涉足区域补全
    if( (y1 - y0) % 8 != 0 ) 
        y1 = (y1-y0)/8 + 1; 
    else 
        y1 = y1 / 8;
    
    for( y = 0 ; y < y1 ; y++ )
    {
        for( x = x0 ; x < x1 ; x++ )
        {      
            temp = pictureBuf[buf_pos++]; 
            for( t = 0 ; t < 8 ; t++ )
            {
                if( temp & 0x01 )
                    SSD1306_DrawPixel(x, y*8+y0+t, color);
                else 
                    SSD1306_DrawPixel(x, y*8+y0+t, !color);
                temp >>= 1;                    
            }
        }
    }
}

/*
 * 函数作用  : 指定位置绘制图片
 * 参数x0、y0: 起点坐标
 * 参数x1、y1: 终点坐标
 * 参数      BMP: 图片存储地址
 * 返回值    : 无
 */
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, unsigned const char BMP[])
{
    uint32_t     bufpos = 0;
    uint8_t     x, page;
 
    if(y1%8==0)
        page = y1/8;
    else
        page = y1/8 + 1;
    
    for(uint8_t i=y0/8 ; i<page ; i++)
    {
        SSD1306_GotoXY(x0, i);
        for(x=x0 ; x<=x1 ; x++)
        {
            SSD1306_Write_Data(BMP[bufpos++]);
        }
    }
}

driver_oled.h(SSD1315驱动)

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DRIVE_IT_H
#define __DRIVE_IT_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "drive_fonts.h"
/* Private includes ----------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/
typedef enum {
    SSD1306_COLOR_BLACK = 0x00, /*!< Black color, no pixel */
    SSD1306_COLOR_WHITE = 0x01  /*!< Pixel is set. Color depends on LCD */
} SSD1306_COLOR_t;
/* Exported constants --------------------------------------------------------*/

/* Exported macro ------------------------------------------------------------*/
#define Drive_SSD1306    0
#define Drive_SSD1315    1

/* Exported functions prototypes ---------------------------------------------*/
void SSD1306_ON(void);
void SSD1306_OFF(void); 
void SSD1306_Init(void); 

void SSD1306_Fill(SSD1306_COLOR_t color);     //全屏填充
void SSD1306_UpdateScreen(void); 

void SSD1306_ToggleInvert(void); 
void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color);
void SSD1306_GotoXY(uint16_t x, uint16_t y);

char SSD1306_Putc(char ch, TM_FontDef_t* Font, SSD1306_COLOR_t color);
char SSD1306_Puts(char* str, TM_FontDef_t* Font, SSD1306_COLOR_t color);
void SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t c);
void SSD1306_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c);
void SSD1306_DrawFilledRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c);
void SSD1306_DrawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color);
void SSD1306_DrawFilledTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color);
void SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c);
void SSD1306_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c);
void ssd1306_HorizontalScrolling(uint8_t direction);
void ssd1306_VerticalScrolling(uint8_t direction);
void OLED_Draw_Picture(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, SSD1306_COLOR_t color, unsigned const char pictureBuf[]);
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, unsigned const char BMP[]);
void OLED_DrawBMP_FullScreen(unsigned const char BMP[]);
/* Private defines -----------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* __DRIVE_IT_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

drive_fonts.c文件

/**
 * |----------------------------------------------------------------------
 * | Copyright (C) Tilen MAJERLE, 2014
 * |
 * | This program is free software: you can redistribute it and/or modify
 * | it under the terms of the GNU General Public License as published by
 * | the Free Software Foundation, either version 3 of the License, or
 * | any later version.
 * |
 * | This program is distributed in the hope that it will be useful,
 * | but WITHOUT ANY WARRANTY; without even the implied warranty of
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * | GNU General Public License for more details.
 * |
 * | You should have received a copy of the GNU General Public License
 * | along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * |----------------------------------------------------------------------
 */
#include "drive_fonts.h"
#include <string.h>

/*
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
*/

const uint16_t TM_Font7x10 [] = {
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // sp
    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000,  // !
    0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // "
    0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000,  // #
    0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000,  // $
    0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000,  // %
    0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000,  // &
    0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // '
    0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800,  // (
    0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000,  // )
    0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // *
    0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000,  // +
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000,  // ,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000,  // -
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,  // .
    0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000,  // /
    0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // 0
    0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // 1
    0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000,  // 2
    0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000,  // 3
    0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000,  // 4
    0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000,  // 5
    0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // 6
    0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000,  // 7
    0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // 8
    0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000,  // 9
    0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,  // :
    0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000,  // ;
    0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000,  // <
    0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000,  // =
    0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000,  // >
    0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000,  // ?
    0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000,  // @
    0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000,  // A
    0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000,  // B
    0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000,  // C
    0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000,  // D
    0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000,  // E
    0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000,  // F
    0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // G
    0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000,  // H
    0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000,  // I
    0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000,  // J
    0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000,  // K
    0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000,  // L
    0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000,  // M
    0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000,  // N
    0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // O
    0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000,  // P
    0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000,  // Q
    0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000,  // R
    0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000,  // S
    0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // T
    0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // U
    0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000,  // V
    0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000,  // W
    0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000,  // X
    0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // Y
    0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000,  // Z
    0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800,  // [
    0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000,  /* \ */
    0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000,  // ]
    0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // ^
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00,  // _
    0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // `
    0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000,  // a
    0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000,  // b
    0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000,  // c
    0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000,  // d
    0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000,  // e
    0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // f
    0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800,  // g
    0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000,  // h
    0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // i
    0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000,  // j
    0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000,  // k
    0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000,  // l
    0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000,  // m
    0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000,  // n
    0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000,  // o
    0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000,  // p
    0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400,  // q
    0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000,  // r
    0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000,  // s
    0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000,  // t
    0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000,  // u
    0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000,  // v
    0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000,  // w
    0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000,  // x
    0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000,  // y
    0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000,  // z
    0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800,  // {
    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,  // |
    0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000,  // }
    0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,  // ~
};

const uint16_t TM_Font11x18 [] = {
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // sp
    0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // !
    0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // "
    0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, 0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000,   // #
    0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, 0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000,   // $
    0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, 0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000,   // %
    0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, 0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000,   // &
    0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // '
    0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080,   // (
    0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000,   // )
    0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // *
    0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // +
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800,   // ,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // -
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // .
    0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000,   // /
    0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 0
    0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000,   // 1
    0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, 0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000,   // 2
    0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 3
    0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, 0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000,   // 4
    0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 5
    0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 6
    0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, 0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000,   // 7
    0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, 0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 8
    0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // 9
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // :
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800,   // ;
    0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, 0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // <
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // =
    0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, 0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // >
    0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // ?
    0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, 0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000,   // @
    0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, 0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000,   // A
    0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, 0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000,   // B
    0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // C
    0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000,   // D
    0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000,   // E
    0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000,   // F
    0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, 0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000,   // G
    0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000,   // H
    0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000,   // I
    0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // J
    0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, 0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000,   // K
    0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000,   // L
    0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000,   // M
    0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, 0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000,   // N
    0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // O
    0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000,   // P
    0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000,   // Q
    0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000,   // R
    0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, 0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // S
    0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // T
    0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // U
    0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000,   // V
    0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, 0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000,   // W
    0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, 0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000,   // X
    0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // Y
    0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000,   // Z
    0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00,   // [
    0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000,   /* \ */
    0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00,   // ]
    0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // ^
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000,   // _
    0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // `
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, 0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000,   // a
    0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000,   // b
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // c
    0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000,   // d
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // e
    0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000,   // f
    0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00,   // g
    0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000,   // h
    0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000,   // i
    0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00,   // j
    0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, 0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000,   // k
    0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000,   // l
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000,   // m
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000,   // n
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // o
    0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000,   // p
    0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180,   // q
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000,   // r
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, 0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000,   // s
    0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000,   // t
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000,   // u
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000,   // v
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, 0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000,   // w
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000,   // x
    0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000,   // y
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, 0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000,   // z
    0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, 0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380,   // {
    0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600,   // |
    0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800,   // }
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, 0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // ~
};

const uint16_t TM_Font16x26 [] = {
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [sp]
    0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!]
    0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["]
    0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, 0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, 0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#]
    0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, 0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$]
    0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, 0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, 0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%]
    0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, 0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, 0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&]
    0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [']
    0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F80, 0x0780, 0x0780, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(]
    0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x00F8, 0x00F0, 0x00F0, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)]
    0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, 0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, 0xFFFF, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.]
    0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x0780, 0x0780, 0x0F00, 0x0F00, 0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/]
    0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, 0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0]
    0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1]
    0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, 0x0780, 0x0F00, 0x1E00, 0x3E00, 0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2]
    0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, 0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, 0x001E, 0x001E, 0x001E, 0x003E, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3]
    0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, 0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, 0xFFFF, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4]
    0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, 0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, 0x001E, 0x003E, 0x003E, 0x003C, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5]
    0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, 0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6]
    0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x0F80, 0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7]
    0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, 0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, 0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8]
    0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, 0x001E, 0x001E, 0x003E, 0x003C, 0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, 0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, 0x3F00, 0x0FC0, 0x03F0, 0x00FC, 0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, 0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, 0x007E, 0x01F8, 0x07E0, 0x1F80, 0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>]
    0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, 0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?]
    0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, 0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, 0x73FF, 0x7BFF, 0x79F7, 0x3C00, 0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@]
    0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, 0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, 0x3FFE, 0x3FFF, 0x781F, 0x780F, 0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A]
    0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B]
    0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7C00, 0x7C00, 0x3E00, 0x3F00, 0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C]
    0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x781F, 0x781E, 0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D]
    0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E]
    0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F]
    0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, 0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, 0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G]
    0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H]
    0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I]
    0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x0078, 0x0078, 0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J]
    0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, 0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K]
    0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L]
    0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, 0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, 0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M]
    0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, 0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, 0x78FF, 0x78FF, 0x787F, 0x783F, 0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N]
    0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O]
    0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P]
    0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q]
    0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R]
    0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, 0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, 0x001F, 0x000F, 0x000F, 0x201F, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S]
    0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T]
    0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U]
    0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V]
    0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, 0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W]
    0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, 0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, 0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X]
    0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y]
    0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, 0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, 0x0F80, 0x0F00, 0x1E00, 0x3E00, 0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z]
    0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[]
    0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, 0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x00F0, 0x00F0, 0x0078, 0x0078, 0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\]
    0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []]
    0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, 0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, 0x380F, 0x780F, 0x7807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_]
    0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, 0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, 0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a]
    0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, 0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x3E00, 0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c]
    0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, 0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, 0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e]
    0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, 0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g]
    0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h]
    0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i]
    0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j]
    0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, 0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k]
    0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x7C1F, 0x3C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, 0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, 0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, 0x781E, 0x781E, 0x7C1E, 0x7C3E, 0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, 0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, 0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, 0x00FE, 0x003E, 0x001E, 0x001E, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s]
    0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, 0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, 0x0F78, 0x0F78, 0x0FF0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, 0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, 0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, 0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, 0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, 0x0F80, 0x1F00, 0x1E00, 0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z]
    0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{]
    0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|]
    0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}]
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, 0xF1FF, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~]
};

TM_FontDef_t TM_Font_7x10 = {
    7,
    10,
    TM_Font7x10
};

TM_FontDef_t TM_Font_11x18 = {
    11,
    18,
    TM_Font11x18
};

TM_FontDef_t TM_Font_16x26 = {
    16,
    26,
    TM_Font16x26
};

char* TM_FONTS_GetStringSize(char* str, TM_FONTS_SIZE_t* SizeStruct, TM_FontDef_t* Font) 
{
    /* Fill settings */
    SizeStruct->Height = Font->FontHeight;
    SizeStruct->Length = Font->FontWidth * strlen(str);

    /* Return pointer */
    return str;
}

drive_fonts.h文件

/**
 * @author  Tilen MAJERLE
 * @email   tilen@majerle.eu
 * @website http://stm32f4-discovery.net
 * @link
 * @version v1.2
 * @ide     Keil uVision
 * @license GNU GPL v3
 * @brief   Fonts library for LCD libraries
 *
@verbatim
   ----------------------------------------------------------------------
    Copyright (C) Tilen MAJERLE, 2015

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------
@endverbatim
 */
#ifndef TM_FONTS_H
#define TM_FONTS_H 120

/* C++ detection */
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup TM_STM32F4xx_Libraries
 * @{
 */

/**
 * @defgroup TM_FONTS
 * @brief    Fonts library for all my LCD libraries
 * @{
 *
 * Default fonts library. It is used in all LCD based libraries.
 *
 * \par Supported fonts
 *
 * Currently, these fonts are supported:
 *  - 7 x 10 pixels
 *  - 11 x 18 pixels
 *  - 16 x 26 pixels
 *
 * \par Changelog
 *
@verbatim
 Version 1.2
  - May 24, 2015
  - Added support for string length and height

 Version 1.0
  - First release
@endverbatim
 *
 * \par Dependencies
 *
@verbatim
 - STM32F4xx
 - defines.h
 - string.h
@endverbatim
 */
#include "stm32f1xx.h"

/**
 * @defgroup TM_LIB_Typedefs
 * @brief    Library Typedefs
 * @{
 */

/**
 * @brief  Font structure used on my LCD libraries
 */
typedef struct {
    uint8_t FontWidth;    /*!< Font width in pixels */
    uint8_t FontHeight;   /*!< Font height in pixels */
    const uint16_t* data; /*!< Pointer to data font data array */
} TM_FontDef_t;

/**
 * @brief  String length and height
 */
typedef struct {
    uint16_t Length;      /*!< String length in units of pixels */
    uint16_t Height;      /*!< String height in units of pixels */
} TM_FONTS_SIZE_t;

/**
 * @}
 */

/**
 * @defgroup TM_FONTS_FontVariables
 * @brief    Library font variables
 * @{
 */

/**
 * @brief  7 x 10 pixels font size structure
 */
extern TM_FontDef_t TM_Font_7x10;

/**
 * @brief  11 x 18 pixels font size structure
 */
extern TM_FontDef_t TM_Font_11x18;

/**
 * @brief  16 x 26 pixels font size structure
 */
extern TM_FontDef_t TM_Font_16x26;

/**
 * @}
 */

/**
 * @defgroup TM_FONTS_Functions
 * @brief    Library functions
 * @{
 */

/**
 * @brief  Calculates string length and height in units of pixels depending on string and font used
 * @param  *str: String to be checked for length and height
 * @param  *SizeStruct: Pointer to empty @ref TM_FONTS_SIZE_t structure where informations will be saved
 * @param  *Font: Pointer to @ref TM_FontDef_t font used for calculations
 * @retval Pointer to string used for length and height
 */
char* TM_FONTS_GetStringSize(char* str, TM_FONTS_SIZE_t* SizeStruct, TM_FontDef_t* Font);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

/* C++ detection */
#ifdef __cplusplus
}
#endif

#endif

 

APP部分

省略文章来源地址https://www.toymoban.com/news/detail-675407.html

 

工程实现

省略

到了这里,关于基于STM32的传送带系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于stm32的智能输液系统设计

    目录 一、原理简述 二、系统硬件设计 1.stm32f103核心控制器 2.电机驱动模块 3.LCD显示屏模块 4.注射液滴速检测模块 5.湿度检测模块 6.声光报警模块 7.按键控制模块 三、系统软件设计 1.声光报警模块及电机驱动软件设计 2.LCD显示屏软件设计 3.注射液滴速检测模块软件设计 4.湿度

    2024年01月16日
    浏览(35)
  • 基于stm32的厨房安全系统设计

    基于STM32的厨房安全系统设计 摘要 随着智能家居的普及,厨房安全系统成为家庭安全的重要组成部分。本文提出了一种基于STM32的厨房安全系统设计方案,旨在检测厨房内的烟雾、可燃气体和火焰,确保家庭安全。系统通过传感器采集数据,STM32微控制器处理数据,实现报警

    2024年02月19日
    浏览(26)
  • 硬件课程设计:基于STM32的多功能播放器之MP3音乐播放

    3.1.1 设计思路         音乐播放是手机等电子产品最常见的功能,也是最具娱乐性的功能,在该模块中,我先从SD卡中读取已存放的MP3音乐文件,然后将读取的字节流依次送人VS1053中进行解码和播放,同时从VS1053相关的寄存器中读取音乐播放时间,在LCD上实时显示歌曲信息。

    2023年04月08日
    浏览(29)
  • 基于stm32的指纹识别系统设计与系统

    详细功能模块描述: 1、系统硬件模块设计与实现: 指纹通过指纹识别模块采集处理;并将处理后的指纹特征值等以数据包的形式发给主控模块;主控模块发送指令包对指纹识别模块进行控制以及对键盘模块、报警模块、液晶显示模块进行控制。在液晶显示屏上显示录入和识别

    2024年02月06日
    浏览(34)
  • 基于STM32的倒车雷达系统设计

    目录 前言 一、绪论 1.1 设计背景 1.2 设计内容 二、系统硬件设计 2.1 硬件系统框图 2.2 主控制电路 2.3 超声波电路 2.4 OLED显示电路 2.5 键盘输入电路 2.6 声光报警模块电路 三、系统软件设计 3.1 系统主程序设计 3.2 OLED显示程序设计 3.3 键盘设定程序设计 四、系统调试 4.1 硬件调

    2024年02月06日
    浏览(35)
  • 【基于STM32的水质检测系统设计】

    最近参加校赛做的基于STM32的水质检测系统设计,进行一些简单记录吧 一、题目要求 二、硬件材料 STM32F103C8T6最小系统一块 x1 语音模块(SU-03T) x1 ESP8266wifi模块 x1 BMP180大气压模块 x1 DS18B20温度传感器带探针 x1 蜂鸣器 x1 TFT3.5显示屏 x1 TDS传感器水电导率 x1 不可充式电极探头P

    2024年02月07日
    浏览(36)
  • 基于STM32超声波测距系统设计

    随着社会的发展和科技的进步,人们对测距的要求越来越高,特别是在一些要求实时测距的场合,传统的测距方式已经无法满足人们的需求,而超声波测距由于其非接触和实时反馈的特点在生活中得到广泛应用。 本系统硬件部分由电源模块、控制模块、显示模块、报警模块、

    2024年02月04日
    浏览(47)
  • STM32项目--基于STM32的办公室安保(智能家居)系统设计

    设计一套基于STM32的办公室安防系统,系统内部包括门禁系统、灾害报警系统、人脸识别系统和交互中心四个子系统。 门禁系统:主要实现对门禁卡的存储和读取并识别已存储卡片的信息并控制开门,如读取卡片为未存储卡片则报警。 灾害探测:系统本项目简单化使用了温湿

    2024年02月05日
    浏览(37)
  • 基于STM32室内空气净化监测系统设计

    ** 单片机设计介绍,1649基于STM32室内空气净化监测系统设计   信息时代的进步,我们的生活潜移默化中发生了许多改变,物联网作为一个 陌生但是早已熟悉的新词也在引领着如今的潮流,但物联网又该如何理解呢? 互联网作为主流,是世界的信息数据得以迅速的进行交互

    2024年02月08日
    浏览(38)
  • 基于STM32的智能饮水机系统设计

    随着智能化的迅速发展,人们对于生活中的各类设备也越来越有智能化的需求,其中智能饮水机是一种比较常见的设备。智能饮水机不仅可以提供饮用水,还可以通过智能化的技术满足人们对于水质、水温、出水量等方面的需求。因此,当前设计了一种基于STM32的智能饮水机

    2024年02月08日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包