📄 ssd1303.c
字号:
#include <string.h>
#include "SSD1303.h"
#ifdef IC_SSD1303_ENABLE
static GRAMBUF grambuf;
static unsigned char grambuf_status;
static void
SSD1303_data_out(unsigned char cmd)
{
// SPI控制寄存器初始化:SPI允许,主模式0,二分频,SPImode2
SPCR = (0 << SPIE) | // 禁止SPI中断,采用死等方式
(1 << SPE) | // SPI使能
(0 << DORD) | // MSB在前
(1 << MSTR) | // SPI主模式
(1 << CPOL) | // SCLK启动沿为下降沿,结束沿上升沿
(1 << CPHA) | // 启动沿设置数据,结束沿采样数据
(0 << SPR1) | // SPI2X,SPR1,SPR0共同决定分频频率
(0 << SPR0); // SPI2X,SPR1,SPR0共同决定分频频率
// 当前SPI2X,SPR1,SPR0值为1,0,0,二分频
SPSR = (1 << SPI2X); // 二倍速,和SPR0,SPR1配合决定分频
// SPI控制寄存器初始化:SPI允许,主模式0,一百二十八分频
// SPCR = (1 << SPE) | (1 << MSTR) | ( 1 << SPR1) | (1 << SPR0);
// D/C#置高
SSD1303_DC_PORT |= (1 << SSD1303_DC_BIT);
// 片选选中
SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
SPDR = cmd;
while(!(SPSR & (1 << SPIF)))
{ // 如果SPIF为1,表示SPI传输(一个字节)操作完成
;
}
// 片选放开
SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
return;
}
static void
SSD1303_command_out(unsigned char cmd)
{
// SPI控制寄存器初始化:SPI允许,主模式0,二分频,SPImode2
SPCR = (0 << SPIE) | // 禁止SPI中断,采用死等方式
(1 << SPE) | // SPI使能
(0 << DORD) | // MSB在前
(1 << MSTR) | // SPI主模式
(1 << CPOL) | // SCLK启动沿为下降沿,结束沿上升沿
(1 << CPHA) | // 启动沿设置数据,结束沿采样数据
(0 << SPR1) | // SPI2X,SPR1,SPR0共同决定分频频率
(0 << SPR0); // SPI2X,SPR1,SPR0共同决定分频频率
// 当前SPI2X,SPR1,SPR0值为1,0,0,二分频
SPSR = (1 << SPI2X); // 二倍速,和SPR0,SPR1配合决定分频
// SPI控制寄存器初始化:SPI允许,主模式0,一百二十八分频
// SPCR = (1 << SPE) | (1 << MSTR) | ( 1 << SPR1) | (1 << SPR0);
// D/C#置低
SSD1303_DC_PORT &= ~(1 << SSD1303_DC_BIT);
// 片选选中
SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
SPDR = cmd;
while(!(SPSR & (1 << SPIF)))
{ // 如果SPIF为1,表示SPI传输(一个字节)操作完成
;
}
// 片选放开
SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
return;
}
void SSD1303_VCC(unsigned char vcc_onoff)
{
if(vcc_onoff)
{
SSD1303_VCC_PORT |= (1 << SSD1303_VCC_BIT);
}
else
{
SSD1303_VCC_PORT &= ~(1 << SSD1303_VCC_BIT);
}
return;
}
void SSD1303_poweron(void)
{
// 片选选中
// SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
// before the CS# pull high, additional NOP command should be inserted during SPI data writing.
SSD1303_command_out(0xae); // set display off
SSD1303_command_out(0xe2); // software reset
SSD1303_command_out(0xee); // read write -modify mode
SSD1303_command_out(0xa8); // set multiplex ratio
SSD1303_command_out(0x3f); // second byte of command set multiplex ratio, 64MUX
SSD1303_command_out(0xd0); // set display offset
SSD1303_command_out(0x7f); // second byte of command set display offset
SSD1303_command_out(0xa1); // set segment re-map
SSD1303_command_out(0xc8); // set COM output scan direction,行方向,黄色16像素在上
SSD1303_command_out(0xa6); // set normal/inverse display (normal)
SSD1303_command_out(0xa4); // set entire display (normal)
SSD1303_command_out(0x81); // set contrast control
SSD1303_command_out(0x28); // second byte
SSD1303_command_out(0xd5); // set display clock divide ratio/oscillator frequency.
SSD1303_command_out(0x10); // second byte
// 打开VCC
SSD1303_VCC_PORT |= (1 << SSD1303_VCC_BIT);
// 等待VCC稳定,100毫秒
delay(100);
SSD1303_command_out(0xaf); // set display on
// 片选放开
// SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
return;
}
void SSD1303_poweroff(void)
{
// 片选选中
// SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
// send display off command
SSD1303_command_out(0xae); // set display off
SSD1303_command_out(0xe3); // NOP
// 关闭VCC
SSD1303_VCC_PORT &= ~(1 << SSD1303_VCC_BIT);
// 等待100毫秒,等待VCC降到零
// 片选放开
// SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
return;
}
void SSD1303_clear_screen(unsigned char pattern)
{
unsigned char i;
unsigned int j;
// 片选选中
// SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
for(i = 0xB0; i< 0xB8; i++)
{
SSD1303_command_out(i); // set page address, 0xB0 -- 0xB8
SSD1303_command_out(0x00); // set the lower nibble of the column address register.
SSD1303_command_out(0x10); // set the higher nibble of the column address register.
for (j = 0; j < 128; j++)
{
SSD1303_data_out(pattern);
}
}
SSD1303_command_out(0xe3); // NOP
// 片选放开
// SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
return;
}
void
SSD1303_init(void)
{
SSD1303_CS_DDR |= (1 << SSD1303_CS_BIT);
SSD1303_DC_DDR |= (1 << SSD1303_DC_BIT);
SSD1303_SCK_DDR |= (1 << SSD1303_SCK_BIT);
SSD1303_VCC_DDR |= (1 << SSD1303_VCC_BIT);
SSD1303_MOSI_DDR |= (1 << SSD1303_MOSI_BIT);
SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT); // 片选关闭
SSD1303_VCC_PORT &= ~(1 << SSD1303_VCC_BIT); // VCC关闭
grambuf_status = 0;
return;
}
void SSD1303_fill_buffer(GRAMBUF* grbuf)
{
while(grambuf_status)
{ // grambuf_status不为零,代表上次的缓冲区还没有写完
;
}
memcpy(&grambuf, grbuf, sizeof(GRAMBUF));
grambuf_status = 1;
return;
}
void SSD1303_fill_screen(void)
{
unsigned char i;
unsigned char nibbleh;
unsigned char nibblel;
if(grambuf_status)
{
nibbleh = ((grambuf.column >> 4) | 0x10);
nibblel = ((grambuf.column & 0x0F) );
// 片选选中
// SSD1303_CS_PORT &= ~(1 << SSD1303_CS_BIT);
if(grambuf.pageh)
{
SSD1303_command_out(grambuf.pageh + 0xB0); // set page address, 0xB0 -- 0xB8
SSD1303_command_out(nibbleh); // set the lower nibble of the column address register.
SSD1303_command_out(nibblel); // set the higher nibble of the column address register.
for(i = 0; i < 8; i ++)
{
SSD1303_data_out(grambuf.hgram[i]);
}
SSD1303_command_out(0xe3); // NOP
}
/* if(grambuf.pagel)
{
SSD1303_command_out(grambuf.pagel + 0xB0); // set page address, 0xB0 -- 0xB8
SSD1303_command_out(nibbleh); // set the lower nibble of the column address register.
SSD1303_command_out(nibblel); // set the higher nibble of the column address register.
for(i = 0; i < 8; i ++)
{
SSD1303_data_out(grambuf.hgram[i]);
}
SSD1303_command_out(0xe3); // NOP
}
*/
// 片选放开
// SSD1303_CS_PORT |= (1 << SSD1303_CS_BIT);
grambuf_status = 0;
}
return;
}
#endif // #ifdef IC_SSD1303_ENABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -