外观
五、点亮数码管
1 电路分析
桌面温湿度仪中通过两个共阴极3位数码管来显示数据,考虑到引脚数量,这里加入3个移位寄存器来驱动共阴极数码管;
注
数码管内部其实就是多个LED灯组合在一起,共阴极的意思一位数码管中的LED灯阴极全部连接在一个引脚上,这里通过对LED灯两侧施加电压,从而达到控制数码管显示不同数据的效果;
这里使用的数码管内部LED灯阳极也是共用一组8个引脚的,所以没有办法单独控制每一位显示,驱动数码管同时显示数字,一般采用的是留影的效果,简单来说就是快速切换3位数据,使LED灯来不及熄灭就再次刷新,从而在视觉上感觉是3位数码管同时点亮显示数据。
2 代码编写
2.1 创建工程
2.2 设置参数
根据原理图,设置晶振引脚、下载引脚、移位寄存器控制引脚的参数;
将SN74HC595引脚设置为推挽输出、快速模式,同时依据原理图对其进行重命名,方便后续代码编写;
配置时钟树,这里主晶振没有使用外部而是内部晶振,外部低速晶振暂时没有使用,先不需要配置;
最后填写输出工程的名称,选择工程输出路径以及适配的IDE;
生成相关文件的.c与.h文件;
选择HAL库;
创建工程,随后打开,这个Cubemx软件就可以关闭了;
2.3 编译配置工程
正常应该是0错误0警告;
点击魔术棒,选择debug,选择合适的下载器,并配置下载器选项;
2.4编写测试代码
在gpio.c文件的用户区编写测试代码,SN74HC595的引脚初始化已经生成好了,现在要做的是编写相关的驱动函数与显示函数;
SN74HC595驱动时序相对简单,首先输入高电平或低电平到SER引脚中,随后产生一个SCLK的上升沿,将数据发送出去,这里是8位数据移位寄存器,所以循环8次,最后一个RCLK的上升沿将数据锁存住,保持不变,直到下一次发送;
这里模拟一下发送时序;首先待发送的数据是0xFE(1111 1110);
此时先发送最高位,也就是0xFE&0x80,判断高低电平;随后数据被送入QA;
然后继续,发送次高位,也就是(0xFE<<1)&0x80,判断高低电平,随后之前的数据被挤到QB,这个数据移位到QA。
依次类推...
SN74HC595数据手册
知道如何驱动数码管后就是想办法在指定位置显示数据了,根据前面的原理图可知,这两个数码管的阴极总共是6个阴极,全部连接在SN74HC595-U6上,通过这一个595芯片,可以指定某一个位导通,同时,两个数码管的阳极,又分别连接在另外两个595芯片上,通过这两个芯片配合,就可以实现单个位显示数据;并根据数码管中LED导通的顺序,从而使数码管显示不一样的值;这里将1到9对应的16进制数据放入数组中,通过数组下标进行调用。
在主函数中,对显示函数进行调用,注意不能加入延时,由于是留影效果,一旦有延时就会导致效果变差甚至闪烁。
核心代码
C
//0~9,外加一个小数点
uint16_t sgh_value[11]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80};
void SN74HC595_Send_Data(unsigned char sn_num,unsigned int sendValue)
{
uint8_t i = 0;
if(sn_num == SN_LED1) //第一个数码管
{
for(i = 0;i < 8;i++)
{
if(((sendValue << i)&0x80)!=0) //如果数据第一位是1
{
HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_SET); //高电平
}
else
{
HAL_GPIO_WritePin(LED1_SER_GPIO_Port,LED1_SER_Pin,GPIO_PIN_RESET); //低电平
}
HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_RESET); //产生一个SCLK上升沿
HAL_GPIO_WritePin(LED1_SCLK_GPIO_Port,LED1_SCLK_Pin,GPIO_PIN_SET);
}
HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_RESET); //产生一个RCLK上升沿
HAL_GPIO_WritePin(LED1_RCLK_GPIO_Port,LED1_RCLK_Pin,GPIO_PIN_SET);
}
else if(sn_num == SN_LED2)
{
for(i = 0;i < 8;i++)
{
if(((sendValue << i)&0x80)!=0)
{
HAL_GPIO_WritePin(LED2_SER_GPIO_Port,LED2_SER_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(LED2_SER_GPIO_Port,LED2_SER_Pin,GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(LED2_SCLK_GPIO_Port,LED2_SCLK_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_SCLK_GPIO_Port,LED2_SCLK_Pin,GPIO_PIN_SET);
}
HAL_GPIO_WritePin(LED2_RCLK_GPIO_Port,LED2_RCLK_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_RCLK_GPIO_Port,LED2_RCLK_Pin,GPIO_PIN_SET);
}
else if(sn_num == SN_DIG)
{
for(i = 0;i < 8;i++)
{
if(((sendValue << i)&0x80)!=0)
{
HAL_GPIO_WritePin(DIG_SER_GPIO_Port,DIG_SER_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(DIG_SER_GPIO_Port,DIG_SER_Pin,GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(DIG_SCLK_GPIO_Port,DIG_SCLK_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(DIG_SCLK_GPIO_Port,DIG_SCLK_Pin,GPIO_PIN_SET);
}
HAL_GPIO_WritePin(DIG_RCLK_GPIO_Port,DIG_RCLK_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(DIG_RCLK_GPIO_Port,DIG_RCLK_Pin,GPIO_PIN_SET);
}
}
void ShowNum(uint8_t row, uint8_t column, uint8_t value)
{
if(row == 1)
{
switch(column)
{
case 1: //如果是第一排第一个
SN74HC595_Send_Data(SN_DIG,0xFE);
SN74HC595_Send_Data(SN_LED1,sgh_value[value]);//显示值对应16进制数
break;
case 2:
SN74HC595_Send_Data(SN_DIG,0xFD);
SN74HC595_Send_Data(SN_LED1,(sgh_value[value]|0x80));
break;
case 3:
SN74HC595_Send_Data(SN_DIG,0xFB);
SN74HC595_Send_Data(SN_LED1,sgh_value[value]);
break;
default:
break;
}
SN74HC595_Send_Data(SN_LED1,0x00); //消影,防止错位
}
else
{
switch(column)
{
case 1:
SN74HC595_Send_Data(SN_DIG,0xF7);
SN74HC595_Send_Data(SN_LED2,sgh_value[value]);
break;
case 2:
SN74HC595_Send_Data(SN_DIG,0xEF);
SN74HC595_Send_Data(SN_LED2,(sgh_value[value]|0x80));
break;
case 3:
SN74HC595_Send_Data(SN_DIG,0xDF);
SN74HC595_Send_Data(SN_LED2,sgh_value[value]);
break;
default:
break;
}
SN74HC595_Send_Data(SN_LED2,0x00);
}
}
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
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
C
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
HAL_DeInit();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
//使数码管全部熄灭
HAL_Delay(100);
SN74HC595_Send_Data(SN_DIG,0x00);
SN74HC595_Send_Data(SN_LED1,0x00);
SN74HC595_Send_Data(SN_LED2,0x00);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
ShowNum(2,1,6);
ShowNum(2,2,6);
ShowNum(2,3,6);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
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
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