-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsegment_display.c
More file actions
135 lines (116 loc) · 4.51 KB
/
segment_display.c
File metadata and controls
135 lines (116 loc) · 4.51 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
/*
@Copyright Han ZHANG (DoubleHan) | All rights reserved.
@Last Modified Time May.24, 2024
*/
/* Includes ------------------------------------------------------------------*/
#include "segment_display.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define DIO1_HIGH HAL_GPIO_WritePin(DIO1_GPIO_Port, DIO1_Pin, GPIO_PIN_SET)
#define DIO1_LOW HAL_GPIO_WritePin(DIO1_GPIO_Port, DIO1_Pin, GPIO_PIN_RESET)
#define SCLK1_HIGH HAL_GPIO_WritePin(SCLK1_GPIO_Port, SCLK1_Pin, GPIO_PIN_SET)
#define SCLK1_LOW HAL_GPIO_WritePin(SCLK1_GPIO_Port, SCLK1_Pin, GPIO_PIN_RESET)
#define RCLK1_HIGH HAL_GPIO_WritePin(RCLK1_GPIO_Port, RCLK1_Pin, GPIO_PIN_SET)
#define RCLK1_LOW HAL_GPIO_WritePin(RCLK1_GPIO_Port, RCLK1_Pin, GPIO_PIN_RESET)
#define DIO2_HIGH HAL_GPIO_WritePin(DIO2_GPIO_Port, DIO2_Pin, GPIO_PIN_SET)
#define DIO2_LOW HAL_GPIO_WritePin(DIO2_GPIO_Port, DIO2_Pin, GPIO_PIN_RESET)
#define SCLK2_HIGH HAL_GPIO_WritePin(SCLK2_GPIO_Port, SCLK2_Pin, GPIO_PIN_SET)
#define SCLK2_LOW HAL_GPIO_WritePin(SCLK2_GPIO_Port, SCLK2_Pin, GPIO_PIN_RESET)
#define RCLK2_HIGH HAL_GPIO_WritePin(RCLK2_GPIO_Port, RCLK2_Pin, GPIO_PIN_SET)
#define RCLK2_LOW HAL_GPIO_WritePin(RCLK2_GPIO_Port, RCLK2_Pin, GPIO_PIN_RESET)
/* Private variables ---------------------------------------------------------*/
static __IO uint16_t display_num_H = 0; //Extracts and displays the first 4 digits, e.g. 439.250 => 439.
static __IO uint16_t display_num_L = 0; //Extracts and displays the last 4 digits, e.g. 439.250 => 250.
uint8_t code[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E}; //Code for displaying 0-F on a single LED segment display.
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//Control logic fot the 74HC595 chip to display the value 'num'.
//seg = {0x08, 0x04, 0x02, 0x01}
//e.g. to display '2345'
//Use writeByteH(2, 0x08) to display 2xxx.
//Use writeByteH(3, 0x04) to display x3xx.
//Use writeByteH(4, 0x02) to display xx4x.
//Use writeByteH(5, 0x01) to display xxx5.
//The 74HC595 chip can handle only one digit at a time, so '2345' cannot be displayed simultaneously.
//To display '2345', call the upper 4 functions every 1 millisecond.
//In other words, scan each digit sequentially to create the illusion of a simultaneous display.
void WriteByteH(uint8_t num, uint8_t seg)
{
for(uint8_t i=0; i<8; i++)
{
((num<<i)&0x80) ? DIO1_HIGH : DIO1_LOW;
SCLK1_HIGH;
SCLK1_LOW;
}
for(uint8_t i=0; i<8; i++)
{
((seg<<i)&0x80) ? DIO1_HIGH : DIO1_LOW;
SCLK1_HIGH;
SCLK1_LOW;
}
RCLK1_HIGH;
RCLK1_LOW;
}
void WriteByteL(uint8_t num, uint8_t seg)
{
for(uint8_t i=0; i<8; i++)
{
((num<<i)&0x80) ? DIO2_HIGH : DIO2_LOW;
SCLK2_HIGH;
SCLK2_LOW;
}
for(uint8_t i=0; i<8; i++)
{
((seg<<i)&0x80) ? DIO2_HIGH : DIO2_LOW;
SCLK2_HIGH;
SCLK2_LOW;
}
RCLK2_HIGH;
RCLK2_LOW;
}
void SetNumH(uint16_t num)
{
display_num_H = num;
}
void SetNumL(uint16_t num)
{
display_num_L = num;
}
//Usage: Call DBH_SetNum(439, 250) to display 439 on segment display H and 250 on segment display L.
void DBH_SetNum(uint16_t num_H, uint16_t num_L)
{
SetNumH(num_H);
SetNumL(num_L);
}
//The 'state' will alternate between 0 and 3 every 1 millisecond, as scheduled in the SysTick Handler.
void DBH_DisplayNumH(uint8_t state)
{
switch (state)
{
case 0:
if (display_num_H/1000 != 0) //If the first digit of display_num_H is 0, skip it (e.g. display '439' instead of '0439').
WriteByteH(code[display_num_H/1000],0x08);
break;
case 1: WriteByteH(code[display_num_H%1000/100],0x04); break;
case 2: WriteByteH(code[display_num_H%100/10],0x02); break;
case 3: WriteByteH(code[display_num_H%100%10],0x01); break;
default: break;
}
}
//The 'state' will alternate between 0 and 3 every 1 millisecond, as scheduled in the SysTick Handler.
void DBH_DisplayNumL(uint8_t state)
{
switch (state)
{
case 0:
if (display_num_L/1000 != 0) //If the first digit of display_num_L is 0, skip it (e.g. display '250' instead of '0250').
WriteByteL(code[display_num_L/1000],0x08);
break;
case 1: WriteByteL(code[display_num_L%1000/100],0x04); break;
case 2: WriteByteL(code[display_num_L%100/10],0x02); break;
case 3: WriteByteL(code[display_num_L%100%10],0x01); break;
default: break;
}
}