电子时代,硬件在突飞猛进的发展,频率不断上升,目前的STM32系列,Cortex M系列,Cortex-M4的频率已经为:180MHz了,基本上与之前的ARM7/9频率差不多了,还有Cortex-M7,频率更高,出现了BGA封装与SDRAM DDR等。看来处理器越来越大众化了,物联网上的电子设备联网,也越来越普及了,硬件成本不断降低是大势所趋,因此,作为一个电子设计人员,还是要不断的学习掌握更多的技术知识与基础,从而不会被社会很快淘汰。
最近买了一个现成的STM32F429 Discovery 的开发板,想尝试一下较大点的嵌入式操作系统如RTEMS的移植与应用。因为有了STM32F103/107的基础,熟悉了硬件与固件库,STM32F429其实很容易入手。下面就先定时器中断点个LED试下吧,主要是要组织好工程目录。
我是根据之前一直使用STM32F103的工程目录改了一下,使用STM32F4XX的最新固件库V1.6.1,至于为何不去直接操作寄存器,我想,虽然自己是硬件出身,搞寄存器更深入的了解处理器,但是,毕竟寄存器过多,有了库,可以封装一下,这样更可以快速的上手。如果需要查看寄存器,也是可以查的。用固件库可以少一些错误,毕竟我们是做应用的,首先要学会使用CPU来实现我们要的功能。
工程目录如下:这里使用最新的Keil MDK V5.17版本的,STM32F4XX的器件库等还需要进一步下载。这里使用的是自带的ST-Link下载程序,当然使用Jlink也是可以的。
STM32F429的系统定时器,原来是系统时钟180MHz的8分频,这个可以看一下STM32F4XX的参考手册,里面时钟RCC部分的框架介绍。我这里为了定时为1S,因此计算了一下。
以下为Tim2.c的主程序。Tim2.h 只是函数声明。
-
-
-
-
-
-
-
-
-
-
-
#include "Tim2.h"
-
-
-
-
-
-
-
-
void TIM2_NVIC_Configuration(void)
-
{
-
NVIC_InitTypeDef NVIC_InitStructure;
-
-
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
-
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
-
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-
NVIC_Init(&NVIC_InitStructure);
-
}
-
-
-
-
-
void TIM2_Configuration(void)
-
{
-
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
-
TIM_DeInit(TIM2);
-
TIM_TimeBaseStructure.TIM_Period=1000;
-
-
TIM_TimeBaseStructure.TIM_Prescaler= (22500 - 1);
-
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
-
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
-
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
-
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
-
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
-
TIM_Cmd(TIM2, ENABLE);
-
-
}
-
-
-
-
-
-
-
-
void TIM2_Config(void)
-
{
-
TIM2_Configuration();
-
TIM2_NVIC_Configuration();
-
}
-
-
-
以下为:led.c的文件。
-
-
-
-
-
-
-
-
-
-
-
-
-
#include "led.h"
-
-
-
-
-
-
-
-
void LED_GPIO_Config(void)
-
{
-
-
GPIO_InitTypeDef GPIO_InitStructure;
-
-
-
RCC_AHB1PeriphClockCmd( RCC_LED1, ENABLE);
-
-
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_LED1;
-
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
-
-
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
-
-
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-
-
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;
-
-
GPIO_Init(GPIO_LED1_PORT, &GPIO_InitStructure);
-
-
-
RCC_AHB1PeriphClockCmd( RCC_LED2, ENABLE);
-
-
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_LED2;
-
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
-
-
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
-
-
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-
-
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;
-
-
GPIO_Init(GPIO_LED2_PORT, &GPIO_InitStructure);
-
-
-
-
-
}
-
-
-
-
-
以下为LED的引脚定义:led.h
-
-
-
-
-
-
-
-
-
-
-
-
-
#ifndef __LED_H
-
#define __LED_H
-
-
#include "stm32f4xx.h"
-
-
-
-
-
-
#define ON 1
-
#define OFF 0
-
-
#define RCC_LED1 RCC_AHB1Periph_GPIOG
-
#define GPIO_LED1_PORT GPIOG
-
#define GPIO_Pin_LED1 GPIO_Pin_13
-
-
#define RCC_LED2 RCC_AHB1Periph_GPIOG
-
#define GPIO_LED2_PORT GPIOG
-
#define GPIO_Pin_LED2 GPIO_Pin_14
-
-
-
#define LED1(a) if (a) \
-
GPIO_SetBits(GPIO_LED1_PORT,GPIO_Pin_LED1);\
-
else \
-
GPIO_ResetBits(GPIO_LED1_PORT,GPIO_Pin_LED1)
-
-
#define LED2(a) if (a) \
-
GPIO_SetBits(GPIO_LED2_PORT,GPIO_Pin_LED2);\
-
else \
-
GPIO_ResetBits(GPIO_LED2_PORT,GPIO_Pin_LED2)
-
-
-
void LED_GPIO_Config(void);
-
-
#endif /* __LED_H */
主程序:硬件的初始化。
-
-
-
-
-
-
-
-
-
-
-
#include "stm32f4xx.h"
-
-
#include "led.h"
-
#include "Tim2.h"
-
-
void Delay(__IO uint32_t nTime)
-
{
-
-
while(--nTime != 0);
-
}
-
-
-
-
-
-
-
-
-
int main(void)
-
{
-
LED_GPIO_Config();
-
TIM2_Config();
-
LED1(ON);
-
LED2(ON);
-
while(1)
-
{
-
#if 0
-
Delay(0x2FFFFF);
-
LED1(OFF);
-
LED2(OFF);
-
Delay(0x2FFFFF);
-
LED1(ON);
-
LED2(ON);
-
#endif
-
}
-
}
-
以下为真正的实现函数:定时器2中断函数 stm32f4xx_it.c
-
-
-
-
-
-
void TIM2_IRQHandler(void)
-
{
-
if (TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
-
{
-
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
-
TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
-
GPIO_WriteBit(GPIO_LED1_PORT,GPIO_Pin_LED1,
-
(BitAction)(1-GPIO_ReadOutputDataBit(GPIO_LED1_PORT,GPIO_Pin_LED1)));
-
}
-
}
编译并烧写,基本上可以看到LED 1S的亮,1S的灭,然后不断的循环下去,一般用于程序的运行指示灯。
重要的总结:
(1)GPIO的时钟,STM32F103的是APB时钟,STM32F429为:RCC_AHB1PeriphClockCmd,我开始弄错了,程序不运行!!
(2)STM32F429虽然180MHz的主频,但是系统定时器的时钟为其的8分频,STM32F103是直接使用的72MHz的主频,因此在计算分频与周期数时,要使用180MHz/8 的定时器基本时钟去计算。
Keil MDK 5.17的工程下载:
阅读(6301) | 评论(0) | 转发(0) |