STM32F103RB数码管定时(秒表)
实验功能:三位数码管实现十分钟计时,最左边数码管显示分钟数,中间和右边的数码管显示秒数。
硬件单路
配置TIM2及其中断代码片如下(示例)
void TIM2_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//设置TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断源
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_Init(void) // 1S
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitStruct.TIM_Prescaler = (2000-1);//预分频系数 2000-1s
TIM_TimeBaseInitStruct.TIM_Period = (36000-1);//自动重载计数周期值
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//设置为向上计数方式
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能TIM2的更新中断
TIM_Cmd(TIM2, ENABLE);//使能TIM2定时器
}
中断执行函数代码片如下(示例)
int num=0;
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
{
num++;
s++;
if(s==10)s=0;
if(num%10==0) m++;
if(m==6)m=0;
if(num%60==0)h++;
if(h==10)h=0;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
seg.c(数码管)代码片如下(示例)
#include “seg.h”
void SEG_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SEG_Disp(unsigned char ucData1, unsigned char ucData2,
unsigned char ucData3, unsigned char ucDot)
{
unsigned char i;
// unsigned char code[17]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
// 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00}; //直接定义好了0123——15
unsigned char code[17]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f};
//0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};
unsigned long ulData = (code[ucData3] 《《 16) + (code[ucData2] 《《 8)
+ code[ucData1];
ulData += (ucDot&1)《《23; //个位
ulData += (ucDot&2)《《14; //十位
ulData += (ucDot&4)《《5; //百位
/*
SER(串行数据输入)--PA1
SCK(移位时钟) --PA3
RCK(输出锁存) --PA2
*/
for(i=0; i《24; i++)
{
if(ulData & 0x800000) //0x800000 24 三个八位
GPIO_SetBits(GPIOA, GPIO_Pin_1); // PA1(SER)=1
else
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // PA1(SER)=0
ulData 《《= 1;
GPIO_SetBits(GPIOA, GPIO_Pin_3); // PA3(SCK)=1
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // PA3(SCK)=0
}
GPIO_SetBits(GPIOA, GPIO_Pin_2); // PA2(RCK)=1
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // PA2(RCK)=0
}
说明:void SEG_Init(void) 此函数初始化锁存器的三个引脚分别对应
SEG_Disp() 函数中code[17]数组中直接定义好了数码管的数字显示,直接调用
ucData1 ucData2 ucData3 分别对应数码管最左边,中间,最右边位的数码管
ucDot 定义了数码管右下角的小数点,按照二进制的思想取数可取数0-7。
STM32F103RB数码管定时(秒表)
实验功能:三位数码管实现十分钟计时,最左边数码管显示分钟数,中间和右边的数码管显示秒数。
硬件单路
配置TIM2及其中断代码片如下(示例)
void TIM2_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//设置TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断源
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_Init(void) // 1S
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitStruct.TIM_Prescaler = (2000-1);//预分频系数 2000-1s
TIM_TimeBaseInitStruct.TIM_Period = (36000-1);//自动重载计数周期值
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//设置为向上计数方式
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能TIM2的更新中断
TIM_Cmd(TIM2, ENABLE);//使能TIM2定时器
}
中断执行函数代码片如下(示例)
int num=0;
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
{
num++;
s++;
if(s==10)s=0;
if(num%10==0) m++;
if(m==6)m=0;
if(num%60==0)h++;
if(h==10)h=0;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
seg.c(数码管)代码片如下(示例)
#include “seg.h”
void SEG_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SEG_Disp(unsigned char ucData1, unsigned char ucData2,
unsigned char ucData3, unsigned char ucDot)
{
unsigned char i;
// unsigned char code[17]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
// 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00}; //直接定义好了0123——15
unsigned char code[17]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f};
//0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};
unsigned long ulData = (code[ucData3] 《《 16) + (code[ucData2] 《《 8)
+ code[ucData1];
ulData += (ucDot&1)《《23; //个位
ulData += (ucDot&2)《《14; //十位
ulData += (ucDot&4)《《5; //百位
/*
SER(串行数据输入)--PA1
SCK(移位时钟) --PA3
RCK(输出锁存) --PA2
*/
for(i=0; i《24; i++)
{
if(ulData & 0x800000) //0x800000 24 三个八位
GPIO_SetBits(GPIOA, GPIO_Pin_1); // PA1(SER)=1
else
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // PA1(SER)=0
ulData 《《= 1;
GPIO_SetBits(GPIOA, GPIO_Pin_3); // PA3(SCK)=1
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // PA3(SCK)=0
}
GPIO_SetBits(GPIOA, GPIO_Pin_2); // PA2(RCK)=1
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // PA2(RCK)=0
}
说明:void SEG_Init(void) 此函数初始化锁存器的三个引脚分别对应
SEG_Disp() 函数中code[17]数组中直接定义好了数码管的数字显示,直接调用
ucData1 ucData2 ucData3 分别对应数码管最左边,中间,最右边位的数码管
ucDot 定义了数码管右下角的小数点,按照二进制的思想取数可取数0-7。
举报