引言
终于轮到我们最后的八段LED了!作为秒表的眼睛,必不可少的就是显示模块。
八段LED初始化
直接就叫做LED_Init()吧
void LED_Init(void)
{
GPIO_InitTypeDef led;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
led.GPIO_Mode=GPIO_Mode_IPU;
led.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;;
led.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &led);
}
我先选取的是共阳极LED显像管。
当我们写下时,所有引脚输出高电平,直接显示错误。
根据我之前讲的课,我们使用的led当位选调制为低电平时,led关闭显示。
当led段选调制为高电平时,led不显示字符。
所以就会有对ODR寄存器的操作!全部关掉。
GPIOE->ODR=GPIOE->ODR&0xff00;
将低八位的电压拉低,关闭led的显示。
将高八位的2电压拉高,关闭led的字符段选。
GPIOE->ODR=0xff00;
构建字符库与显示函数
查阅我们的LED字符库我们就可以构建:
const uint16_t GLedSeg[]={~0x3f, ~0x06, ~0x5b, ~0x4f, ~0x66, ~0x6d, ~0x7d, ~0x07, ~0x7f, ~0x6f, ~0x40};
干脆我们把它写进我们的显示函数中Display(); =》【位选第一位+段选】【位选第二位+段选】——【循环至第八位】
void Display(uint16_t wei=0,uint16_t duan=0;)
{
const uint16_t GLedSeg[]={~0x3f, ~0x06, ~0x5b, ~0x4f, ~0x66, ~0x6d, ~0x7d, ~0x07, ~0x7f, ~0x6f, ~0x40};
uint16_t wei=0;
uint16_t duan=0;
if(wei>7)
{
wei=0;
}
GPIO->ODR=0xff00;
PEout(wei)=1;
if(duan<=9)
{
valueODR = GPIOE->ODR & 0x00ff;
valueODR |= ((uint16_t)(GLedSeg[duan]))<<8;
GPIOE->ODR = valueODR;
}
else
{
valueODR = GPIOE->ODR & 0x00ff;
valueODR |= ((uint16_t)(GLedSeg[10]))<<8;
GPIOE->ODR = valueODR;
}
}
选中位再输出段,但如果段不在我们的范围内输出“——”。
时间显示函数
我们刚刚完成了可以显示数字的函数,现在我们使用它来显示我们的时间。
void DispTime(TimeTypeDef *ptime)
{
Display(6, ptime->sec01);
delay(10000);
Display(5, 10); //'-'
delay(10000);
Display(4, ptime->sec%10);
delay(10000);
Display(3, ptime->sec/10);
delay(10000);
Display(2, 10); //'-'
delay(10000);
Display(1, ptime->min%10);
delay(10000);
Display(0, ptime->min/10);
delay(10000);
}
这里就讲一下我们的计算过程:
第六位显示秒的精度
第5位显示“——”
第四位显示分钟的个位:假设sec=51
51%10=1(取余数)
第三位显示分的十位:
52%10=5(取十位)
下面同理。
再说一下我们这里的指针,可以直接查询我们定时器定的值。例如:
GPIOE->ODR
最后一节课我们直接优化一下全部代码!!!然后就漂漂亮亮地完成了我们的课程设计。
我也会上传相关代码提供给大家参考!