-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTM1637DisplayTest.c
More file actions
278 lines (244 loc) · 11.4 KB
/
TM1637DisplayTest.c
File metadata and controls
278 lines (244 loc) · 11.4 KB
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
// ---------------------------------------------------------------------
// Microchip 12F675/TM1637 display code adapted by Steve Williams
// for Microchip's MPLAB XC8 compiler. The TM1637 routines were originally
// written by electro-dan for the BoostC compiler as part of project:
// https://github.com/electro-dan/PIC12F_TM1637_Thermometer.
// The code produces an incrementing count on a 4 digit TM1637 display module.
// No warranty is implied and the code is for test use at users own risk.
//
// Hardware configuration for the PIC 12F675:
// GP0 = OUT: N/C
// GP1 = OUT: N/C
// GP2 = in original code IN/OUT for DS18B20 (not used by this demo)
// GP3 = OUT: N/C
// GP4 = IN/OUT: TM1637 DIO
// GP5 = IN/OUT: TM1637 CLK
// -----------------------------------------------------------------------
#include <xc.h>
// CONFIG as generated by Microchip IDE:
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-Up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#define _XTAL_FREQ 4000000 // Define clock frequency used by xc8 __delay(time) functions
// Set the TM1637 module data and clock pins:
#define trisConfiguration 0b00110000; // This config ONLY TM1637 GP4/5 pins are inputs, TM1637 module pullups will take high
#define tm1637dio GP4 // Set the i/o ports names for TM1637 data and clock here
#define tm1637dioTrisBit 4 // This is the bit shift to set TRIS for GP4
#define tm1637clk GP5
#define tm1637clkTrisBit 5
//Variables:
const uint8_t tm1637ByteSetData = 0x40; // 0x40 [01000000] = Indicate command to display data
const uint8_t tm1637ByteSetAddr = 0xC0; // 0xC0 [11000000] = Start address write out all display bytes
const uint8_t tm1637ByteSetOn = 0x88; // 0x88 [10001000] = Display ON, plus brightness
const uint8_t tm1637ByteSetOff = 0x80; // 0x80 [10000000] = Display OFF
const uint8_t tm1637MaxDigits = 4;
const uint8_t tm1637RightDigit = tm1637MaxDigits - 1;
// Used to output the segment data for numbers 0..9 :
const uint8_t tm1637DisplayNumtoSeg[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
uint8_t tm1637Brightness = 5; // Range 0 to 7
uint8_t tm1637Data[] = {0, 0, 0, 0}; //Digit numeric data to display,array elements are for digits 0..3
uint8_t decimalPointPos = 99; //Flag for decimal point (digits counted from left),if > MaxDigits dp off
uint8_t zeroBlanking = 1; //If set true blanks leading zeros
//Function prototypes:
void initialise(void);
void tm1637StartCondition(void);
void tm1637StopCondition(void);
uint8_t tm1637ByteWrite(uint8_t bWrite);
void tm1637UpdateDisplay(void);
void tm1637DisplayOn(void);
void tm1637DisplayOff(void);
uint8_t getDigits(unsigned int number); //Extracts decimal digits from integer, populates tm1637Data array
void main(void)
{
uint16_t displayedInt=0; //Beware 65K limit if larger than 4 digit display,consider using uint32_t
uint16_t ctr = 0;
initialise();
_delay(100);
getDigits(displayedInt);
tm1637UpdateDisplay();
while(1)
{
displayedInt ++;
if (displayedInt>9999)
displayedInt = 0;
if (getDigits(displayedInt))
{
__delay_ms(1000);
tm1637UpdateDisplay();
}
}
}
/*********************************************************************************************
tm1637UpdateDisplay()
Publish the tm1637Data array to the display
*********************************************************************************************/
void tm1637UpdateDisplay()
{
uint8_t tm1637DigitSegs = 0;
uint8_t ctr;
uint8_t stopBlanking = !zeroBlanking; // Allow blanking of leading zeros if flag set
// Write 0x40 [01000000] to indicate command to display data - [Write data to display register]:
tm1637StartCondition();
tm1637ByteWrite(tm1637ByteSetData);
tm1637StopCondition();
// Specify the display address 0xC0 [11000000] then write out all 4 bytes:
tm1637StartCondition();
tm1637ByteWrite(tm1637ByteSetAddr);
for (ctr = 0; ctr < tm1637MaxDigits; ctr ++)
{
tm1637DigitSegs = tm1637DisplayNumtoSeg[tm1637Data[ctr]];
if (!stopBlanking && (tm1637Data[ctr]==0)) // Blank leading zeros if stop blanking flag not set
{
if (ctr < tm1637RightDigit) // Never blank the rightmost digit
tm1637DigitSegs = 0; // Segments set 0x00 gives blanked display numeral
}
else
{
stopBlanking = 1; // Stop blanking if have reached a non-zero digit
if (ctr==decimalPointPos) // Flag for presence of decimal point, digits 0..3
{ // No dp display if decimalPointPos is set > Maxdigits
tm1637DigitSegs |= 0b10000000; // High bit of segment data is decimal point, set to display
}
}
tm1637ByteWrite(tm1637DigitSegs); // Finally write out the segment data for each digit
}
tm1637StopCondition();
// Write 0x80 [10001000] - Display ON, plus brightness
tm1637StartCondition();
tm1637ByteWrite((tm1637ByteSetOn + tm1637Brightness));
tm1637StopCondition();
}
/*********************************************************************************************
tm1637DisplayOn()
Send display on command
*********************************************************************************************/
void tm1637DisplayOn(void)
{
tm1637StartCondition();
tm1637ByteWrite((tm1637ByteSetOn + tm1637Brightness));
tm1637StopCondition();
}
/*********************************************************************************************
tm1637DisplayOff()
Send display off command
*********************************************************************************************/
void tm1637DisplayOff(void)
{
tm1637StartCondition();
tm1637ByteWrite(tm1637ByteSetOff);
tm1637StopCondition();
}
/*********************************************************************************************
tm1637StartCondition()
Send the start condition
*********************************************************************************************/
void tm1637StartCondition(void)
{
TRISIO &= ~(1<<tm1637dioTrisBit); //Clear data tris bit
tm1637dio = 0; //Data output set low
__delay_us(100);
}
/*********************************************************************************************
tm1637StopCondition()
Send the stop condition
*********************************************************************************************/
void tm1637StopCondition()
{
TRISIO &= ~(1<<tm1637dioTrisBit); // Clear data tris bit
tm1637dio = 0; // Data low
__delay_us(100);
TRISIO |= 1<<tm1637clkTrisBit; // Set tris to release clk
//tm1637clk = 1;
__delay_us(100);
// Release data
TRISIO |= 1<<tm1637dioTrisBit; // Set tris to release data
__delay_us(100);
}
/*********************************************************************************************
tm1637ByteWrite(char bWrite)
Write one byte
*********************************************************************************************/
uint8_t tm1637ByteWrite(uint8_t bWrite) {
for (uint8_t i = 0; i < 8; i++) {
// Clock low
TRISIO &= ~(1<<tm1637clkTrisBit); // Clear clk tris bit
tm1637clk = 0;
__delay_us(100);
// Test bit of byte, data high or low:
if ((bWrite & 0x01) > 0) {
TRISIO |= 1<<tm1637dioTrisBit; // Set data tris
} else {
TRISIO &= ~(1<<tm1637dioTrisBit); // Clear data tris bit
tm1637dio = 0;
}
__delay_us(100);
// Shift bits to the left:
bWrite = (bWrite >> 1);
TRISIO |= 1<<tm1637clkTrisBit; // Set tris so clk goes high
__delay_us(100);
}
// Wait for ack, send clock low:
TRISIO &= ~(1<<tm1637clkTrisBit); // Clear clk tris bit
tm1637clk = 0;
TRISIO |= 1<<tm1637dioTrisBit; // Set data tris, makes input
tm1637dio = 0;
__delay_us(100);
TRISIO |= 1<<tm1637clkTrisBit; // Set tris so clk goes high
__delay_us(100);
uint8_t tm1637ack = tm1637dio;
if (!tm1637ack)
{
TRISIO &= ~(1<<tm1637dioTrisBit); // Clear data tris bit
tm1637dio = 0;
}
__delay_us(100);
TRISIO &= ~(1<<tm1637clkTrisBit); // Clear clk tris bit, set clock low
tm1637clk = 0;
__delay_us(100);
return 1;
}
/*********************************************************************************************
Function called once only to initialise variables and
setup the PIC registers
*********************************************************************************************/
void initialise()
{
GPIO = 0b00000000; // all pins low by default
TRISIO = trisConfiguration;
ANSEL = 0; // configure A/D inputs as digital I/O
CMCON = 7; // comparator off
OPTION_REG = 0b10000000; // Set bit 7, disable pullups, otherwise clear OPTION_REG bits
// old timer/interrupt/pullup setup was here
}
/*************************************************************************************************
getDigits extracts decimal digit numbers from an integer for the display, note max displayed value is
9999 for 4 digit display, truncation of larger numbers. Larger displays: note maximum 65K as coded with
16 bit parameter - probable need to declare number as uint32_t if coding for a 6 digit display
************************************************************************************************/
uint8_t getDigits(uint16_t number)
{
int8_t ctr = (tm1637RightDigit); // Start processing for the rightmost displayed digit
for (uint8_t ctr2 = 0; ctr2 < tm1637MaxDigits; ctr2++)
{
tm1637Data[ctr2]=0; //Initialise the display data array with 0s
}
while(number > 0) //Do if number greater than 0, ie. until all number's digits processed
{
if (ctr >= 0)
{
uint16_t modulus = number % 10; // Split last digit from number
tm1637Data[ctr] = (uint8_t)modulus; // Update display character array
number = number / 10; // Divide number by 10
ctr --; // Decrement digit counter to process number from right to left
}
else
{
number = 0; // Stop processing if have exceeded display's no of digits
}
}
return 1;
}