一、项目配置

1、新建项目文件夹"TimSeg";

2、通过Keil5创建新项目,保存在所创建的文件夹中(设项目名为pTimSeg),选择MCU芯片为"STM32F103ZE"(本程序使用的硬件为:STM32-PZ6806L开发板)

3、在"TimSeg"文件夹下新建"CMSIS"、"Device"、"Public"、"Startup"、"User"和"Lib"文件夹。

① 在"CMSIS"文件夹中复制"core_cm3.h"和"core_cm3.c"文件;

② 在" Device "文件夹中复制"stm32f10x.h"、"system_stm32f10x.h"和"system_stm32f10x.c"文件;

③ 在" Startup "文件夹中复制"startup_stm32f10x_hd.s"文件;

④在"Lib"文件夹中新建"inc"和"src"两个子文件夹,在"inc"文件夹中复制"misc.h"、"stm32f10x_gpio.h"、"stm32f10x_tim.h"和"stm32f10x_rcc.h"文件;在"src"文件夹中复制"misc.c"、"stm32f10x_gpio.c"、"stm32f10x_tim.c"和"stm32f10x_rcc.c"文件;

4、为项目添加"CMSIS"、"Device"、"Public"、"Startup"、"User"和"Lib"组,并将上述C程序文件和"startup_stm32f10x_hd.s"启动文件加入到相应组中。

5、打开“项目配置”对话框,在"Output"选项卡中选择"Create HEX File",在"C/C++"选项卡中的"Include Paths"中添加如下包含路径:".CMSIS;", ".Device;", ".Libinc;",".Public;"。

6、在"stm32f10x.h"中添加函数参数检查宏

