-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathssd1306.c
215 lines (184 loc) · 5.29 KB
/
ssd1306.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include"ssd1306.h"
// Databuffer voor het scherm
static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8];
// Een scherm-object om lokaal in te werken
static SSD1306_t SSD1306;
//
// Een byte sturen naar het commando register
// Kan niet gebruikt worden buiten deze file
//
static void ssd1306_WriteCommand(uint8_t command)
{
HAL_I2C_Mem_Write(&hi2c1,SSD1306_I2C_ADDR,0x00,1,&command,1,10);
}
//
// Het scherm initialiseren voor gebruik
//
uint8_t ssd1306_Init(void)
{
// Even wachten zodat het scherm zeker opgestart is
HAL_Delay(100);
/* Init LCD */
ssd1306_WriteCommand(0xAE); //display off
ssd1306_WriteCommand(0x20); //Set Memory Addressing Mode
ssd1306_WriteCommand(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
ssd1306_WriteCommand(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
ssd1306_WriteCommand(0xC8); //Set COM Output Scan Direction
ssd1306_WriteCommand(0x00); //---set low column address
ssd1306_WriteCommand(0x10); //---set high column address
ssd1306_WriteCommand(0x40); //--set start line address
ssd1306_WriteCommand(0x81); //--set contrast control register
ssd1306_WriteCommand(0xFF);
ssd1306_WriteCommand(0xA1); //--set segment re-map 0 to 127
ssd1306_WriteCommand(0xA6); //--set normal display
ssd1306_WriteCommand(0xA8); //--set multiplex ratio(1 to 64)
ssd1306_WriteCommand(0x3F); //
ssd1306_WriteCommand(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
ssd1306_WriteCommand(0xD3); //-set display offset
ssd1306_WriteCommand(0x00); //-not offset
ssd1306_WriteCommand(0xD5); //--set display clock divide ratio/oscillator frequency
ssd1306_WriteCommand(0xF0); //--set divide ratio
ssd1306_WriteCommand(0xD9); //--set pre-charge period
ssd1306_WriteCommand(0x22); //
ssd1306_WriteCommand(0xDA); //--set com pins hardware configuration
ssd1306_WriteCommand(0x12);
ssd1306_WriteCommand(0xDB); //--set vcomh
ssd1306_WriteCommand(0x20); //0x20,0.77xVcc
ssd1306_WriteCommand(0x8D); //--set DC-DC enable
ssd1306_WriteCommand(0x14); //
ssd1306_WriteCommand(0xAF); //--turn on SSD1306 panel
/* Clearen scherm */
ssd1306_Fill(Black);
/* Update screen */
ssd1306_UpdateScreen();
/* Set default values */
SSD1306.CurrentX = 0;
SSD1306.CurrentY = 0;
/* Initialized OK */
SSD1306.Initialized = 1;
/* Return OK */
return 1;
}
//
// We zetten de hele buffer op een bepaalde kleur
// color => de kleur waarin alles moet
//
void ssd1306_Fill(SSD1306_COLOR color)
{
/* Set memory */
uint32_t i;
for(i = 0; i < sizeof(SSD1306_Buffer); i++)
{
SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF;
}
}
//
// Alle weizigingen in de buffer naar het scherm sturen
//
void ssd1306_UpdateScreen(void)
{
uint8_t i;
for (i = 0; i < 8; i++) {
ssd1306_WriteCommand(0xB0 + i);
ssd1306_WriteCommand(0x00);
ssd1306_WriteCommand(0x10);
// We schrijven alles map per map weg
HAL_I2C_Mem_Write(&hi2c1,SSD1306_I2C_ADDR,0x40,1,&SSD1306_Buffer[SSD1306_WIDTH * i],SSD1306_WIDTH,100);
}
}
//
// 1 pixel op het scherm tekenen
// X => X coordinaat
// Y => Y coordinaat
// color => kleur die pixel moet krijgen
//
void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color)
{
if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT)
{
// We gaan niet buiten het scherm schrijven
return;
}
// Kijken of de pixel geinverteerd moet worden
if (SSD1306.Inverted)
{
color = (SSD1306_COLOR)!color;
}
// We zetten de juiste kleur voor de pixel
if (color == White)
{
SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);
}
else
{
SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));
}
}
//
// We willen 1 char naar het scherm sturen
// ch => char om weg te schrijven
// Font => Font waarmee we gaan schrijven
// color => Black or White
//
char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color)
{
uint32_t i, b, j;
// Kijken of er nog plaats is op deze lijn
if (SSD1306_WIDTH <= (SSD1306.CurrentX + Font.FontWidth) ||
SSD1306_HEIGHT <= (SSD1306.CurrentY + Font.FontHeight))
{
// Er is geen plaats meer
return 0;
}
// We gaan door het font
for (i = 0; i < Font.FontHeight; i++)
{
b = Font.data[(ch - 32) * Font.FontHeight + i];
for (j = 0; j < Font.FontWidth; j++)
{
if ((b << j) & 0x8000)
{
ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color);
}
else
{
ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color);
}
}
}
// De huidige positie is nu verplaatst
SSD1306.CurrentX += Font.FontWidth;
// We geven het geschreven char terug voor validatie
return ch;
}
//
// Functie voor het wegschrijven van een hele string
// str => string om op het scherm te schrijven
// Font => Het font dat gebruikt moet worden
// color => Black or White
//
char ssd1306_WriteString(char* str, FontDef Font, SSD1306_COLOR color)
{
// We schrijven alle char tot een nulbyte
while (*str)
{
if (ssd1306_WriteChar(*str, Font, color) != *str)
{
// Het karakter is niet juist weggeschreven
return *str;
}
// Volgende char
str++;
}
// Alles gelukt, we sturen dus 0 terug
return *str;
}
//
// Zet de cursor op een coordinaat
//
void ssd1306_SetCursor(uint8_t x, uint8_t y)
{
/* Set write pointers */
SSD1306.CurrentX = x;
SSD1306.CurrentY = y;
}