stm32专题三十:12864 IIC驱动

发布者:yunhui最新更新时间:2021-10-29 来源: eefocus关键字:stm32  IIC驱动 手机看文章 扫描二维码
随时随地手机看文章

1 IIC发送数据 / 命令时序

2 12864 图形显示(显存)


RAM的大小是128×64位,RAM分为8页,从PAGE0到PAGE7,用于单色128x64点阵显示。

3 行列设置


1 设置起始行坐标(设置页)


命令 0XB0 ~ 0XB7 用于设置分页,所以我们显示的分页要 + 偏移(0XB0)


2 设置起始列坐标

4 制作字模


1 字模软件设置方式:

2 生成的字模的批处理:


生成的字模如图所示,我们要转成 0X00 这种格式:

使用 sublime 这个软件,可以进行批处理(先全选,然后再 快捷键 Ctrl + Shift + L):

字模生成完毕。


驱动程序如下所示:


bsp_12864.c


#include "bsp_12864.h"

#include "bsp_font.h"

 

/**

  * @brief 向 oled 写入命令

  */

void OLED_Write_Cmd(uint8_t cmd)

{

    uint8_t temp = cmd;

    HAL_I2C_Mem_Write(&I2C_X, OLED_ADDR, CMD_CTRL, I2C_MEMADD_SIZE_8BIT, &temp, 1, 0xFFFF);

}

 

/**

  * @brief 向 oled 写入数据

  */

void OLED_Write_Data(uint8_t data)

{

    uint8_t temp = data;

    HAL_I2C_Mem_Write(&I2C_X, OLED_ADDR, DATA_CTRL, I2C_MEMADD_SIZE_8BIT, &temp, 1, 0xFFFF);

}

 

/**

  * @brief 设置 oled 写入坐标 

  * @param x    列坐标:0 ~ 127

  * @param y    行坐标:0 ~ 63

  */

void OLED_Set_Pos(uint8_t x, uint8_t y)

{

    OLED_Write_Cmd(0xb0 + y);                 // 写入页地址

    OLED_Write_Cmd((x & 0x0f));               // 写入列的地址 (低半字节)

    OLED_Write_Cmd(((x & 0xf0) >> 4) | 0x10); // 写入列的地址(高半字节)

}

 

/**

  * @brief oled 清屏

  */

void OLED_Clear(void)

{

    unsigned char page, row;

    for (page = 0; page < 8; page++)

    {

        OLED_Write_Cmd(0xb0 + page); // 从0 ~ 7页依次写入

        OLED_Write_Cmd(0x00);        // 低位列地址

        OLED_Write_Cmd(0x10);        // 高位列地址

        for (row = 0; row < 128; row++)

        {

            OLED_Write_Data(0X00);

        }

    }

}

 

void OLED_Init(void)

{

    HAL_Delay(100); // 延迟(必须要有)

 

    OLED_Write_Cmd(0xAE); // 关闭显示

 

    OLED_Write_Cmd(0x00); // 设置低列地址

    OLED_Write_Cmd(0x10); // 设置高列地址

    OLED_Write_Cmd(0x40); // 设置起始行地址

    OLED_Write_Cmd(0xB0); // 设置页地址

 

    OLED_Write_Cmd(0x81); // 对比度设置,可设置亮度

    OLED_Write_Cmd(0xFF); // 265

 

    OLED_Write_Cmd(0xA1); // 设置段(SEG)的起始映射地址

    OLED_Write_Cmd(0xA6); // 正常显示;0xa7逆显示

 

    OLED_Write_Cmd(0xA8); // 设置驱动路数(16~64)

    OLED_Write_Cmd(0x3F); // 64duty

 

    OLED_Write_Cmd(0xC8); // 重映射模式,COM[N-1]~COM0扫描

 

    OLED_Write_Cmd(0xD3); // 设置显示偏移

    OLED_Write_Cmd(0x00); // 无偏移

 

    OLED_Write_Cmd(0xD5); // 设置震荡器分频

    OLED_Write_Cmd(0x80); // 使用默认值

 

    OLED_Write_Cmd(0xD9); // 设置 Pre-Charge Period

    OLED_Write_Cmd(0xF1); // 使用官方推荐值

 

    OLED_Write_Cmd(0xDA); // 设置 com pin configuartion

    OLED_Write_Cmd(0x12); // 使用默认值

 

    OLED_Write_Cmd(0xDB); // 设置 Vcomh,可调节亮度(默认)

    OLED_Write_Cmd(0x40); // 使用官方推荐值

 

    OLED_Write_Cmd(0x8D); // 设置OLED电荷泵

    OLED_Write_Cmd(0x14); // 开显示

 

    OLED_Write_Cmd(0xAF); // 开启OLED面板显示

}

 

