1.
先从网上下载3.5版(据说3.0版以后的固件库才逐渐稳定)stm32固件库(stm32f10x_stdperiph_lib)。由于与固件库版本兼容问题,重新下载安装了IAR6.30版。
1.1 创建项目文件夹“project”;
1.2
1.3
1.4
1.5
其中:
l
l
l
startup_stm32f10x_cl.s
startup_stm32f10x_hd.s
startup_stm32f10x_hd_vl.s
startup_stm32f10x_ld.s
startup_stm32f10x_ld_vl.s
startup_stm32f10x_md.s
startup_stm32f10x_md_vl.s
startup_stm32f10x_xl.s
其中大、中、小容量的区分如下图所示:
各型号名称辨识如下图所示:
个人所使用的芯片型号是STM32F103VBT6,所以是属于中等容量,所以选择的是”startup_stm32f10x_md.s”文件。
l
l
项目设置
C/C++Compiler>Preprocessor项:
至此,工程设置完毕,可以往main文件里写空代码试着编译,如:
- #include “stm32f10x.h”
- Int main()
- {While(1);}
[page]
编译无误后即可开始写自己的代码。
附注:关于CMSIS的core_cm3文件,在编译的时候经常会报错,一般是无法找到”core_cm3.h”文件,但实际上该文件与”core_cm3.c”同处于同一个目录,具体原因未明。解决方法如下:
l
A special note on CMSISintegration:
If your application source code include CMSISheader files explicitly, then you should not check theUse CMSIS check-box Project>Options...>GeneralOptions>Library Configuration>UseCMSIS. Some of the Cortex-M application examplesincludes CMSIS source files explicitly, do not check the saidcheck-box in these projects.
However, due to the evolution of the IAR C/C++ Compiler for ARM,older versions of CMSIS are incompatible with the current versionof the compiler. One simple example of how to solve this issueis:
a) Press F4 to bring up the erroneous source (header) file in theeditor - in most cases named core_cm3.h.
b) Right-click on the window tab of that editor window,choose File Properties....
c) Add (or remove) any character to the file name - so the compilerwon't find it any more.
d) Modify project options: Check Project>Options...>GeneralOptions>Library Configuration>UseCMSIS.
Steps a) to c) might need to be done for more than one file.Normally, the names of these files are core_cm0.h, core_cm3.h,core_cm4.h, core_cmFunc.h and core_cmInstr.h.
即将”core_cm3.h”改名或删除,然后勾选工程设置中的”Use CMSIS”选项即可。
l
2. 使用函数库编程
2.1 与本例程有关的几个函数:
函数名 |
RCC_APB2PeriphClockCmd |
函数原型 |
Void RCC_APB2PeriphClockCmd(u32RCC_APB2Periph,FunctionalState |
行为描述 |
使能或关闭高速APB(APB2)外围设备时钟 |
输入参数1 |
RCC_APB2Periph:用于门控时钟的AHB2外围设备 涉及章节:RCC_AHB2Periph结构详细说明了这个参数允许的值。 |
输入参数2 |
NewState:专用外围设备时钟的新状态。 这个参数可以是:ENABLE或DISABLE。 |
输出参数 |
无 |
返回参数 |
无 |
调用前提条件 |
无 |
调用函数 |
无 |
RCC_APB2Periph值:
RCC_APB2Periph |
描述 |
RCC_APB2Periph_AFIO |
交替功能I/O时钟 |
RCC_APB2Periph_GPIOA |
IO端口A时钟 |
RCC_APB2Periph_GPIOB |
IO端口B时钟 |
RCC_APB2Periph_GPIOC |
IO端口C时钟 |
RCC_APB2Periph_GPIOD |
IO端口D时钟 |
RCC_APB2Periph_GPIOE |
IO端口E时钟 |
RCC_APB2Periph_ADC1 |
ADC1接口时钟 |
RCC_APB2Periph_ADC2 |
ADC2接口时钟 |
RCC_APB2Periph_TIM1 |
TIM1时钟 |
RCC_APB2Periph_SPI1 |
SPI1时钟 |
RCC_APB2Periph_USART1 |
USART1时钟 |
RCC_APB2Periph_ALL |
所有APB2外围设备时钟 |
例子:
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_SPI1,ENABLE);
2.1.2 标签定义
- #define _GPIO
- #define _GPIOA
- #define _GPIOB
- #define _GPIOC
- #define _GPIOD
- #define _GPIOE
- #define _AFIO
关于此标签定义,还存在疑问,因为即便是没有进行如此定义,编译依旧通过,寄存器依旧可用。
2.1.3声明PPP_InitTypeDef结构
在初始化和配置外围模块时,必须在主应用程序文件中,声明一个PPP_InitTypeDef结构(PPP是外围模块),例如:
- PPP_InitTypeDef PPP_InitStructure;
PPP_InitStructure是一个位于数据存储区的有效变量。
2.1.4 GPIO_Init函数
函数名 |
GPIO_Init |
函数原型 |
void GPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef* GPIO_InitStruct) |
功能描述 |
按照GPIO_InitStruct的特定参数初始化GPIO部件 |
输入参数1 |
GPIOx:x可为A到E来选择特定的GPIO部件 |
输入参数2 |
GPIO_InitStruct:指向GPIO_InitTypeDef结构的指针,它包含特定GPIO部件的配置信息。参考GPIO_InitTypeDef结构 |
输出参数 |
无 |
返回参数 |
无 |
前提条件 |
无 |
调用函数 |
无 |
GPIO_InitTypeDef结构
GPIO_InitTypeDef在stm32f10x_gpio.h中如下定义:
- typedef struct
- {
- u16 GPIO_Pin;
- GPIO_Speed_TypeDef GPIO_Speed;
- GPIO_Mode_TypeDef GPIO_Mode;
- } GPIO_InitTypeDef
GPIO_Pin值
可用”|”完成多引脚的配置。
GPIO_Pin |
描述 |
GPIO_Pin_None |
没有引脚被选择 |
GPIO_Pin_x |
引脚x被选择(x=0…15) |
GPIO_Pin_All |
所有引脚都被选择 |
GPIO_Speed值
GPIO_Speed |
描述 |
GPIO_Speed_10MHz |
最大输出频率=10MHz |
GPIO_Speed_2MHz |
最大输出频率=2MHz |
GPIO_Speed_50MHz |
最大输出频率=50MHz |
GPIO_Mode值
GOIO_Mode是用来配置选定引脚的操作模式的。
GPIO_Mode |
描述 |
GPIO_Mode_AIN |
模拟输入 |
GPIO_Mode_IN_FLOATING |
浮点输入 |
GPIO_Mode_IPD |
下拉输入 |
GPIO_Mode_IPU |
上拉输入 |
GPIO_Mode_Out_OD |
开漏输出 |
GPIO_Mode_Out_PP |
推拉输出 |
GPIO_Mode_AF_OD |
开漏输出备用功能 |
GPIO_Mode_AF_PP |
推拉输出备用功能 |
实例:
- GPIO_InitTypeDefGPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
2.1.5 GPIO_SetBits函数
函数名 |
GPIO_SetBits |
函数原型 |
voidGPIO_SetBits(GPIO_TypeDef* GPIOx,u16 GPIO_Pin |
功能描述 |
置位选定的端口位 |
输入参数1 |
GPIOx:x=A…E |
输入参数2 |
GPIO_Pin:GPIO_Pin_x的任意组合,x=0…15。 |
输出参数 |
无 |
返回参数 |
无 |
前提条件 |
无 |
调用函数 |
无 |
实例:
- GPIO_SetBits(GPIOA,GPIO_Pin_10|GPIO_Pin_15);
2.1.6 GPIO_ResetBits函数
函数名 |
GPIO_ResetBits |
函数原型 |
void ResetBits(GPIO_TypeDef* GPIOx,u16 GPIO_Pin) |
功能描述 |
清除选定的数据端口位 |
输入参数1 |
GPIOx:x=A…E |
输入参数2 |
GPIO_Pin:GPIO_Pin_x(x=0…15)的任意组合 |
输出参数 |
无 |
返回参数 |
无 |
前提条件 |
无 |
调用函数 |
无 |
实例:
- GPIO_ResetBits(GPIOA,GPIO_Pin_10|GPIO_Pin_15);
[page]
2.1.7 GPIO_Write 函数
函数名 |
GPIO_Write |
函数原型 |
voidGPIO_Write(GPIO_TypeDef* GPIOx,u16 PortVal) |
功能描述 |
写数据到指定的GPIO端口数据寄存器 |
输入参数1 |
GPIOx:x=A…E |
输入参数2 |
PortVal:写入到数据端口寄存器的值 |
输出参数 |
无 |
返回参数 |
无 |
前提条件 |
无 |
调用函数 |
无 |
实例:
- GPIO_Write(GPIOA,0x1101);
2.2 完整程序:
- #include "stm32f10x.h"
- void delay(void);
- void GPIO_Configuration(void);
- int main(void)
- {
- //使能GPIOC时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
- //此条语句一定要在时钟使能后,否则无效(费了好多时间才找到原因)
- GPIO_Configuration();
- while(1)
- {
- //利用GPIO_SetBits函数与GPIO_ResetBits函数点亮与熄灭led
- GPIO_ResetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_9);
- GPIO_SetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_8);
- delay();
- GPIO_ResetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_8);
- GPIO_SetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_9);
- delay();
- //利用GPIO_Write函数点亮与熄灭led
- GPIO_Write(GPIOC,0x0140);
- delay();
- GPIO_Write(GPIOC,0x0280);
- delay();
- }
- }
- //GPIO口设置
- void GPIO_Configuration(void)
- {
- //声明结构体
- GPIO_InitTypeDefGPIO_InitStructure;
- //设置选择引脚
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
- //设置引脚最大输出频率
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- //设置引脚输出模式
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
- 根据设置的InitStructure 初始化GPIO口
- GPIO_Init(GPIOC,&GPIO_InitStructure);
- }
- void delay(void)
- {
- unsigned longj,n=100000;
- while(n--)
- {
- j=12;
- while(j--);
- }
- }
编译通过烧写到开发板上后,最终结果是:led1和led3与led2和led4两两交替亮灭。
参考文献
[1]jhliuzj.IAR FOR ARM6.20工程创建建议(固件库为3.5)[EB/OL].
http://hi.baidu.com/jhliuzj/item/459830ae7e19e136020a4d3f
[2]kiropower.IARSTM32项目工程创建[EB/OL].http://hi.baidu.com/kiropower/item/e20faad0007502352b35c785
[3]gasbi.startup_stm32f10x_xx.s 启动代码文件选择[EB/OL].
http://blog.csdn.net/gasbi/article/details/7545568,2012-05-08/2012-08-25.
[4]IAR Systems AB.Releasenotes for the IAR C/C++ Compiler for ARM 6.20.1[EB/OL].http://supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/infocenter/iccarm.ENU.html,2012-08-25
[5]Changing.用stm32点个灯[操作寄存器+库函数][EB/OL].
http://www.ichanging.org/stm32_gpio_led.html,
- #ifdef USE_STDPERIPH_DRIVER
- #include "stm32f10x_conf.h"
- #endif
上一篇:STM32的功能引脚重映射和复用功能
下一篇:STM32学习笔记——利用通用定时器TIM2进行精确延时
推荐阅读最新更新时间:2024-03-16 14:28