Files
new_f_3/User/bsp/src/bsp_digital_tube.c
刘正航 609eb878d1 New
2026-04-16 16:55:01 +08:00

455 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//------------------------------------------------------------------------------
// 模块名称:数码管驱动模块
// 文件名称bsp_digital_tube
// 版本名称V1.0
// 文件说明8个0.2寸共阴数码管轮流刷新控制点亮。
// 日期时间2018年8月15日16点42分
// 文件作者Jackie Chan
// 修改记录:
// 版本号 日期 作者 说明
// V1.0 2018.08.15 J.C 正式发布
//
// 公司名称:多场低温科技有限公司
//
//------------------------------------------------------------------------------
#include "bsp.h"
#include <string.h>
#include <ctype.h>
#include <math.h>
// 数码管控制引脚对应的RCC时钟
#define RCC_ALL_TUBE (RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD)
// 数码管的位选,高电平有效
#define GPIO_PORT_A GPIOD
#define GPIO_PIN_A GPIO_Pin_0
#define GPIO_PORT_B GPIOD
#define GPIO_PIN_B GPIO_Pin_1
#define GPIO_PORT_C GPIOD
#define GPIO_PIN_C GPIO_Pin_2
#define GPIO_PORT_D GPIOD
#define GPIO_PIN_D GPIO_Pin_3
#define GPIO_PORT_E GPIOD
#define GPIO_PIN_E GPIO_Pin_4
#define GPIO_PORT_F GPIOD
#define GPIO_PIN_F GPIO_Pin_5
#define GPIO_PORT_G GPIOD
#define GPIO_PIN_G GPIO_Pin_6
#define GPIO_PORT_H GPIOD
#define GPIO_PIN_H GPIO_Pin_7
// 数码管的段选,高电平有效
#define GPIO_PORT_DS1 GPIOC
#define GPIO_PIN_DS1 GPIO_Pin_9
#define GPIO_PORT_DS2 GPIOC
#define GPIO_PIN_DS2 GPIO_Pin_8
#define GPIO_PORT_DS3 GPIOC
#define GPIO_PIN_DS3 GPIO_Pin_10
#define GPIO_PORT_DS4 GPIOC
#define GPIO_PIN_DS4 GPIO_Pin_6
#define GPIO_PORT_DS5 GPIOD
#define GPIO_PIN_DS5 GPIO_Pin_11
#define GPIO_PORT_DS6 GPIOD
#define GPIO_PIN_DS6 GPIO_Pin_10
#define GPIO_PORT_DS7 GPIOD
#define GPIO_PIN_DS7 GPIO_Pin_9
#define GPIO_PORT_DS8 GPIOD
#define GPIO_PIN_DS8 GPIO_Pin_8
// 关闭所有段选
#define CLOSE_ALL_TUBE_COM \
do \
{ \
GPIO_PORT_DS1->BRR = GPIO_PIN_DS1; \
GPIO_PORT_DS2->BRR = GPIO_PIN_DS2; \
GPIO_PORT_DS3->BRR = GPIO_PIN_DS3; \
GPIO_PORT_DS4->BRR = GPIO_PIN_DS4; \
GPIO_PORT_DS5->BRR = GPIO_PIN_DS5; \
GPIO_PORT_DS6->BRR = GPIO_PIN_DS6; \
GPIO_PORT_DS7->BRR = GPIO_PIN_DS7; \
GPIO_PORT_DS8->BRR = GPIO_PIN_DS8; \
} while (0)
// 关闭所有位选
#define CLOSE_ALL_TUBE_SEG \
do \
{ \
GPIO_PORT_A->BRR = GPIO_PIN_A; \
GPIO_PORT_B->BRR = GPIO_PIN_B; \
GPIO_PORT_C->BRR = GPIO_PIN_C; \
GPIO_PORT_D->BRR = GPIO_PIN_D; \
GPIO_PORT_E->BRR = GPIO_PIN_E; \
GPIO_PORT_F->BRR = GPIO_PIN_F; \
GPIO_PORT_G->BRR = GPIO_PIN_G; \
GPIO_PORT_H->BRR = GPIO_PIN_H; \
} while (0)
// 数码管共阴或者共阳选择,用于正确输出位选电平
#define SEG_A 0X01
#define SEG_B 0X01
#define SEG_C 0X01
#define SEG_D 0X01
#define SEG_E 0X01
#define SEG_F 0X01
#define SEG_G 0X01
#define SEG_H 0X01
#define SEG_0 0X00 // 数码管的该段<不点亮>
const uint8_t g_tube_table[12][7] = {
{SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_0}, // NO_0
{SEG_0, SEG_B, SEG_C, SEG_0, SEG_0, SEG_0, SEG_0}, // NO_1
{SEG_A, SEG_B, SEG_0, SEG_D, SEG_E, SEG_0, SEG_G}, // NO_2
{SEG_A, SEG_B, SEG_C, SEG_D, SEG_0, SEG_0, SEG_G}, // NO_3
{SEG_0, SEG_B, SEG_C, SEG_0, SEG_0, SEG_F, SEG_G}, // NO_4
{SEG_A, SEG_0, SEG_C, SEG_D, SEG_0, SEG_F, SEG_G}, // NO_5
{SEG_A, SEG_0, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G}, // NO_6
{SEG_A, SEG_B, SEG_C, SEG_0, SEG_0, SEG_0, SEG_0}, // NO_7
{SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G}, // NO_8
{SEG_A, SEG_B, SEG_C, SEG_D, SEG_0, SEG_F, SEG_G}, // NO_9
{SEG_0, SEG_0, SEG_0, SEG_0, SEG_0, SEG_0, SEG_G}, // NO__
{SEG_0, SEG_0, SEG_0, SEG_0, SEG_0, SEG_0, SEG_0}, // NO_NULL
};
// 全局变量声明
DIGITIAL_TUBE_T g_tTube;
extern MOTO_T g_tMoto;
// 该文件中的所有函数声明
void bsp_InitDigitalTube(void);
void bsp_DigitalTubeMainLoop(void);
void bsp_TubeTest(uint8_t _com, uint8_t _seg);
void bsp_InitTubeVar(void);
void bsp_UpdateDisplayBuf(void);
void bsp_ToogleWorkMode(void);
void bsp_ToogleStateMode(void);
void bsp_Pulse2Buf(void);
void bsp_Angle2Buf(void);
static void bsp_ReadDatFromEEPROM(void);
void bsp_InitTubeVar(void)
{
uint8_t i = 0;
for (i = 0; i < 8; i++)
{
g_tTube.buf[i] = NO_NULL;
}
g_tTube.disp_mode = MODE_PULSE;
g_tTube.cnt = 0;
g_tTube.state = IDLE;
// g_tTube.state = WORK;
g_tTube.dir = DIR_CW;
g_tTube.pulse = 0;
g_tTube.tim_pulse_cnt = 0;
g_tTube.angle = 0;
}
void bsp_TubeTest(uint8_t _com, uint8_t _seg)
{
if (_seg == ' ')
_seg = NO_NULL;
if (_seg >= 12)
return;
CLOSE_ALL_TUBE_COM;
CLOSE_ALL_TUBE_SEG;
if (g_tube_table[_seg][0])
{
GPIO_PORT_A->BSRR = GPIO_PIN_A;
};
if (g_tube_table[_seg][1])
{
GPIO_PORT_B->BSRR = GPIO_PIN_B;
};
if (g_tube_table[_seg][2])
{
GPIO_PORT_C->BSRR = GPIO_PIN_C;
};
if (g_tube_table[_seg][3])
{
GPIO_PORT_D->BSRR = GPIO_PIN_D;
};
if (g_tube_table[_seg][4])
{
GPIO_PORT_E->BSRR = GPIO_PIN_E;
};
if (g_tube_table[_seg][5])
{
GPIO_PORT_F->BSRR = GPIO_PIN_F;
};
if (g_tube_table[_seg][6])
{
GPIO_PORT_G->BSRR = GPIO_PIN_G;
};
if ((_com == 5) && (g_tTube.disp_mode == MODE_ANGLE))
{
GPIO_PORT_H->BSRR = GPIO_PIN_H;
}
switch (_com)
{
case 0:
GPIO_PORT_DS1->BSRR = GPIO_PIN_DS1;
break;
case 1:
GPIO_PORT_DS2->BSRR = GPIO_PIN_DS2;
break;
case 2:
GPIO_PORT_DS3->BSRR = GPIO_PIN_DS3;
break;
case 3:
GPIO_PORT_DS4->BSRR = GPIO_PIN_DS4;
break;
case 4:
GPIO_PORT_DS5->BSRR = GPIO_PIN_DS5;
break;
case 5:
GPIO_PORT_DS6->BSRR = GPIO_PIN_DS6;
break;
case 6:
GPIO_PORT_DS7->BSRR = GPIO_PIN_DS7;
break;
case 7:
GPIO_PORT_DS8->BSRR = GPIO_PIN_DS8;
break;
default:
break;
}
}
void bsp_ToogleDispMode(void)
{
uint8_t buf[5]; // PULSE: 55AA00FF; ANGLE: FF00AA55
switch (g_tTube.disp_mode)
{
case MODE_PULSE:
g_tTube.disp_mode = MODE_ANGLE;
break;
case MODE_ANGLE:
g_tTube.disp_mode = MODE_PULSE;
break;
default:
break;
}
if (g_tTube.disp_mode == MODE_ANGLE)
{
buf[0] = 0xFF;
buf[1] = 0x00;
buf[2] = 0xAA;
buf[3] = 0x55;
ee_WriteBytes(buf, 0, 4);
}
else if (g_tTube.disp_mode == MODE_PULSE)
{
buf[0] = 0x55;
buf[1] = 0xAA;
buf[2] = 0x00;
buf[3] = 0xFF;
ee_WriteBytes(buf, 0, 4);
}
bsp_UpdateDisplayBuf();
}
void bsp_ToogleStateMode(void)
{
switch (g_tTube.state)
{
case IDLE:
g_tTube.state = WORK;
break;
case WORK:
g_tTube.state = IDLE;
break;
default:
break;
}
bsp_UpdateDisplayBuf();
}
void bsp_UpdateDisplayBuf(void)
{
uint8_t i = 0;
// 开机或执行了搜索命令但未找到零点时的数码管显示状态
if ((g_tTube.state == IDLE) || (g_tTube.state == SEARCH))
{
if (g_tTube.disp_mode == MODE_PULSE) // 数码管显示[--------]
{
memset(g_tTube.buf, NO__, 8);
}
else if (g_tTube.disp_mode == MODE_ANGLE) // 数码管显示[ -.--]
{
for (i = 0; i < 5; i++)
{
g_tTube.buf[i] = NO_NULL;
}
g_tTube.buf[5] = NO__;
g_tTube.buf[6] = NO__;
g_tTube.buf[7] = NO__;
}
}
else if (g_tTube.state == WORK) // 已经找到零点后数码管的显示状态
{
bsp_Angle2Buf(); // 数码管显示,例如[-1234567]
}
}
void bsp_Pulse2Buf(void)
{
uint8_t i = 0;
memset(g_tTube.buf, 0, 8);
snprintf(g_tTube.buf, 9, "%8d", g_tTube.pulse);
for (i = 0; i < 8; i++)
{
if (g_tTube.buf[i] == ' ')
{
g_tTube.buf[i] = NO_NULL;
}
else if (g_tTube.buf[i] == '-')
{
g_tTube.buf[i] = NO__;
}
else if (isdigit(g_tTube.buf[i]))
{
g_tTube.buf[i] = g_tTube.buf[i] - '0';
}
}
}
void bsp_Angle2Buf(void)
{
uint8_t i = 0;
float angle = (((g_tTube.pulse % STEP_PER_LAP) + STEP_PER_LAP) % STEP_PER_LAP) * 360.0f / (STEP_PER_LAP / 100.0f);
// printf("angle = %f\r\n", angle);
if (angle < 0)
{
angle -= 0.5f; // 负数向下取整
angle += 360.0f; // 转换成整角度
}
else
angle += 0.5f; // 正数向上取整
// printf("angle = %f\r\n", angle);
memset(g_tTube.buf, 0, 8);
g_tTube.angle = angle;
snprintf(g_tTube.buf, 9, "%8d", g_tTube.angle);
for (i = 0; i < 8; i++)
{
if (g_tTube.buf[i] == ' ')
{
g_tTube.buf[i] = NO_NULL;
if (i >= 5)
{
g_tTube.buf[i] = NO_0;
}
}
else if (g_tTube.buf[i] == '-')
{
if (i >= 5)
{
g_tTube.buf[4] = NO__;
g_tTube.buf[i] = NO_0;
}
else
{
g_tTube.buf[i] = NO__;
}
}
else if (isdigit(g_tTube.buf[i]))
{
g_tTube.buf[i] = g_tTube.buf[i] - '0';
}
}
}
void bsp_DigitalTubeMainLoop(void)
{
static uint8_t i = 0;
if (++i >= 50) // 该函数每1ms调用一次每50ms刷新一次脉冲或角度值
{
i = 0;
if (g_tTube.dir == DIR_CCW)
{
g_tTube.pulse = g_tMoto.pv_pulse;
}
else
{
g_tTube.pulse = g_tMoto.pv_pulse;
}
bsp_UpdateDisplayBuf();
}
bsp_TubeTest(g_tTube.cnt, g_tTube.buf[g_tTube.cnt]);
if (++g_tTube.cnt >= 8)
g_tTube.cnt = 0;
}
//------------------------------------------------------------------------------
// 函 数 名: bsp_InitDigitalTube
// 功能说明: 配置数码管相关的GPIO, 该函数被 bsp_Init() 调用。
// 形 参: 无
// 返 回 值: 无
//------------------------------------------------------------------------------
void bsp_InitDigitalTube(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 打开数码管GPIO时钟
RCC_APB2PeriphClockCmd(RCC_ALL_TUBE, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_A; // 位 a
GPIO_Init(GPIO_PORT_A, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_B; // 位 b
GPIO_Init(GPIO_PORT_B, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_C; // 位 c
GPIO_Init(GPIO_PORT_C, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_D; // 位 d
GPIO_Init(GPIO_PORT_D, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_E; // 位 e
GPIO_Init(GPIO_PORT_E, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_F; // 位 f
GPIO_Init(GPIO_PORT_F, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_G; // 位 g
GPIO_Init(GPIO_PORT_G, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_H; // 位 h
GPIO_Init(GPIO_PORT_H, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS1; // 段 1
GPIO_Init(GPIO_PORT_DS1, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS2; // 段 2
GPIO_Init(GPIO_PORT_DS2, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS3; // 段 3
GPIO_Init(GPIO_PORT_DS3, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS4; // 段 4
GPIO_Init(GPIO_PORT_DS4, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS5; // 段 5
GPIO_Init(GPIO_PORT_DS5, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS6; // 段 6
GPIO_Init(GPIO_PORT_DS6, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS7; // 段 7
GPIO_Init(GPIO_PORT_DS7, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_DS8; // 段 8
GPIO_Init(GPIO_PORT_DS8, &GPIO_InitStructure);
bsp_InitTubeVar();
bsp_ReadDatFromEEPROM();
bsp_UpdateDisplayBuf();
}
static void bsp_ReadDatFromEEPROM(void)
{
uint8_t buf[5]; // PULSE: 55AA00FF; ANGLE: FF00AA55
ee_ReadBytes((uint8_t *)buf, 0, 4);
if ((buf[0] == 0X55) && (buf[1] == 0XAA) && (buf[2] == 0X00) && (buf[3] == 0XFF))
{
g_tTube.disp_mode = MODE_PULSE;
}
else if ((buf[0] == 0XFF) && (buf[1] == 0X00) && (buf[2] == 0XAA) && (buf[3] == 0X55))
{
g_tTube.disp_mode = MODE_ANGLE;
}
}
//-------------------------------- End of file ---------------------------------