/**

  * @brief 将 OLED 从休眠中唤醒

  */

void OLED_ON(void)

{

    OLED_Write_Cmd(0X8D); // 设置电荷泵

    OLED_Write_Cmd(0X14); // 开启电荷泵

    OLED_Write_Cmd(0XAF); // OLED 唤醒

}

 

/**

  * @brief 让OLED休眠

  */

void OLED_OFF(void)

{

    OLED_Write_Cmd(0X8D); // 设置电荷泵

    OLED_Write_Cmd(0X10); // 关闭电荷泵

    OLED_Write_Cmd(0XAE); // OLED 休眠

}

 

/**

  * @brief 显示 bsp_font.h 中的ASCII字符 字体为 Consolas

  * @param x:  起始点列坐标:0 ~ 127

  *        y:   起始点页坐标:0 ~ 7

  * @param *ch:要显示的字符串

  */

void OLED_Show_String(uint8_t x, uint8_t y, uint8_t *ch)

{

    uint8_t i = 0, c = 0, k = 0;

 

    while (ch[k] != '')

    {

        c = ch[k] - ' ';

        if (x > 120)

        {

            x = 0;

            y++;

        }

        OLED_Set_Pos(x, y);

        for (i = 0; i < 8; i++)

        {

            OLED_Write_Data(Consolas_8X16[c * 16 + i]);

        }

 

        OLED_Set_Pos(x, y + 1);

        for (i = 0; i < 8; i++)

        {

            OLED_Write_Data(Consolas_8X16[c * 16 + i + 8]);

        }

        x += 8;

        k++;

    }

}

 

/**

  * @brief 显示 bsp_font.h 中的汉字(宋体)

  * @param x:  起始点列坐标:0 ~ 127

  *        y:   起始点页坐标:0 ~ 7

  * @param n:  汉字在字库中的索引

  */

void OLED_Show_CN(uint8_t x, uint8_t y, uint8_t n)

{

    uint8_t i = 0;

    uint16_t k = 32 * n;

    OLED_Set_Pos(x, y);

    for (i = 0; i < 16; i++)

    {

        OLED_Write_Data(CN_16X16[k]);

        k += 1;

    }

    OLED_Set_Pos(x, y + 1);

    for (i = 0; i < 16; i++)

    {

        OLED_Write_Data(CN_16X16[k]);

        k += 1;

    }

}

 

#if 0

// 以下是测试程序

 

  OLED_Init();

 

  OLED_Clear();

 

  for (i = 3; i < 7; i++)

  {

    OLED_Show_CN((i - 3) * 16, 2, i);     // 测试显示中文

  }

  OLED_Show_String(0, 4, "hello world");  // 测试 8*16 字符

 

#endif

bsp_12864.h


#ifndef __BSP_12864_H

#define __BSP_12864_H

 

#include "i2c.h"

 

#define I2C_X           hi2c1

 

#define OLED_ADDR       0x78

#define CMD_CTRL        0X00

#define DATA_CTRL       0X40

 

void OLED_Init(void);

void OLED_Clear(void);

void OLED_ON(void);

void OLED_OFF(void);

void OLED_Show_String(uint8_t x, uint8_t y, uint8_t *ch);

void OLED_Show_CN(uint8_t x, uint8_t y, uint8_t n);

 

#endif /* __BSP_12864_H */

字库文件(部分):


bsp_font.h


// ASCII Consolas字体

