【雅特力开发板 AT32F421 测评】7、库加寄存器联合点亮OLED
[复制链接]
我也从万能地淘宝,买了个OLED,只不过五一假期没有收到,但上班确收到了。
晚上,打开,喜欢的不得了,于是,很想短时间内点亮它。
首先,打资料,给卖家汪汪,要资料,可是卖家没有及时回,于是我问渡娘,SH1107,找了半天也没有头绪。
正当我一愁莫展之际,从一个网站上看到了这样的文字:
STM32 library for working with OLEDs based on SSD1306, supports I2C and 4-wire SPI. It also works with SH1106, SH1107 and SSD1309 which are compatible with SSD1306.
意思是说,SSD1306同SH1106,SH1107是兼容地,我又去找SSD1306。
正当我找到SSD1306的程序,想要动手时,卖家给我发来了,资料的链接。
我于是就扔开SSD1306去看卖家的程序,没有想到竟然是寄存器版的。
于是我参考坛友的程序及卖家的程序搞个又用库又不用库,又用寄存器,又用库。
程序如下:
#include "at32f4xx.h"
/**********SPI引脚分配,连接oled屏,更具实际情况修改*********/
#define IIC_SCK_PIN 9//5
#define IIC_SDA_PIN 8//6
#define OLED_COLUMN_NUMBER 64
#define OLED_LINE_NUMBER 128
#define OLED_PAGE_NUMBER (OLED_LINE_NUMBER/8)
#define OLED_COLUMN_OFFSET 32
#define OLED_LINE_OFFSET 0
/**********SPI引脚分配,连接oled屏,更具实际情况修改*********/
#define IIC_SCK_0 GPIOB->BRE=0X0200 // 设置sck接口到PB5 清零
#define IIC_SCK_1 GPIOB->BSRE=0X0200 //置位
#define IIC_SDA_0 GPIOB->BRE=0X0100 // 设置SDA接口到PB6
#define IIC_SDA_1 GPIOB->BSRE=0X0100
const unsigned char *point;
unsigned char ACK=0;
const unsigned char OLED_init_cmd[25]=
{
0xAE,//关闭显示
0xD5,//设置时钟分频因子,震荡频率
0x50, //[3:0],分频因子;[7:4],震荡频率 默认0x50
0xA8,//设置驱动路数
0X7f,//默认(1/64)
0xD3,//设置显示偏移
0X00,//默认为0
0x40,//设置显示开始行 [5:0],行数.
0x8D,//电荷泵设置
0x14,//bit2,开启/关闭
0x20,//设置内存地址模式
0x02,//[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
0xA0,//段重定义设置,bit0:0,0->0;1,0->127; A1
0xC0,//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 C0 翻转显示 C8
0xDA,//设置COM硬件引脚配置
0x12,//[5:4]配置
0x81,//对比度设置
0x7f,//1~255;默认0X7F (亮度设置,越大越亮)
0xD9,//设置预充电周期
0x22,//[3:0],PHASE 1;[7:4],PHASE 2;
0xDB,//设置VCOMH 电压倍率
0x37,//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
0xA4,//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
0xA6,//设置显示方式;bit0:1,反相显示;0,正常显示
0xAF,//开启显示
};
void IO_init(void)
{
GPIO_InitType GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOB, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8|GPIO_Pins_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;//GPIO_Pull_NOPULL;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void delay_us(unsigned int _us_time)
{
unsigned char x=0;
for(;_us_time>0;_us_time--)
{
x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;
x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;
x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;x++;
}
}
void delay_ms(unsigned int _ms_time)
{
unsigned int i,j;
for(i=0;i<_ms_time;i++)
{
for(j=0;j<900;j++)
{;}
}
}
/**************************IIC模块发送函数************************************************
*************************************************************************/
//写入 最后将SDA拉高,以等待从设备产生应答
void IIC_write(unsigned char date)
{
unsigned char i, temp;
temp = date;
for(i=0; i<8; i++)
{ IIC_SCK_0;
if ((temp&0x80)==0)
IIC_SDA_0;
else IIC_SDA_1;
temp = temp << 1;
delay_us(1);
IIC_SCK_1;
delay_us(1);
}
IIC_SCK_0;
delay_us(1);
IIC_SDA_1;
delay_us(1);
IIC_SCK_1;
// 不需要应答
// if (READ_SDA==0)
// ACK = 1;
// else ACK =0;
delay_us(1);
IIC_SCK_0;
delay_us(1);
}
//启动信号
//SCL在高电平期间,SDA由高电平向低电平的变化定义为启动信号
void IIC_start()
{
IIC_SDA_1;
delay_us(1);
IIC_SCK_1;
delay_us(1); //所有操作结束释放SCL
IIC_SDA_0;
delay_us(3);
IIC_SCK_0;
IIC_write(0x78);
}
//停止信号
//SCL在高电平期间,SDA由低电平向高电平的变化定义为停止信号
void IIC_stop()
{
IIC_SDA_0;
delay_us(1);
IIC_SCK_1;
delay_us(3);
IIC_SDA_1;
}
void OLED_send_cmd(unsigned char o_command)
{
IIC_start();
IIC_write(0x00);
IIC_write(o_command);
IIC_stop();
}
void OLED_send_data(unsigned char o_data)
{
IIC_start();
IIC_write(0x40);
IIC_write(o_data);
IIC_stop();
}
void Column_set(unsigned char column)
{
column = column+OLED_COLUMN_OFFSET;
OLED_send_cmd(0x10|(column>>4)); //设置列地址高位
OLED_send_cmd(0x00|(column&0x0f)); //设置列地址低位
}
void Page_set(unsigned char page)
{
page = page+(OLED_LINE_OFFSET/8);
OLED_send_cmd(0xb0+page);
}
void OLED_clear(void)
{
unsigned char page,column;
for(page=0;page<OLED_PAGE_NUMBER;page++) //page loop
{
Page_set(page);
Column_set(0);
for(column=0;column<OLED_COLUMN_NUMBER;column++) //column loop
{
OLED_send_data(0x00);
}
}
}
void OLED_full(void)
{
unsigned char page,column;
for(page=0;page<OLED_PAGE_NUMBER;page++) //page loop
{
Page_set(page);
Column_set(0);
for(column=0;column<OLED_COLUMN_NUMBER;column++) //column loop
{
OLED_send_data(0xff);
}
}
}
void OLED_init(void)
{
unsigned char i;
for(i=0;i<25;i++)
{
OLED_send_cmd(OLED_init_cmd);
}
}
void Picture_display(const unsigned char *ptr_pic)
{
unsigned char page,column;
for(page=0;page<OLED_PAGE_NUMBER;page++) //page loop
{
Page_set(page);
Column_set(0);
for(column=0;column<OLED_COLUMN_NUMBER;column++) //column loop
{
OLED_send_data(*ptr_pic++);
}
}
}
void Picture_ReverseDisplay(const unsigned char *ptr_pic)
{
unsigned char page,column,data;
for(page=0;page<OLED_PAGE_NUMBER;page++) //page loop
{
Page_set(page);
Column_set(0);
for(column=0;column<OLED_COLUMN_NUMBER;column++) //column loop
{
data=*ptr_pic++;
data=~data;
OLED_send_data(data);
}
}
}
以后,遇到SH1107,直接管脚驱动的,考一下就行。
运行效果见下图:
|