赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
本项目包含KEIL代码编写和Proteus代码仿真两部分,主要通过基础定时器实现时钟功能,难点在于在六位数码管上显示,本项目采用定时器3的中断,以一秒为一单位,重点对时间的处理,让小时,分钟,秒显示在数码管上,项目扩展部分,可以加入按键来进行一个时间的设置与校准。
Proteus仿真方面,配置好I/O后,在驱动数码管时,需要添加74LS245模块来增强I/O的驱动能力,数码管采用的是共阳极连接,对于段选和位选这里就不多赘述,值得注意的是,段选和位选的I/O分配最好不要都在一个I/O上,这样避免GPIO写入时发生冲突。
代码如下(示例):
#include "stm32f10x.h" #include "smg.h" void SMG_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //使能GPIOC时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = 0x00ff; //PC0-PC7引脚配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIOC速度为50MHz GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC0-PC7 GPIO_InitStructure.GPIO_Pin = 0x003f; //PB0-PC5引脚配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIOB速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB0-PB5 }
代码如下(示例):
#ifndef __SMG_H
#define __SMG_H
void SMG_Init(void);
#endif
#include "timer.h" #include "stm32f10x_tim.h" int count=0; // 通用定时器3中断初始化 // 这里时钟选择为APB1的2倍,而APB1为36M // arr:自动重装值。 // psc:时钟预分频数 // 这里使用的是定时器3! void TIM3_Int_Init(u16 arr, u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 时钟使能 // 定时器TIM3初始化 TIM_TimeBaseStructure.TIM_Period = arr; // 设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler = psc; // 设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 使能指定的TIM3中断,允许更新中断 // 中断优先级NVIC设置 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设定中断优先级分组0 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); // 初始化NVIC寄存器 TIM_Cmd(TIM3, ENABLE); // 使能TIMx } // 定时器3中断服务程序 void TIM3_IRQHandler (void) // TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) // 检查TIM3更新中断发生与否 { count++; TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除TIMx更新中断标志 } }
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
extern int count;
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
#include "stm32f10x.h" #include "Delay.h" #include "smg.h" #include "timer.h" //定义0~9十个数字的字型码表 uint16_t table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uint16_t wei[]={0x0fe,0x0fd,0x0fb,0x0f7,0x0ef,0x0df,0xff,0xff}; //位码; int main(void) { SMG_Init(); TIM3_Int_Init(719,9999); while(1) { if(count<60) { GPIO_Write(GPIOB,wei[0]); GPIO_Write(GPIOC,table[count%10]); Delay(10); GPIO_Write(GPIOB,wei[1]); GPIO_Write(GPIOC,table[count/10%10]); Delay(10); for(uint8_t i=2;i<=5;i++) { GPIO_Write(GPIOB,wei[i]); GPIO_Write(GPIOC,table[0]); Delay(10); } } if(count>=60||count<3600) { int m,n,t=0; n=count/60%10; m=count/60/10; t=count%60; GPIO_Write(GPIOB,wei[0]); GPIO_Write(GPIOC,table[t%10]); Delay(10); GPIO_Write(GPIOB,wei[1]); GPIO_Write(GPIOC,table[t/10%10]); Delay(10); GPIO_Write(GPIOB,wei[2]); GPIO_Write(GPIOC,table[n]); Delay(10); GPIO_Write(GPIOB,wei[3]); GPIO_Write(GPIOC,table[m]); Delay(10); GPIO_Write(GPIOB,wei[4]); GPIO_Write(GPIOC,table[0]); Delay(10); GPIO_Write(GPIOB,wei[5]); GPIO_Write(GPIOC,table[0]); Delay(10); } if(count>=3600||count<86400) { int m,n,t,x,y,q=0; x=count/3600/10; y=count/3600%10; q=count%3600; m=q/60/10; n=q/60%10; t=q%60; GPIO_Write(GPIOB,wei[0]); GPIO_Write(GPIOC,table[t%10]); Delay(10); GPIO_Write(GPIOB,wei[1]); GPIO_Write(GPIOC,table[t/10%10]); Delay(10); GPIO_Write(GPIOB,wei[2]); GPIO_Write(GPIOC,table[n]); Delay(10); GPIO_Write(GPIOB,wei[3]); GPIO_Write(GPIOC,table[m]); Delay(10); GPIO_Write(GPIOB,wei[4]); GPIO_Write(GPIOC,table[y]); Delay(10); GPIO_Write(GPIOB,wei[5]); GPIO_Write(GPIOC,table[x]); Delay(10); } } }
在项目开发时候,需要理解数码管的工作原理,理解段选和位选的区别,对于数码管动态显示来说,认识到同一时间数码管只能显示一位,重点在于定时器中断后时间的处理,需要对数据进行分解。Proteus仿真方面,芯片调频72MHz。
代码和模型文件:
链接:https://pan.quark.cn/s/25e64b55ec13
提取码:CG29
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。