0.96寸OLED在STM32f103上实现滚动显示长字符

一、了解OLED屏的滚屏命令

本OLED屏的芯片类型:SSD1306
详细命令的介绍,请查找SSD1306-OLED驱动中文手册或者参考下面链接进行了解
https://wlink.blog.csdn.net/article/details/81329770

1.水平左右移

OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
OLED_WR_Byte(0x26,OLED_CMD);        //水平向左或者右滚动 26/27
OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7
OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

2.垂直和水平滚动

OLED_WR_Byte(0x2e,OLED_CMD);        //关闭滚动
OLED_WR_Byte(0x29,OLED_CMD);        //水平垂直和水平滚动左右 29/2a
OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
OLED_WR_Byte(0x07,OLED_CMD);        //终止页 1
OLED_WR_Byte(0x01,OLED_CMD);        //垂直滚动偏移量
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

说明:设置前需要先发关闭滚动的指令2E,接着发滚动指令29(向右)或2A(向左)。紧接着发5条参数设置指令,用来设置持续水平滚动参数和决定滚动开始页,结束页,滚动速度和垂直滚动偏移的,最后才发开始滚屏指令2F。
注意:在发送开始滚屏(2F)前要先传输好显示数据,如果在滚屏的时候传输显示数据RAM中的内容可能被损坏,无法正常显示。

二、对显示文字进行取模

1.下载字模软件
下载链接:
http://download.eeworld.com.cn/detail/jacksonluo/16285
2. 获取相应文字的点阵十六进制表示

"欢",0x00,0x80,0x00,0x80,0xFC,0x80,0x04,0xFC,0x05,0x04,0x49,0x08,0x2A,0x40,0x14,0x40,
  0x10,0x40,0x28,0xA0,0x24,0xA0,0x45,0x10,0x81,0x10,0x02,0x08,0x04,0x04,0x08,0x02,/*"欢",0*/
"迎",0x00,0x00,0x20,0x80,0x13,0x3C,0x12,0x24,0x02,0x24,0x02,0x24,0xF2,0x24,0x12,0x24,
  0x12,0x24,0x12,0xB4,0x13,0x28,0x12,0x20,0x10,0x20,0x28,0x20,0x47,0xFE,0x00,0x00,/*"迎",0*/
"来",0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x01,0x00,0x11,0x10,0x09,0x10,0x09,0x20,  
  0xFF,0xFE,0x03,0x80,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00,0x01,0x00,/*"来",0*/
"到",0x00,0x04,0xFF,0x84,0x08,0x04,0x10,0x24,0x22,0x24,0x41,0x24,0xFF,0xA4,0x08,0xA4,  
  0x08,0x24,0x08,0x24,0x7F,0x24,0x08,0x24,0x08,0x04,0x0F,0x84,0xF8,0x14,0x40,0x08,/*"到",0*/
"博",0x20,0x50,0x20,0x48,0x2F,0xFE,0x20,0x40,0x27,0xFC,0xFC,0x44,0x27,0xFC,0x24,0x44,
  0x27,0xFC,0x24,0x44,0x20,0x08,0x2F,0xFE,0x22,0x08,0x21,0x08,0x21,0x28,0x20,0x10,/*"博",0*/
"客",0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x88,0x04,0x0F,0xF0,0x10,0x20,0x2C,0x40,  
  0x03,0x80,0x1C,0x70,0xE0,0x0E,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,/*"客",0*/

三、主要代码

mian函数

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{	
	delay_init();	    	       //延时函数初始化	  
	NVIC_Configuration(); 	   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)
	OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
    OLED_WR_Byte(0x27,OLED_CMD);        //水平向左或者右滚动 26/27
    OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
	OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
	OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
	OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7
	OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
	OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节
	TEST_MainPage();
	OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
}

显示数据函数

void TEST_MainPage(void)
{	
	GUI_ShowCHinese(10,20,16,"欢迎来到博客",1);
	delay_ms(1500);		
	delay_ms(1500);
}

效果显示
在这里插入图片描述

四、小结

整个命令的使用,其实并不复杂。但是,自己却花了好久时间去弄,最后,才发现是代码的放置出现了问题。对应滚动停止命令,一旦使用后,其ROM中的内容就会被破坏,需要重新对内容进行传输保存,否则就不能够实现滚屏的效果。不过这种方式,好像只能够完成将内容写好后,显示在同一个面板上的滑动。

