STM32-HAL库05-GPIO直接4位驱动数码管
一、数码管的引脚确定
之前购买了一个TM1638驱动的数码管,但是驱动时间上达不到我的预期目标,所以就想着自己直接用GPIO引脚进行驱动,然后就单独从板子上拆下来了数码管,这就带来了一个问题,不知道数码管的引脚分布,因此就只能一个一个去试了。
首先选择数码管带有标志性的一个面作为基准面:
然后利用万用表的蜂鸣档选择两个临近的引脚,如果没有任何反应,则说明这两个引脚为共阴端(或者共阳)或者都为触发端。
这时就一个引脚,移动另外一个,直到有亮光出现,此时万用表一定是一段接着共性端,一段接着触发端,但是还不能确定方向,此时固定住万用表的红色线,移动黑色线,当再次发生亮光时:
(1)与第一次发生亮光比,亮光位置处于同一位中的不同位置,则说明该数码管为共阳极,万用表红色线此时为某一共性端。
(2)与第一次发生亮光比,亮光位置处于不同位的相同位置,则说明该数码管为共阴极,万用表红色线此时为某一触发端。
再选定某个共性端,挨个测出触发端的具体标号(ABCDEFG)。
最后选定某一触发端,挨个测出四个共性端标号(G1G2G3G4)
二、数码管驱动
由于本文中只用到了数字码,因此只设定0-9数字的GPIO控制函数。
配置头文件
#ifndef __TM1638_H
#define __TM1638_H
//========移植的时候,根据所选芯片引入相应的头文件==========在main.h里面查看
#include "stm32f1xx_hal.h"
#include "gpio.h"
#define A1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
#define A0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
#define B1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
#define B0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
#define C1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
#define C0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
#define D1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
#define D0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
#define E1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
#define E0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
#define F1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
#define F0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
#define G1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
#define G0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
#define GP1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
#define GP0 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
#define G1_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);
#define G1_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
#define G2_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
#define G2_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
#define G3_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
#define G3_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
#define G4_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
#define G4_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
void Showone_inadd(uint8_t add,uint8_t data);
void Off_all(void);
void Show_current(float current);
void Show_int(uint16_t a);
#endif
配置源文件
#include "gpio.h"
#include "TM1638.h"
void Showone_inadd(uint8_t add,uint8_t data)
{
switch (add)
{
case 1:
G1_1;G2_0;G3_0;G4_0;break;
case 2:
G1_0;G2_1;G3_0;G4_0;break;
case 3:
G1_0;G2_0;G3_1;G4_0;break;
case 4:
G1_0;G2_0;G3_0;G4_1;break;
default:
break;
}
switch (data)
{
case 1:
A1;B0;C0;D1;E1;F1;G1;GP1;break;
case 2:
A0;B0;C1;D0;E0;F1;G0;GP1;break;
case 3:
A0;B0;C0;D0;E1;F1;G0;GP1;break;
case 4:
A1;B0;C0;D1;E1;F0;G0;GP1;break;
case 5:
A0;B1;C0;D0;E1;F0;G0;GP1;break;
case 6:
A0;B1;C0;D0;E0;F0;G0;GP1;break;
case 7:
A0;B0;C0;D1;E1;F1;G1;GP1;break;
case 8:
A0;B0;C0;D0;E0;F0;G0;GP1;break;
case 9:
A0;B0;C0;D1;E1;F0;G0;GP1;break;
case 0:
A0;B0;C0;D0;E0;F0;G1;GP1;break;
}
if (add == 3)
{
GP0;
}
}
void Show_current(float current)
{
float incurrent;
uint16_t intcurrent;
uint8_t data1;
uint8_t data2;
uint8_t data3;
uint8_t data4;
incurrent = current;
if (incurrent < 0)
{
incurrent = -incurrent;
}
if (incurrent >99.99)
{
incurrent =99.99;
}
intcurrent = incurrent *100.0;
data1 = intcurrent/1000;
intcurrent = intcurrent - data1*1000;
data2 = intcurrent/100;
intcurrent = intcurrent - data2*100;
data3 = intcurrent/10;
intcurrent = intcurrent - data3*10;
data4 = intcurrent;
Showone_inadd(1,data1);
Off_all();
Showone_inadd(2,data2);
Off_all();
Showone_inadd(3,data3);
Off_all();
Showone_inadd(4,data4);
Off_all();
}
void Show_int(uint16_t a)
{
uint16_t intcurrent;
uint8_t data1;
uint8_t data2;
uint8_t data3;
uint8_t data4;
intcurrent = a;
data1 = intcurrent/1000;
intcurrent = intcurrent - data1*1000;
data2 = intcurrent/100;
intcurrent = intcurrent - data2*100;
data3 = intcurrent/10;
intcurrent = intcurrent - data3*10;
data4 = intcurrent/1;
Off_all();
Showone_inadd(1,data1);
Off_all();
Showone_inadd(2,data2);
Off_all();
Showone_inadd(3,data3);
Off_all();
Showone_inadd(4,data4);
Off_all();
}
void Off_all(void)
{
G1_0;G2_0;G3_0;G4_0;
A1;B1;C1;D1;E1;F1;G1;GP1;
}
main函数中进行调用
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 */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc1); //AD校准
//OLED_Init();
//OLED_ShowString(0,0,(unsigned char *)"Current:");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
switch(station)
{
case 0://开机初始化过程
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);//打开LED,绿灯常亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);//打开EN
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);//打开继电器
station = 1;//进入下一个状态:电流检测监控
break;
case 1://电流检测状态
HAL_ADC_Start(&hadc1); //启动ADC转换
HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
ADC_Value = HAL_ADC_GetValue(&hadc1); //获取AD值
i = ((ADC_Value*0.00081)-1.65)*7.57576;
}
if (i <-4 || i >=4)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);//打开LED,绿灯熄灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);//关闭EN
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);//断开继电器
station =2;//进入过流报警状态
}
Show_current(i);
break;
case 2://过流报警状态
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);//关闭EN
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);//断开继电器
HAL_Delay(200);
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) ==0)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}
break;
default :
break;
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
三、结果说明
数码管驱动用时40us,电流检测部分用时20us,总用时符合预期需求。