(参看:https://blog.csdn.net/fanxp66/article/details/80215090)

#ifdef  USE_FULL_ASSERT

/**

* @brief  这个assert_param宏用于函数参数检查

* @param  expr:如果expr是 false,就调用 assert_failed函数报告源文件名和

*         失败的行号,如果expr是 true ,就返回一个空值

* @retval None

*/

#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))

/* Exported functions ------------------------------------------------------- */

void assert_failed(uint8_t* file, uint32_t line);

#else

#define assert_param(expr) ((void)0)

#endif /* USE_FULL_ASSERT */

7、新建一个文件(system.h),保存到"Public"文件夹中,内容为:

#ifndef __SYSTEM__H

#define __SYSTEM__H

#include "stm32f10x.h"

//定义位带地址宏

#define BITBAND(addr,bitnum) ((addr&0xF0000000) + 0x02000000 + ((addr&0x000FFFFF)<<5) + (bitnum<<2))

#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))

#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))

//IO口地址映射

//数据输出寄存器地址

#define GPIOA_ODR_Addr          (GPIOA_BASE + 12)

#define GPIOB_ODR_Addr (GPIOB_BASE + 12)

#define GPIOC_ODR_Addr (GPIOC_BASE + 12)

#define GPIOD_ODR_Addr          (GPIOD_BASE + 12)

#define GPIOE_ODR_Addr (GPIOE_BASE + 12)

#define GPIOF_ODR_Addr (GPIOF_BASE + 12)

#define GPIOG_ODR_Addr          (GPIOG_BASE + 12)

//数据输入寄存器地址

#define GPIOA_IDR_Addr  (GPIOA_BASE + 12)

#define GPIOB_IDR_Addr  (GPIOB_BASE + 12)

#define GPIOC_IDR_Addr  (GPIOC_BASE + 12)

#define GPIOD_IDR_Addr  (GPIOD_BASE + 12)

#define GPIOE_IDR_Addr   (GPIOE_BASE + 12)

#define GPIOF_IDR_Addr   (GPIOF_BASE + 12)

#define GPIOG_IDR_Addr  (GPIOG_BASE + 12)

#endif

该文件定义了GPIO端口位带操作的宏。

二、数码管电路与使用配置

开发板上数码管相关电路如下图所示:

要使得数码管正常显示需要进过以下步骤:

1、使能GPIOC时钟

2、配置GPIOC_0-GPIOC_7为推挽输出,50MHz速度

3、通过库函数操作控制输出

4、实现过程

① 在上述配置的项目中添加"seg.h"和"seg.c"文件,保存在"User/Seg"文件夹下,"seg.h"文件的内容为:

#ifndef __SEG__H

#define __SEG__H

#include "system.h"

#include "stm32f10x_gpio.h"

#define SEGPORT GPIOC

#define SEG_RCCPORT RCC_APB2Periph_GPIOC

#define SEGPIN (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7)

void Seg_Init(void);

#endif

"seg.c"文件的内容为:

#include "seg.h"

#include "stm32f10x_rcc.h"

void Seg_Init()

{

GPIO_InitTypeDef GPIOC_mode;

RCC_APB2PeriphClockCmd(SEG_RCCPORT, ENABLE);

GPIOC_mode.GPIO_Pin = SEGPIN;

GPIOC_mode.GPIO_Speed = GPIO_Speed_50MHz;

GPIOC_mode.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(SEGPORT, &GPIOC_mode);

}

void Show()

{

static u8 n=0;

u16 seg[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

GPIO_Write(SEGPORT, seg[n]);

n++;

n = n%10;

}

② 将"seg.c"文件添加到项目的"User"组中;

③ 将"./User/Seg"路径添加到项目文件包含的配置路径中(在"C/C++"选项卡中的"Include Paths"中)。

三、定时器TIM1配置

1、选择定时器

使用定时器首先要选择定时器,stm32f103zet6MCU芯片有8个定时器,其中TIM1和TIM8称为高级定时器,TIM2-TIM5称为通用定时器,TIM6和TIM7称为基本定时器,这里选择TIM1作为通用定时器功能使用。

2、计算定时器配置参数

在本程序中,想要通过TIM1进行1秒的定时,实现每秒钟产生一次定时计数溢出中断,然后在中断函数中调用数码管显示输出。由于系统初始化时钟(调用SystemInit函数)后APB2总线上的时钟为72MHz,本程序中TIM1的时钟选择为CK_INT,为72MHz,这个频率进过预分频和计数后得到1秒的定时,需要设置预分频系数与定时计数值之积为72M,这里设置预分频系数为7200,计数器计数值为10000。

3、计数器配置编程

① 使能TIM1时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE );

② 配置TIM1参数

typedef struct

{

uint16_t TIM_Prescaler;         /*预分频系数. 取值0x0000-0xFFFF */

uint16_t TIM_CounterMode;       /*计数模式*/

uint16_t TIM_Period;            /*计数值 0x0000到 0xFFFF.  */

uint16_t TIM_ClockDivision;     /*!时钟分割,用于数字滤波器*/

uint8_t TIM_RepetitionCounter;  /*重复次数,仅对TIM1和TIM8有意义.

} TIM_TimeBaseInitTypeDef;

计数模式定义:

#define TIM_CounterMode_Up                 ((uint16_t)0x0000)

#define TIM_CounterMode_Down               ((uint16_t)0x0010)

#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)

#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)

#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)

时钟分割

#define TIM_CKD_DIV1                       ((uint16_t)0x0000)

#define TIM_CKD_DIV2                       ((uint16_t)0x0100)

#define TIM_CKD_DIV4                       ((uint16_t)0x0200)

程序如下:

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;      //定义配置结构体变量

TIM_TimeBaseStructure.TIM_Prescaler = (7200– 1);

TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = (10000 –1);

TIM_TimeBaseStructure.TIM_ClockDivision =0;

TIM_TimeBaseStructure.TIM_RepetitionCounter= 0;

TIM_TimeBaseInit( TIM1,&TIM_TimeBaseStructure);

③ 设置定时器中断类型,并使能。

TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

④ 开启计数器,开始计数

TIM_Cmd( TIM1, ENABLE);

4、实现步骤

① 在上述配置的项目中添加"tim.h"和"tim.c"文件,保存在"User/Tim"文件夹下,"tim.h"文件的内容为:

#ifndef __TIM__H

#define __TIM__H

#include "system.h"

#include "stm32f10x_rcc.h"

#include "stm32f10x_tim.h"

void Init_Tim(void);

#endif

"tim.c"文件内容为:

#include "tim.h"

void Tim_Init(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     //定义配置结构体变量

RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );//使能定时器TIM1时钟

TIM_TimeBaseStructure.TIM_Prescaler = (7200-1);

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = (10000-1);

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit( TIM1, &TIM_TimeBaseStructure);

TIM_ClearITPendingBit(TIM1,TIM_IT_Update);//清除TIM1溢出中断标志

TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//打开溢出中断

TIM_Cmd( TIM1, ENABLE);       //启动定时器

}

② 将"tim.c"文件添加到项目的"User"组中;

③ 将"./User/Tim"路径添加到项目文件包含的配置路径中(在"C/C++"选项卡中的"Include Paths"中)。

四、NVIC配置和中断函数

1、配置中断分组(NVIC)

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

2、使能中断

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel =TIM1_UP_IRQn;     //定时器1上溢中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;       //主优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;

NVIC_Init( & NVIC_InitStructure);

3、实现步骤

① 在上述配置的项目中添加"nvic.h"和"nvic.c"文件,保存在"User/Nvic"文件夹下,"nvic.h"文件的内容为:

#ifndef __NVIC__H

#define __NVIC__H

#include "stm32f10x.h"

#include "misc.h"

void My_NVIC_Init(void);

#endif

"nvic.c"文件内容为:

#include "nvic.h"

void My_NVIC_Init(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );

NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;     //定时器TIM1上溢中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init( & NVIC_InitStructure);

}

② 将"nvic.c"文件添加到项目的"User"组中;

③ 将"./User/Nvic"路径添加到项目文件包含的配置路径中(在"C/C++"选项卡中的"Include Paths"中)。

五、主函数和终端服务函数

在main.c中添加中断服务函数TIM1_UP_IRQHandler,修改主函数,内容如下:

#include "seg.h"

#include "tim.h"

#include "nvic.h"

int main()

{

Seg_Init();

My_NVIC_Init();

Tim_Init();

Show();

while(1)

[1] [2]

stm32c语言写数码管定时器,使用TIM1产生1秒定时控制数码管显示0-9(STM32_10)相关推荐

  1. 定时器驱动数码管c语言,第五章 定时器和数码管

    1.1基本数字逻辑门电路 不管是数字电路,还是C语言,我们都会经常遇到逻辑运算和逻辑电路,在这里我介绍一下,大家先简单了解一下,知道有这么回事,回头遇到了,再详细研究. 首先,在"逻辑&qu ...

  2. at89s51数码管秒表c语言程序,基于AT89C51单片机的一个2位的LED数码显示作为“秒表”设计【基于单片机系统的00-99s的定时器】...

    基于AT89C51单片机的一个2位的LED数码显示作为"秒表"设计[基于单片机系统的00-99s的定时器] 工程技术学院 课程设计 题 目:用单片机AT89C51设计一个2位的LE ...

  3. rw1601可以用C语言写程序吗,用8051+1601LCD设计的整型计算器讲解.doc

    浙江海洋学院 设计题目 用8051+1601LCD设计的整型计算器 摘 要 当今时代,是一个新技术层出不穷的年代.单片机具有体积小.质量轻.价格便宜.为学习.应用和开发提供了便利条件.单片机由运算器. ...

  4. 用C语言写PHP扩展

     用C语言写PHP扩展 1:预定义 在home目录,也可以其他任意目录,写一个文件,例如caleng_module.def 内容是你希望定义的函数名以及参数: int a(int x,int y) s ...

  5. 看看现在大型网站都是用什么语言写的 ?

    看看现在大型网站都是用什么语言写的 ? 不排除一个网站用多种技术!如淘宝是Java + php,底层是java,表现层是php.新浪,网易,腾讯应该也是用了多种技术. 据说是这样的:php,新浪,雅虎 ...

  6. 会写代码的AI开源了!C语言写得比Codex还要好,掌握12种编程语言丨CMU

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 萧箫 发自 凹非寺 量子位 | 公众号 QbitAI 比Codex还 ...

  7. 大学生只会用C语言写简单的计算怎么办?

    大学生会用C语言写几个简单的计算太正常了,有些人直到毕业了都写不出什么程序. 这个也是大多数应届生的一个现状. 在学校的时候不知道要好好学习,等马上会接受社会毒打时才发现自己一无是处,然后开始临时抱佛 ...

  8. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  9. C语言写一函数交换两变量的值

    C语言写一函数交换两变量的值 #include <stdio.h> void swap(int *p1, int *p2); // 形参,只声明 int main(){int a=5, b ...

最新文章

  1. FIFO and DMA
  2. linux中here文档,Linux下Bash Heredoc(Here document)的用法及基本示例
  3. matlab怎么调整子图间距,matplotlib调整子图间距,调整整体空白的方法
  4. 浅谈 Scala 中下划线的用途
  5. php编译支持mysql,编译php支持curl和pdo_mysql
  6. cJSON各函数实现的功能
  7. Ogre 3d 工具集
  8. 戴尔计算机没有硬盘驱动,在Dell计算机上重新安装系统后,如果找不到硬盘驱动器或引导设备该怎么办?...
  9. 如何安装浏览器插件,一篇文章全搞定
  10. 计算机培训课堂感言,信息技术培训学习感言.docx
  11. Solidworks速成——仿人机械手设计
  12. 水杯测试用例(500ml的塑料水杯)
  13. 分布式与微服务——Iaas,Paas和Saas、单体应用和缺点、微服务概念、传统 分布式 SOA 架构与微服务架构的区别、微服务实战、什么是RPC、CAP定理和BASE理论、唯一ID生成、实现分布式
  14. Java:外包Java项目有什么好处?
  15. linux 查看mysql
  16. DDPG-终态done对结果的影响探究
  17. php写动物的属性,状物的记叙文类型——描述动物
  18. 网易云音乐真实链接地址
  19. xlwt 合并单元格内 富文本 同一单元格内多个样式
  20. 在腾讯实习的五个月的一些思考与收获

热门文章

  1. 測试新浪微博@小冰 为代码机器人的一些方法
  2. InstallShield 杀掉进程
  3. 制作安装媒体来部署额外域控制器
  4. Linux常用备份恢复工具
  5. 数字带通滤波器c语言程序,C语言编写FIR数字低通滤波器
  6. servlet获取不到Angular4 post过来的参数
  7. Linux磁盘分区及要求
  8. th:text为null报错_为vue3.0的学习TS解读高级类型
  9. sqllite java 密码,SQLite登录检查用户名和密码
  10. 什么是html的混杂模式_HTML的完整形式是什么?