五、参考资料

  1. SSD1306-0.96寸oled屏-滚动指令介绍
  2. 0.96oled屏,驱动ssd1306 一些不常用的命令用法和效果
  3. 完整代码链接
  • 28
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是使用STM32F103单片机和0.96OLED屏幕的I2C程序。 首先,需要确保你已经连接好了OLED屏幕和STM32F103单片机,然后将以下代码复制到你的STM32F103开发板的IAR或Keil等开发环境中进行编译: ```c #include "stm32f10x.h" #include "stm32f10x_i2c.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #define OLED_I2C_ADDR 0x78 void OLED_I2C_Init(void); void OLED_I2C_WriteCmd(uint8_t I2C_Command); void OLED_I2C_WriteData(uint8_t I2C_Data); void OLED_Init(void); void OLED_Clear(void); void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); void OLED_Set_Pos(uint8_t x, uint8_t y); void Delay(__IO uint32_t nCount); int main(void) { OLED_I2C_Init(); OLED_Init(); OLED_Clear(); OLED_ShowString(0,2,"Hello,World!",16); OLED_ShowString(0,4,"这是一行中文测试",16); while(1); } void OLED_I2C_Init(void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB,&GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000; I2C_Init(I2C1,&I2C_InitStructure); I2C_Cmd(I2C1,ENABLE); } void OLED_I2C_WriteCmd(uint8_t I2C_Command) { while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1,OLED_I2C_ADDR,I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1,0x00); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,I2C_Command); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1,ENABLE); Delay(200); } void OLED_I2C_WriteData(uint8_t I2C_Data) { while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1,OLED_I2C_ADDR,I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1,0x40); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,I2C_Data); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1,ENABLE); Delay(200); } void OLED_Init(void) { Delay(200); OLED_I2C_WriteCmd(0xAE); OLED_I2C_WriteCmd(0x00); OLED_I2C_WriteCmd(0x10); OLED_I2C_WriteCmd(0x40); OLED_I2C_WriteCmd(0x81); OLED_I2C_WriteCmd(0xCF); OLED_I2C_WriteCmd(0xA1); OLED_I2C_WriteCmd(0xC8); OLED_I2C_WriteCmd(0xA6); OLED_I2C_WriteCmd(0xA8); OLED_I2C_WriteCmd(0x3F); OLED_I2C_WriteCmd(0xD3); OLED_I2C_WriteCmd(0x00); OLED_I2C_WriteCmd(0xD5); OLED_I2C_WriteCmd(0x80); OLED_I2C_WriteCmd(0xD9); OLED_I2C_WriteCmd(0xF1); OLED_I2C_WriteCmd(0xDA); OLED_I2C_WriteCmd(0x12); OLED_I2C_WriteCmd(0xDB); OLED_I2C_WriteCmd(0x40); OLED_I2C_WriteCmd(0x20); OLED_I2C_WriteCmd(0x02); OLED_I2C_WriteCmd(0x8D); OLED_I2C_WriteCmd(0x14); OLED_I2C_WriteCmd(0xA4); OLED_I2C_WriteCmd(0xA6); OLED_I2C_WriteCmd(0xAF); OLED_Clear(); } void OLED_Clear(void) { uint8_t i,j; for(i=0;i<8;i++) { OLED_I2C_WriteCmd(0xb0+i); OLED_I2C_WriteCmd(0x00); OLED_I2C_WriteCmd(0x10); for(j=0;j<128;j++) { OLED_I2C_WriteData(0); } } } void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size) { uint8_t c = 0,i = 0,j = 0; while (chr[j]!='\0') { c = chr[j] - 32; if(x > 120) { x = 0; y++; } OLED_Set_Pos(x,y); for(i=0;i<Char_Size;i++) { OLED_I2C_WriteData(F8X16[c*16+i]); } OLED_Set_Pos(x,y+1); for(i=0;i<Char_Size;i++) { OLED_I2C_WriteData(F8X16[c*16+i+8]); } x += Char_Size; j++; } } void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no) { uint8_t t,adder = 0; OLED_Set_Pos(x , y); for(t=0;t<16;t++) { OLED_I2C_WriteData(CHS[2*no][t]); adder += 1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_I2C_WriteData(CHS[2*no+1][t]); adder += 1; } } void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_I2C_WriteCmd(0xb0+y); OLED_I2C_WriteCmd(((x&0xf0)>>4)|0x10); OLED_I2C_WriteCmd((x&0x0f)|0x01); } void Delay(__IO uint32_t nCount) { for(;nCount!=0;nCount--); } ``` 在上面的代码中,我们首先定义了OLED屏幕的I2C地址,然后实现了一些函数来初始化OLED屏幕、清屏、显示字符串、显示汉字等。在主函数中,我们初始化OLED屏幕并显示一些测试信息。 请注意,这只是一个示例程序,你需要根据你的具体需求进行修改。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值