const unsigned char Consolas_8X16[] = {

    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

    0x00,0x00,0x00,0xf8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x1b,0x00,0x00,0x00,

    0x00,0x00,0x78,0x08,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

    0x00,0x40,0xe0,0x50,0x40,0xf0,0x50,0x40,0x00,0x04,0x1f,0x04,0x04,0x1f,0x04,0x00,

    0x00,0xe0,0xb0,0x10,0xf8,0x10,0x10,0x00,0x00,0x10,0x10,0x7f,0x11,0x13,0x0e,0x00,

    0x30,0x58,0x48,0x70,0x80,0x60,0x30,0x08,0x10,0x18,0x04,0x03,0x0c,0x12,0x12,0x0c,

    0x00,0x60,0xf0,0x90,0x90,0x70,0x00,0x00,0x04,0x1f,0x11,0x11,0x16,0x1c,0x1f,0x10,

    0x00,0x00,0x00,0x78,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

    0x00,0x00,0x80,0xe0,0x30,0x08,0x00,0x00,0x00,0x00,0x07,0x3f,0x60,0xc0,0x00,0x00,

    0x00,0x00,0x08,0x10,0xe0,0x80,0x00,0x00,0x00,0x00,0x80,0x60,0x38,0x0f,0x00,0x00,

    0x00,0x80,0xa0,0x60,0xd8,0x60,0x90,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,

    0x00,0x00,0x00,0xc0,0xc0,0x00,0x00,0x00,0x00,0x02,0x02,0x1f,0x1f,0x02,0x02,0x02,

    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x58,0x38,0x00,0x00,0x00,

    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x00,0x00,

    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,

    0x00,0x00,0x00,0x00,0xc0,0x70,0x18,0x00,0x00,0x20,0x18,0x06,0x01,0x00,0x00,0x00,

    0x00,0xe0,0x30,0x10,0x10,0xb0,0xe0,0x80,0x00,0x0f,0x1a,0x13,0x11,0x18,0x0f,0x03,

    0x00,0x60,0x20,0x30,0xf0,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1f,0x10,0x10,0x00,

    0x00,0x20,0x10,0x10,0x10,0xf0,0xe0,0x00,0x00,0x10,0x18,0x14,0x12,0x11,0x10,0x00,

    0x00,0x10,0x10,0x10,0x10,0xf0,0x60,0x00,0x00,0x10,0x11,0x11,0x11,0x19,0x0e,0x00,

    0x00,0x00,0x80,0x60,0x30,0xf0,0x00,0x00,0x04,0x07,0x05,0x04,0x04,0x1f,0x04,0x04,

    0x00,0xf0,0xf0,0x10,0x10,0x10,0x10,0x00,0x00,0x11,0x11,0x11,0x11,0x19,0x0f,0x00,

    0x00,0xc0,0x60,0x30,0x90,0x10,0x10,0x00,0x00,0x0f,0x19,0x11,0x10,0x11,0x0f,0x00,

    0x00,0x10,0x10,0x10,0x10,0xd0,0x70,0x00,0x00,0x00,0x10,0x1c,0x07,0x01,0x00,0x00,

    0x00,0x60,0xb0,0x90,0x10,0x90,0xe0,0x00,0x00,0x0e,0x12,0x11,0x11,0x13,0x0e,0x00,

    0x00,0xe0,0x30,0x10,0x10,0x30,0xe0,0x00,0x00,0x11,0x11,0x12,0x12,0x09,0x07,0x00,

    0x00,0x00,0x00,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,

    0x00,0x00,0x00,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x40,0x58,0x38,0x00,0x00,0x00,

    0x00,0x00,0x00,0x80,0x80,0x40,0x00,0x00,0x00,0x02,0x03,0x05,0x08,0x18,0x10,0x00,

    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,0x05,0x05,0x05,0x05,0x00,

    0x00,0x00,0x40,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x07,0x02,0x00,

    0x00,0x00,0x08,0x18,0x10,0xf0,0xe0,0x00,0x00,0x00,0x00,0x1b,0x01,0x00,0x00,0x00,

    0x80,0xe0,0x10,0x88,0x88,0x88,0x10,0xe0,0x3f,0x60,0x8f,0x91,0x88,0x9f,0x08,0x0f,

    0x00,0x00,0xc0,0x70,0x30,0xe0,0x00,0x00,0x10,0x1e,0x07,0x04,0x04,0x05,0x0f,0x18,

    0x00,0xf0,0x10,0x10,0x10,0xb0,0xe0,0x00,0x00,0x1f,0x11,0x11,0x11,0x11,0x0e,0x00,

    0x00,0xc0,0x20,0x10,0x10,0x10,0x10,0x00,0x00,0x0f,0x18,0x10,0x10,0x10,0x10,0x00,

    0x00,0xf0,0x10,0x10,0x10,0x30,0xe0,0x80,0x00,0x1f,0x10,0x10,0x10,0x08,0x0f,0x03,

    0x00,0xf0,0xf0,0x10,0x10,0x10,0x10,0x00,0x00,0x1f,0x1f,0x11,0x11,0x11,0x11,0x00,

[1] [2]
关键字:stm32  IIC驱动 引用地址:stm32专题三十:12864 IIC驱动

上一篇:stm32专题二十九:Flash 读写保护
下一篇:stm32专题三十一:电源管理

推荐阅读最新更新时间:2024-11-13 10:09

STM32串口USART1中断接收和中断发送
  先贴出中断函数:    view plain copy   void USART1_IRQHandler(void){   IF (USART_GetiTStatus(USART1, USART_IT_RXNE) != RESET) {   USART_ClearITPendingBit(USART1, USART_IT_RXNE);   USART1_Buffer =USART_ReceiveData(USART1); //USART1_Buffesh是一个自己定义的接收数组   if(i 3){   SendFlag = 1;   }   }   if(USART_GetITStatus(USART1, USART_I
[单片机]
STM32 NVIC中断优先级:抢占优先级&响应优先级区别
首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。 分组配置是在寄存器SCB- AIRCR中配置: 抢占优先级 & 响应优先级区别: 1. 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。 2. 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。 3. 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个 先执行。 4. 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先 执行; 等级越低,优先级越高。
[单片机]
<font color='red'>STM32</font> NVIC中断优先级:抢占优先级&响应优先级区别
STM32学习笔记之使用库函数驱动LED灯
一、熟悉GPIO结构体 以下这个结构体是我从官方手册中获取的: view plain copy print? typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef; 二、编写程序步骤 1、首先定义一个GPIO_InitTypeDef的结构体,给结构体起一个名字 GPIO_InitStructure; view plain copy print? GPIO_initTypeDef GPIO_initStructure ; 2、初始化RCC时钟 RCC
[单片机]
<font color='red'>STM32</font>学习笔记之使用库函数<font color='red'>驱动</font>LED灯
使用变参函数实现STM32串口的简易printf功能
第一,去掉了原来使用的goto语句,因为C语言中除了错误处理之外,不建议使用goto语句; 第二,fmt和pnt的含义更加明确,它们始终指向下一个需要处理的字符和变参; 第三,整理了程序结构,使它更加清晰。 void uart_printf(USART_TypeDef *USARTx, char *fmt, ...) { char *pnt = (char *)&fmt + sizeof(fmt); int len; while (*fmt != '') { if (*fmt == '%') { if (*(fmt + 1) == 'c') { uart_send_byte(
[单片机]
基于stm32处理器的PWM 异步驱动蜂鸣器
这两天应工作需求研究了一下M3处理器的PWM(脉宽调制)实现对蜂鸣器的异步控制。鉴于阻塞式对蜂鸣器的控制比较耗时,影响用户体验,因此对原有阻塞式控制方案进行了改善,提出了异步控制蜂鸣器的实现方法。以下主要对实现中需要注意的重点知识以及所遇到的问题进行了讨论。 PWM波利用M3的定时器产生,出于对平台资源的有效利用,选择定时器1用来输出脉宽调制信号。这就引出了本文的重点,M3定时器的应用。 M3的定时器资源一共有11个,其中两个高级定时器(Timer1和Timer8)、4个通用定时器(Timer2-Timer5)、2个普通定时器(Timer6-Timer7)、2个看门狗定时器以及一个SysTick定时器。相对于普通定时器来说,高
[单片机]
基于<font color='red'>stm32</font>处理器的PWM 异步<font color='red'>驱动</font>蜂鸣器
STM32:GPIO基础与对应管脚操作库函数
USE_STDPERIPH_DRIVER, STM32F10X_HD STM32固件库Libraries\CMSIS\Core\CM3\startup\arm中启动文件的文件名英文缩写意义: cl:互联型产品, stm32f105/107 系列 vl:超值型产品, stm32f100 系列 xl:超高密度(容量) 产品, stm32f101/103 系列 ld:低密度产品, FLASH 小于 64K md:中等密度产品, FLASH=64 or 128 hd:高密度产品, FLASH 大于 128 GPIO_TypeDef * GPIOx; //定义一个 GPIO_TypeDef 型结构体指针 GPIOx GPIOx = G
[单片机]
STM32】STM32CubeMX教程--功能介绍
功能介绍: 我们首先看下CubeMx的主界面,模块分类大体是这样,我们接下来一一讲解。 已存在工程 Open Existing Projects:打开项目工程 新建工程 ·Start My project from MCU:从MCU开始我的项目 ·Start My project from STBoard:从ST开发板开始我的项目 ·Start My project from Cross Selector:从交叉选择器启动我的项目 软件包管理 ·CHECK FOR UPDATE:检查更新 ·INSTALL/REMOVE:安装/移除
[单片机]
【<font color='red'>STM32</font>】STM32CubeMX教程--功能介绍
关于stm32的USB和SPI疑似存在干扰的问题
情况是这样的,最近做一个项目,使用的是stm32f103RE单片机,使用到了单片机的usb口和SPI1。USB虚拟成串口向上位机发送数据,已经通过修改官网的例程调试通过,SPI1也能正常工作。但是当把两个功能做在同一个工程中时,发现出现了一些问题:USB想上位机发送一段时间后会停止发送(我的程序是在while中一直发送);USB发送会出现乱码。当我把SPI1的读写函数注释掉之后上述问题有消失了。这个问题纠结了我好几天了,不知道各位高手能不能帮我解答解答。 调试发现程序停在了while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);中,但是之前没有添加USB功能模块
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved