本帖最后由 gaoyang9992006 于 2021-11-26 11:33 编辑
[url=home.php?mod=space&uid=760190]@21小跑堂 #申请原创#[/url]
很多人觉得这很容易嘛,但是我看了论坛好多人发的贴,不是没提供完整的工程,就是虽然移植成功了,但是不够完美,这里我将提供一份完美移植的方法,就是让代码修改最少,基于cubeMX配置好I2C后,就不用动工程的结构就搞定。
我先提供一份OLED的驱动文件。
这里我使用的是一片0.91寸,128×32分辨率的OLED,一共4给腿,依次是:GND,VCC,SCL,SDA。
0.91OLED-SSD1306-STM32HAL.rar
(6.28 KB)
我们在cubeMX中配置自己使用的单片机,选择一组没有被占用的I2C端口,简单的配置后,生成工程代码,这个cubeMX应该大家都会用了吧,我就不重复说了,也可以下载我最后的工程自己看。
比如我这里选择I2C2,端口对应为:SCL----PC4;SDA---PA8
然后我们在工程中新建一个虚拟文件夹,起个名字OLED,将上面提供的OLED文件添加进来,最好全部添加进来,这样我们也方便查看。
图形化配置工具给我们生成的代码已经给我们创建好了I2C2的操作句柄结构体变量,因此我们在oled.c中想直接使用i2c2,只需要引用这个变量就行了,这个时候我们可以在oled.h中新增一句:
extern I2C_HandleTypeDef hi2c2;
我们通过关键字extern告诉oled.c中引用的hi2c2,在其他文件中定义了,这样就不用那么麻烦了,我看有人还重新拆分了配置好的文件,那样就麻烦大了,容易出错。
然后就是在oled.c中实现oled的基本操作写数据与写命令
void OLED_Write_cmd(uint8_t cmd)
{
HAL_I2C_Mem_Write(&hi2c2, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0x100);
}
void OLED_Write_data(uint8_t data)
{
HAL_I2C_Mem_Write(&hi2c2, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, &data, 1, 0x100);
}
这里给大家看看为何使用这个写内存的库函数,下面这给函数的原型。
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] Write an amount of data in blocking mode to a specific memory address
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @param DevAddress Target device address: The device 7 bits address value
* in datasheet must be shifted to the left before calling the interface
* @param MemAddress Internal memory address
* @param MemAddSize Size of internal memory address
* @param pData Pointer to data buffer
* @param Size Amount of data to be sent
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
现在我们只需要把头文件包含进来,然后在工程配置中,将oled.c所在的文件夹包含进来即可了。然后我们在main.c中就可以直接使用oled.c中的驱动函数驱动oled显示内容了
你学会了吗,简单的两步即可完成移植:
1,用关键字告诉oled操作函数i2c的控制句柄结构体在其他文件已经创建好了
2,然后通过HAL库函数完成oled的基本操作映射。
|