硬件设计
链接:https://pan.baidu.com/s/13imCGlvfuT-N3VYs_wGzYA
提取码:pqlz
仿真图如下所示:
程序设计
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include <stdio.h>
#include "timer.h"
#include "key.h"
#include "lcd1602.h"
char tab0[16]; //暂存数组
char tab1[16]; //暂存数组
unsigned char i;//中间变量i
unsigned int Dtimes = 0; //计时
unsigned int keyFlag = 0;//按键按下标志
void CheckKey(void);
//设置向量表偏移地址
//NVIC_VectTab:基址
//Offset:偏移量
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
//用于标识向量表是在CODE区还是在RAM区
}
void MYRCC_DeInit(void)
{
RCC->APB1RSTR = 0x00000000;//复位结束
RCC->APB2RSTR = 0x00000000;
RCC->AHBENR = 0x00000014; //睡眠模式闪存和SRAM时钟使能.其他关闭.
RCC->APB2ENR = 0x00000000; //外设时钟关闭.
RCC->APB1ENR = 0x00000000;
RCC->CR |= 0x00000001; //使能内部高速时钟HSION
RCC->CFGR &= 0xF8FF0000; //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC->CR &= 0xFEF6FFFF; //复位HSEON,CSSON,PLLON
RCC->CR &= 0xFFFBFFFF; //复位HSEBYP
RCC->CFGR &= 0xFF80FFFF; //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
RCC->CIR = 0x00000000; //关闭所有中断
//配置向量表
#ifdef VECT_TAB_RAM
MY_NVIC_SetVectorTable(0x20000000, 0x0);
#else
MY_NVIC_SetVectorTable(0x08000000,0x0);
#endif
}
//系统时钟初始化函数
//pll:选择的倍频数,从2开始,最大值为16
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;
MYRCC_DeInit(); //复位并配置向量表
RCC->CR|=0x00010000; //外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2; //抵消2个单位(因为是从2开始的,设置0就是2)
RCC->CFGR|=PLL<<18; //设置PLL值 2~16
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x32; //FLASH 2个延时周期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟
while(temp!=0x02) //等待PLL作为系统时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
int main(void)
{
//uart_init(9600); //串口初始化为115200
// uart2_init(9600) ;
LED_Init(); //初始化与LED连接的硬件接口
delay_init(); //延时函数初始化
Stm32_Clock_Init(9); //系统时钟设置 72M .仿真时钟选8M
Lcd_GPIO_init();
Lcd_Init();
Lcd_Puts(0,0,"READY? GO!!!");
KEY_Init();
TIM3_Int_Init(49,7199);//50ms 仿真时间无法精确
//TIM3_Int_Init(499,7199);//50ms 实物程序定时器用此语句。
// Led = 1 ;//初始化先关闭LED灯
while(1)
{
if(keyFlag == 0)//按键无任何按下
{
CheckKey(); //按键设置
PAout(keyFlag)=0;
}
if(Host == 0)//主持人按键,按下重新开始抢答
{
delay_ms(10);
if(Host == 0)
{
PAout(keyFlag)=1;
Dtimes=0;
sprintf(tab1," NO BODY");//没有人按键
keyFlag = 0;
disFlag=0;
PAout(9)=0;
}
}
if(disFlag==1) //显示
{
disFlag = 0;
if(keyFlag == 0)
{
Dtimes++;
sprintf(tab1," NO BODY ");//没有人按键
}
else
{
sprintf(tab1," %d ",keyFlag);//显示按键的值
PAout(9)=1;
}
Lcd_Puts(0,1,(unsigned char *)tab1); //初始化显示
sprintf(tab0,"time :%5.1fs ",(float)(Dtimes-1)/10); //显示时间
Lcd_Puts(0,0,(unsigned char *)tab0); //初始化显示
//Beep = 1;
}
}
}
.
.