所谓动态扫描显示即轮流向各位数码管送出段码和位码,利用发光管的余辉和人眼视觉暂留作用,使人眼的感觉好像各位数码管同时都在显示。明确了原理,我们要使电压电流表的三个位同时显示不同的值需要用到CW32的定时器功能,在定时器的中断服务程序里面执行显示刷新的动作。有关CW32的定时器和中断的相关知识请查看链接:【CW32F003E4核心板】入门学习教程。本文只讲述如何配置定时器中断并执行数码管刷新函数。
在配置定时器之前需要注意是否将系统时钟树配置完成,定时器利用了高级外设时钟 PCLK,在之前的时钟配置中,我们将高级外设时钟 PCLK的频率配置成了6MHz,这将影响我们对定时器的预分频和装填计数值的配置。
在本次实验中,我们使用定时器BTIM1进行中断配置,代码如下:
#include "BTIM1.h"
void Btim1_Init(void)
{
BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct;
__RCC_BTIM_CLK_ENABLE(); //使能BTIM的时钟
NVIC_EnableIRQ(BTIM1_IRQn); //使能BTIM1的中断
BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER;//将定时器配置为计时模式
BTIM_TimeBaseInitStruct.BTIM_Period = 6000 - 1; // 1ms采集1次
BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV1; // 6MHZ÷1÷6000 = 1000Hz
BTIM_TimeBaseInitStruct.BTIM_OPMode = BTIM_OPMode_Repetitive;//配置定时器连续运行
BTIM_TimeBaseInit(CW_BTIM1, &BTIM_TimeBaseInitStruct); //初始化BTIM1
BTIM_ITConfig(CW_BTIM1, BTIM_IT_OV, ENABLE); //配置BTIM1的中断,定时器溢出产生中断
BTIM_Cmd(CW_BTIM1, ENABLE); //使能BTIM1
}
在上一节的数码管显示数字的数码管显示模块Seg_Dis.c文件中,我们还需要添加三个函数和定义一个数组 Seg_Reg 来完成动态显示的功能。
uint8_t Seg_Reg[3] = {0,0,0}; //这个数组存放数码管显示三位的数字,0~9
void Close_Com(void) //关闭所有数码管的显示,防止重影
{
GPIO_WritePin(CW_GPIOB,GPIO_PIN_7,GPIO_Pin_SET); //PB07,COM1
GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_Pin_SET); //PC03,COM2
GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_Pin_SET); //PC02,COM3
}
void Display(uint32_t value)
{
uint8_t Hundreds;// 百位数
uint8_t Tens; // 十位数
uint8_t Units; // 个位数
Units = value % 10; //分别取余获得位数的值
Tens = value / 10 % 10;
Hundreds = value / 100 % 10;
Seg_Reg[0] = Hundreds; //将个十百位的数字分别存放进数组等待调用
Seg_Reg[1] = Tens;
Seg_Reg[2] = Units;
}
void Dis_Refresh(void) //函数将在定时器中断里调用,不断刷新数码管
{
/*静态变量从作用域上分属于局部变量;从生命周期上来看,它与用户程序的生命周期相同。*/
static uint8_t num = 0; //这里的静态临时变量num,轮询Seg_Reg数组
Close_Com(); //先关闭公共端,防止重影
Seg_Dis(num,Seg_Reg[num]); //调用显示函数
num++;
if(num > 2)
{
num = 0;
}
}
最后在定时器中断里不断调用显示刷新函数完成数码管的刷新显示:
void BTIM1_IRQHandler(void) //BTIM1的中断服务程序
{
static uint32_t Cnt=0; //Cnt作为计数标志位控制刷新函数是否执行
if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
{
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV); //清除中断标志位
Cnt++;
if (Cnt > 2) //3ms显示一个数码管
{
Cnt = 0;
Dis_Refresh(); //数码管扫描显示
}
}
}
最终的实验效果如下图所示,人眼已经看不出闪烁,但实际上数码管是依次刷新显示。
图5-1 数码管动态显示效果图
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !