极客秀
搜索

STM32中用硬件I2C替换繁杂的软件I2C以及如何显示字符串

上一期我们介绍了如何使用GPIO翻转模拟软件I2C实现OLED屏幕的显示,本期我们介绍如何利用STM32中的硬件I2C来提高我们的传输效率以及字符串显示。

本期源码可以私信作者或者主页添加作者联系方式获取

首先我们需要在CubeMX中开启我们对应的I2C设备。

//#define USE_SOFEWARE_I2C#define USE_HADEWARE_I2C

我们用宏定义来区分我们的I2C驱动是选用软件I2C还是硬件I2C。


uint8_t MY_IIC_WriteCommand(uint8_t Address,uint8_t Command,uint8_t Data){  #ifdef USE_SOFEWARE_I2C   MY_IIC_START();//I2C开始  MY_IIC_Write(Address);//发送设备地址  if(!MY_IIC_WaitACK())//如果没有响应  {    return 0;//返回失败  }  MY_IIC_Write(Command);//发送命令  if(!MY_IIC_WaitACK())//如果没有响应  {    return 0;//返回失败  }  MY_IIC_Write(Data);//发送数据  if(!MY_IIC_WaitACK())//如果没有响应  {    return 0;//返回失败  }  MY_IIC_STOP();//停止通信    #endif    #ifdef USE_HADEWARE_I2C    HAL_I2C_Mem_Write(&hi2c2,OLED_ADDRESS,Command,I2C_MEMADD_SIZE_8BIT,&Data,1,100);    #endif}

在上一期的基础上,我们让软件I2C和硬件I2C的运行根据宏定义来区分。

在硬件I2C的定义中,我们只需要添加I2C的传输函数


  #ifdef USE_HADEWARE_I2C  HAL_I2C_Mem_Write(&hi2c2,OLED_ADDRESS,Command,I2C_MEMADD_SIZE_8BIT,&Data,1,100);  #endif

本来按理来说是要使用HAL_I2C_Master_Transmit这个函数的,因为这个函数更像是主机到设备的传输函数,不过之所以使用HAL_I2C_Mem_Write这个函数,因为它的参数结构:硬件I2C句柄,设备地址,寄存器地址,数据宽度,数据缓存区,数据长度,超时时间。

这个结构更像是三段式发命令,所以我比较喜欢这个,用前者的话需要把命令和数据两个值合并,比较啰嗦。

………………

………………

然后就没了,硬件I2C就是如此简单。

接下来我们聊一聊OLED显示字符是如何实现的。在OLED中显示字符,我们需要先将屏幕分块,我们知道屏幕总共分为12864的像素点,
我们将一块区域块作为每个字符的显示,例如我们选择8
6的区域作为每个字符块。(取模软件默认,可以自己设置)

我们可以利用字库取模软件来生成字库信息。


取模方式修改为纵向取模,获得我们的十六进制数据。并且创建一个文件来存放这些数据。(这里偷个懒用现成的字库,为了防止观感,直接放到最后去了)


// 在OLED.H中void OLED_ShowChar(uint8_t x, uint8_t y, char chr);void OLED_ShowString(uint8_t x, uint8_t y, const char *str);

接着我们在OLED.H文件中添加显示字符和字符串的函数。


// 显示单个字符void OLED_ShowChar(uint8_t x, uint8_t y, char chr){    uint8_t i;    // 检查坐标是否有效    if(x > 127 || y > 63) return;        // 计算字符在字库中的索引(支持ASCII码从0x20到0x7F)    if(chr < 0x20 || chr > 0x7F) return;    uint8_t char_index = chr - 0x20;  // 0x20是空格的ASCII码        // 计算显示的页地址    uint8_t page = y / 8;    uint8_t y_offset = y % 8;        // 设置显示位置    MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_PAGE_ADDR | page);    MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_COL_LOW | (x & 0x0F));    MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_COL_HIGH | (x >> 4));        // 写入6列数据    for(i = 0; i < 6; i++) {        uint8_t data = F6x8[char_index][i];        MY_IIC_WriteCommand(OLED_ADDRESS, OLED_DATA, data);    }        // 如果字符跨页显示    if(y_offset != 0 && page < 7) {        MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_PAGE_ADDR | (page + 1));        MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_COL_LOW | (x & 0x0F));        MY_IIC_WriteCommand(OLED_ADDRESS, OLED_CMD, OLED_SET_COL_HIGH | (x >> 4));                // 写入第二页的数据        for(i = 0; i < 6; i++) {            uint8_t data = F6x8[char_index][i] >> (8 - y_offset);            MY_IIC_WriteCommand(OLED_ADDRESS, OLED_DATA, data);        }    }}  
// 显示字符串void OLED_ShowString(uint8_t x, uint8_t y, const char *str){    uint8_t x_pos = x;        while(*str != '') {        // 检查是否超出显示范围        if(x_pos > 122) break;  // 留出6像素的宽度                // 显示当前字符        OLED_ShowChar(x_pos, y, *str);                // 移动到下一个字符位置        x_pos += 6;  // 每个字符宽度为6像素        str++;    }}

我们先完成字符填充函数,在字符填充函数的基础上增加字符串显示函数。

编写测试函数。

**
**

** 下期我们介绍如何利用硬件I2C配合DMA大幅度提高刷新效率 **


字库函数如下:


#ifndef __FRONT_H__#include "OLED.h"  
  
const unsigned char F6x8[][6] =    {  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp  0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !  0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "  0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #  0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $  0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %  0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &  0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '  0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (  0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )  0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *  0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +  0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,  0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -  0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .  0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /  0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0  0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1  0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2  0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3  0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4  0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5  0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6  0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7  0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8  0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9  0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :  0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;  0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <  0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =  0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >  0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?  0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @  0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A  0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B  0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C  0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D  0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E  0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F  0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G  0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H  0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I  0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J  0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K  0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L  0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M  0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N  0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O  0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P  0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q  0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R  0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S  0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T  0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U  0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V  0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W  0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X  0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y  0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z  0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [  0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55  0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]  0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^  0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _  0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '  0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a  0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b  0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c  0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d  0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e  0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f  0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g  0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h  0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i  0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j  0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k  0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l  0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m  0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n  0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o  0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p  0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q  0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r  0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s  0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t  0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u  0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v  0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w  0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x  0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y  0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z  0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines};  
#endif
1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容