基于STM32的簡易電子秒表仿真設(shè)計(仿真+程序+設(shè)計報告+講解)
仿真圖proteus 8.9
程序編譯器:keil 5
編程語言:C語言
設(shè)計編號:C0078
視頻演示
基于STM32的簡易電子秒表proteus仿真設(shè)計
1.主要功能
結(jié)合實際情況,基于STM32F103單片機設(shè)計一個電子秒表。該設(shè)計應(yīng)滿足的功能要求為:
1、以STM32為最小系統(tǒng)電路進行連接,用四位數(shù)碼管顯示計時時間。
2、三個按鍵作為開始、清零、暫停來控制秒表的計時。
3、計時精確度為0.1S,最大可以顯示999.9s
主要硬件設(shè)備:STM32F103單片機、四位數(shù)碼管。
以下為本設(shè)計資料展示:
2.仿真
整體設(shè)計方案
該系統(tǒng)為電子秒表設(shè)計系統(tǒng),其主要的硬件設(shè)計:以stm32為最小系統(tǒng)電路進行連接,用數(shù)碼管顯示秒表計時時間。
測試如下所示:
開始仿真后顯示000.0,等待開始按鍵按下后開始計時,0.1秒增加一次計時。
按下暫停按鍵后暫停計時,顯示當前計時的時間。如下圖所示:
3. 程序
主函數(shù):
#include "stm32f10x.h"
#include "main.h"
//定義數(shù)碼管的引腳
#define SEG_A PC(12)
#define SEG_B PC(11)
#define SEG_C PC(10)
#define SEG_D PC(9)
#define SEG_E PC(8)
#define SEG_F PC(7)
#define SEG_G PC(6)
#define SEG_DP PC(5)
#define SEG1 PC(4)
#define SEG2 PC(3)
#define SEG3 PC(2)
#define SEG4 PC(1)
//定義數(shù)按鍵的引腳
#define K1 PBIN(15)
#define K2 PBIN(14)
#define K3 PBIN(13)
//共陽數(shù)碼管段碼表0-F
const char CAseg_table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//共陰數(shù)碼管段碼表0-F
const char CCseg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u8 Time_count=0;//計時時間
//初始化引腳
void GPIO_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_All);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_All);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//把數(shù)值輸出到具體的單片機引腳
void Drv_SEG(u8 num)
{
SEG_A=GETVALBIT(num,0);
SEG_B=GETVALBIT(num,1);
SEG_C=GETVALBIT(num,2);
SEG_D=GETVALBIT(num,3);
SEG_E=GETVALBIT(num,4);
SEG_F=GETVALBIT(num,5);
SEG_G=GETVALBIT(num,6);
SEG_DP=GETVALBIT(num,7);
}
//驅(qū)動數(shù)碼管的函數(shù)
//mode =0表示共陽,mode=1表示共陰,可以通過這個修改
//m是要顯示的數(shù)字,比如1.0就是m=10,放大10倍
void Show_num(u16 m)
{
u8 num=0,n=0;
static u8 temp_flag=0;
//數(shù)碼管消隱
SEG1=0;SEG2=0;SEG3=0;SEG4=0;
switch(temp_flag)
{
case 0://左側(cè)第1位數(shù)碼管
n=m/1000;//取數(shù)據(jù)
num=CAseg_table[n];//查詢數(shù)碼管的斷碼表
Drv_SEG(num);
SEG1=1;//打開數(shù)碼管顯示
temp_flag++;
break;
case 1://左側(cè)第2位數(shù)碼管
n=m%1000/100;//取數(shù)據(jù)
num=CAseg_table[n];//查詢數(shù)碼管的斷碼表
Drv_SEG(num);
SEG2=1;//打開數(shù)碼管顯示
temp_flag++;
break;
case 2://左側(cè)第3位數(shù)碼管
n=m%100/10;//取數(shù)據(jù)
num=CAseg_table[n]&0x7f;//查詢數(shù)碼管的斷碼表
Drv_SEG(num);
SEG3=1;//打開數(shù)碼管顯示
temp_flag++;
break;
case 3://左側(cè)第4位數(shù)碼管
n=m%10;//取數(shù)據(jù)
num=CAseg_table[n];//查詢數(shù)碼管的斷碼表
Drv_SEG(num);
SEG4=1;//打開數(shù)碼管顯示
temp_flag=0;
break;
}
Delay_ms(10);//延時
}
//獲取獨立按鍵數(shù)據(jù)
u8 Get_key_num()
{
u8 temp_key=0;
static u8 flag=0;
if((flag==0)&&((K1==0)||(K2==0)||(K3==0)))
{
flag=1;//按鍵只獲取一次按鍵數(shù)值
SysTick_Delay_Ms(10);//消除抖動
//如果有對應(yīng)的按鍵按下就返回對應(yīng)按鍵數(shù)值
if(K1==0)
{temp_key=1;}
else if(K2==0)
{temp_key=2;}
else if(K3==0)
{temp_key=3;}
}
else if((K1==1)&&(K2==1)&&(K3==1))
{
flag=0;//所有按鍵都彈起就清除標志
}
return temp_key;
}
//定時器初始化
void TimInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_DeInit(TIM2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 999; // 10mS
TIM_TimeBaseStructure.TIM_Prescaler = (80-1); // 10uS,這里配合仿真是8M,所以是80,如果是72M那么就是720,仿真沒有備倍頻
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_PrescalerConfig(TIM2, 80-1, TIM_PSCReloadMode_Immediate); // 10uS,這里配合仿真是8M,所以是80,如果是72M那么就是720,仿真沒有備倍頻
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
//定時器服務(wù)函數(shù)
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if(++Time_count>250)Time_count=250;//時間計時
}
}
int main(void)
{
u8 key_num=0;//按鍵數(shù)值
u16 dis_num=0;
u8 mode=0;
GPIO_Config(); //初始化引腳
TimInit(); //初始化定時器
while(1)
{
key_num=Get_key_num();//讀取按鍵
switch(key_num)
{
case 1://開始按鍵
TIM_Cmd(TIM2, ENABLE);
mode=1;//開始
break;
case 2://暫停按鍵
TIM_Cmd(TIM2, DISABLE);
mode=2;//暫停
break;
case 3://清除按鍵
TIM_Cmd(TIM2, DISABLE);
Time_count=0;
dis_num=0;
mode=0;//清除顯示
break;
}
if(mode==1)//開始
{
if(Time_count>=10)//每0.1s增加1
{
Time_count=0;
if(++dis_num>9999)dis_num=9999;//最大999.9s
}
}
Show_num(dis_num);//刷新數(shù)碼管顯示
}
}
4. 設(shè)計報告
報告部分內(nèi)容
二、主控制器選擇
2.1 stm32f103芯片的概述
STM32單片機有很多個系列,其中包括基本型、USB基本型、增強型以及互聯(lián)型幾大系列,這寫系列的STM32單片機都是具有性能高、功耗低、成本低等特點。其內(nèi)部結(jié)構(gòu)圖如圖 2.2所示:
? 圖 2.2 STM32內(nèi)部結(jié)構(gòu)圖
本課題采用的是STM32F103C8T6單片機芯片,這是是一款A(yù)RM M3內(nèi)核的增強型微控制器,這款內(nèi)核的工作頻率是能夠達到72MHz的,它擁有著128K字節(jié)的閃存和極其豐富的外設(shè),如GPIO口,串口,定時器,中斷,數(shù)模轉(zhuǎn)換,實時時鐘,看門狗,SPI,IIC,CAN總線等部分組成。STM32F103系列單片機的性能在同一個類別的產(chǎn)品中是最高的,它能夠在-40°C -85°C溫度下正常地進行工作,工作的電壓范圍為2V-3.6V,具有低功耗的節(jié)能工作模式,閃存存儲器的容量為64K字節(jié)。
5.資料清單&下載鏈接
百度網(wǎng)盤分享下載鏈接:
https://docs.qq.com/doc/DS21hQUpNd3JabkZt