写程序的思路是位选置1,段选为0的地方点亮显示。一般动态显示需要用到延时用于视觉暂留,以前用delay函数空等待,这样只能放在main函数的while循环里面,如果while函数中有程序占用时间过长会产生闪烁的感觉。放在定时器中断里面也会出问题。于是就取消delay函数,把动态扫描程序放在定时器中断中,利用定时器来切换数码管显示位置,方便很多。
1、先在CubeMX配置引脚 全部是输出口
2、原理图
SMG_A SMG_B SMG_C SMG_D SMG_E SMG_F SMG_G SMG_H DIG1 DIG2 DIG3 DIG4 DIG5 DIG6 DIG7 DIG8
A4 A5 A6 A7 A8 A9 A10 A11 B11 B12 B13 A0 A1 C13 C14 C15
main.h
/* USER CODE BEGIN Private defines */
#define SMG_A(a) (a?HAL_GPIO_WritePin(SMG_A_GPIO_Port,SMG_A_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_A_GPIO_Port,SMG_A_Pin,GPIO_PIN_RESET))
#define SMG_B(a) (a?HAL_GPIO_WritePin(SMG_B_GPIO_Port,SMG_B_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_B_GPIO_Port,SMG_B_Pin,GPIO_PIN_RESET))
#define SMG_C(a) (a?HAL_GPIO_WritePin(SMG_C_GPIO_Port,SMG_C_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_C_GPIO_Port,SMG_C_Pin,GPIO_PIN_RESET))
#define SMG_D(a) (a?HAL_GPIO_WritePin(SMG_D_GPIO_Port,SMG_D_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_D_GPIO_Port,SMG_D_Pin,GPIO_PIN_RESET))
#define SMG_E(a) (a?HAL_GPIO_WritePin(SMG_E_GPIO_Port,SMG_E_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_E_GPIO_Port,SMG_E_Pin,GPIO_PIN_RESET))
#define SMG_F(a) (a?HAL_GPIO_WritePin(SMG_F_GPIO_Port,SMG_F_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_F_GPIO_Port,SMG_F_Pin,GPIO_PIN_RESET))
#define SMG_G(a) (a?HAL_GPIO_WritePin(SMG_G_GPIO_Port,SMG_G_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_G_GPIO_Port,SMG_G_Pin,GPIO_PIN_RESET))
#define SMG_H(a) (a?HAL_GPIO_WritePin(SMG_H_GPIO_Port,SMG_H_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SMG_H_GPIO_Port,SMG_H_Pin,GPIO_PIN_RESET))
#define DIG1(a) (a?HAL_GPIO_WritePin(DIG1_GPIO_Port,DIG1_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG1_GPIO_Port,DIG1_Pin,GPIO_PIN_RESET))
#define DIG2(a) (a?HAL_GPIO_WritePin(DIG2_GPIO_Port,DIG2_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG2_GPIO_Port,DIG2_Pin,GPIO_PIN_RESET))
#define DIG3(a) (a?HAL_GPIO_WritePin(DIG3_GPIO_Port,DIG3_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG3_GPIO_Port,DIG3_Pin,GPIO_PIN_RESET))
#define DIG4(a) (a?HAL_GPIO_WritePin(DIG4_GPIO_Port,DIG4_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG4_GPIO_Port,DIG4_Pin,GPIO_PIN_RESET))
#define DIG5(a) (a?HAL_GPIO_WritePin(DIG5_GPIO_Port,DIG5_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG5_GPIO_Port,DIG5_Pin,GPIO_PIN_RESET))
#define DIG6(a) (a?HAL_GPIO_WritePin(DIG6_GPIO_Port,DIG6_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG6_GPIO_Port,DIG6_Pin,GPIO_PIN_RESET))
#define DIG7(a) (a?HAL_GPIO_WritePin(DIG7_GPIO_Port,DIG7_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG7_GPIO_Port,DIG7_Pin,GPIO_PIN_RESET))
#define DIG8(a) (a?HAL_GPIO_WritePin(DIG8_GPIO_Port,DIG8_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(DIG8_GPIO_Port,DIG8_Pin,GPIO_PIN_RESET))
main.c
/* USER CODE BEGIN PD */
#define DIS_NUM 7
/* USER CODE END PD */
// 0 1 2 3 4 5 6 7 8 9 A B C D E F 全灭 .
uint8_t smg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x7f};
//数码管位选表,最后一位表示全部不选择
uint8_t numb[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uint8_t dis_pos=0; //数码管显示位置
/*******************************************************************************
* Function Name : Write_data
* Description : 数码管写段选
* Input : data :要发送的段选数据
* Output : None
* Return : None
*******************************************************************************/
void Write_data(uint8_t data)
{
if((data & 0x80) >> 7) SMG_H(1);
else SMG_H(0);
if((data & 0x40) >> 6) SMG_G(1);
else SMG_G(0);
if((data & 0x20) >> 5) SMG_F(1);
else SMG_F(0);
if((data & 0x10) >> 4) SMG_E(1);
else SMG_E(0);
if((data & 0x08) >> 3) SMG_D(1);
else SMG_D(0);
if((data & 0x04) >> 2) SMG_C(1);
else SMG_C(0);
if((data & 0x02) >> 1) SMG_B(1);
else SMG_B(0);
if((data & 0x01) ) SMG_A(1);
else SMG_A(0);
}
/*******************************************************************************
* Function Name : dis_bit
* Description : 数码管显示位置,用于选择某个要显示的数码管
* Input : pos : 数码管位置
* Output : None
* Return : None
*******************************************************************************/
void dis_bit(uint8_t pos)
{
switch(pos)
{
case 0x01:
DIG1(0); DIG2(1); DIG3(1); DIG4(1); DIG5(1); DIG6(1); DIG7(1); DIG8(1);
break;
case 0x02:
DIG1(1); DIG2(0); DIG3(1); DIG4(1); DIG5(1); DIG6(1); DIG7(1); DIG8(1);
break;
case 0x04:
DIG1(1); DIG2(1); DIG3(0); DIG4(1); DIG5(1); DIG6(1); DIG7(1); DIG8(1);
break;
case 0x08:
DIG1(1); DIG2(1); DIG3(1); DIG4(0); DIG5(1); DIG6(1); DIG7(1); DIG8(1);
break;
case 0x10:
DIG1(1); DIG2(1); DIG3(1); DIG4(1); DIG5(0); DIG6(1); DIG7(1); DIG8(1);
break;
case 0x20:
DIG1(1); DIG2(1); DIG3(1); DIG4(1); DIG5(1); DIG6(0); DIG7(1); DIG8(1);
break;
case 0x40:
DIG1(1); DIG2(1); DIG3(1); DIG4(1); DIG5(1); DIG6(1); DIG7(0); DIG8(1);
break;
case 0x80:
DIG1(1); DIG2(1); DIG3(1); DIG4(1); DIG5(1); DIG6(1); DIG7(1); DIG8(0);
break;
}
}
/*******************************************************************************
* Function Name : dis_num
* Description : 数码管显示数据
* Input : num:要显示的数据
* Output : None
* Return : None
*******************************************************************************/
void dis_num(uint16_t num1,uint16_t num2)
{
uint8_t tab[8]; //定义一个数组,用于存放各个数码管显示的数据
tab[7]=smg_code[num1%10000/1000]& smg_code[17];
tab[6]=smg_code[num1%1000/100];
tab[5]=smg_code[num1%100/10] ;
tab[4]=smg_code[num1%10]; //分离数据
tab[3]=smg_code[num2%10000/1000];
tab[2]=smg_code[num2%1000/100];
tab[1]=smg_code[num2%100/10] & smg_code[17];
tab[0]=smg_code[num2%10]; //分离数据
Write_data(smg_code[16]); //段选全不亮,消影
Write_data(tab[dis_pos]); //送段选
dis_bit(numb[dis_pos]); //送位选
}
显示的内容要在定时器里写
dis_num(1200,time); //显示数据
dis_pos++; //数码管位置变化1位
if(dis_pos>DIS_NUM) dis_pos=0; //限定数码管显示位数,可改小DIS_NUM得到想要的位数
主题授权提示:请在后台主题设置-主题授权-激活主题的正版授权,授权购买:RiTheme官网
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。