stm32初学例程.docx

上传人:b****7 文档编号:25524076 上传时间:2023-06-09 格式:DOCX 页数:16 大小:222.72KB
下载 相关 举报
stm32初学例程.docx_第1页
第1页 / 共16页
stm32初学例程.docx_第2页
第2页 / 共16页
stm32初学例程.docx_第3页
第3页 / 共16页
stm32初学例程.docx_第4页
第4页 / 共16页
stm32初学例程.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

stm32初学例程.docx

《stm32初学例程.docx》由会员分享,可在线阅读,更多相关《stm32初学例程.docx(16页珍藏版)》请在冰豆网上搜索。

stm32初学例程.docx

stm32初学例程

<2011-1-6>

Ifanerror,pleasecontactauthor,tobecorrected.

Forotheruses,indicatethesource,toexpressmyrecognitionoftheresults.

Thankyou.

Introduction

由于公司需要,以及充满对arm的向往,开始学习STM32.。

与8位单片机不同,32位处理器的开发变得更加复杂,同时也伴随着性能和功能的显著提高。

由于初学STM32,遇到了很多莫名其妙的问题,但是总归是在自己的摸索中一个个的解决了。

说来惭愧,三个星期天天忙STM32,总算实现了几个常用的功能,心中窃喜——arm也不过如此嘛!

当然,STM32许多过人之处还没有细细研究,巧妙设计之处还没有完全的感受到,暂且就当是小小的步入STM32开发初期阶段吧。

为了纪念STM32学习过程的辛劳和无助,记下我的学习过程,与大家共勉。

也希望能为广大的初学者提供小小的帮助。

如有任何问题和建议,您可以联系。

此文章所采用的开发环境如下

A、开发板、仿真器:

使用的是STM32F103C8-PKT+ST-LINK;

B、开发环境:

IAREmbeddedWorkbenchforARM6.10Kickstart;

C、Firmware:

STM32F10x_StdPeriph_Lib_V

首先安装IAREmbeddedWorkbenchforARM,32KKickstartEdition;

下载STM32F10x_StdPeriph_Lib_V;

购买一块开发板,通过ST-Link进行仿真和调试;

(所有的资源都可以到IAR和ST官网上下载,资源的获取也是很重要的,要是自己不培养找资源的功夫,就不是一个好的开发人员,这里就不留网址了)

关于编译环境和仿真方法可以参考我的另一篇记录环境搭建的文章——《EWARM_STM32_Use_Instructions》。

在成功搭建开发环境之后,我们就可以对STM32进行深入的学习了,STM32功能繁多,不可以一下子学习所有的知识,因此采用各个击破,由简转难的学习方法,一步步的学会STM32的功能。

总之,我们需要调通每一个经常使用到的功能。

而本篇文章就是记录了调通某些功能的历程,以及在调试过程中可能会出现的问题。

由于自身能力的限制,对有些知识点可能理解的不是很透彻,因此错误难免,希望谅解并给出指导建议。

您可以通过联系我,谢谢。

在使用固件库时,需要自己有点C语言的相关基础,如结构体、枚举、指针等;

1GPIOTest(端口操作实验)

GPIO实验是最简单,也是一般最先开始的一个实验,他可以搭建一个最小的工程项目,之后,所有的实验都可以建立在该项目之上,从而节省了在搭建过程中所消耗的时间和精力。

建议,当该实验顺利完成后,作为一个模板,供以后实验使用,确保您可以将精力花费在需要实现的功能上。

关于环境的搭建,您可以参考《EWARM_STM32_Use_Instructions》;

本实验需要实现:

四个LED的简单控制。

1.1硬件设计:

1.确认硬件连接:

根据开发板原理图,如图,得知:

与LED相连的有PB12、PB13、PB14、PB15;

以下就是对这四个引脚的配置,及相关操作;

1.2软件设计:

//main()程序开始……

1.2.1头文件:

#include"stm32f10x.h"

#include"main.h"

//#include"k_gpio.h"//已经转移到main函数中;

#defineVECT_TAB_RAM//选择在RAM中调试;

//main()函数:

1.2.2系统初始化

SystemInit();//选择系统运行时钟,默认是72MHz,可以调试跟踪进行修改;

#ifdefVECT_TAB_RAM//设置仿真调试区域,这里设置成在RAM中;

//SettheVectorTablebaselocationat0x20000000

NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);

#else/*VECT_TAB_FLASH*/

//SettheVectorTablebaselocationat0x08000000

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);

#endif

1.2.3GPIO配置

//首先,选择GPIOB外设时钟;只有选择好时钟后,才可以进行下面的配置;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

//配置端口,开始时,不需要知道所有的细节,从字面上理解就ok;

gpio.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;

gpio.GPIO_Speed=GPIO_Speed_50MHz;

gpio.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_Init(GPIOB,&gpio);

GPIO_SetBits(GPIOB,GPIO_Pin_12);//将端口拉高,灭LED灯;

GPIO_SetBits(GPIOB,GPIO_Pin_13);

GPIO_SetBits(GPIOB,GPIO_Pin_14);

GPIO_SetBits(GPIOB,GPIO_Pin_15);

如此,GPIOB连接LED的四个端口都配置好了;

1.2.4GPIO操作

While

(1)

{

GPIO_ResetBits(GPIOB,GPIO_Pin_12);

Delay(0xffffff);

GPIO_ResetBits(GPIOB,GPIO_Pin_13);

Delay(0xffffff);

GPIO_ResetBits(GPIOB,GPIO_Pin_14);

Delay(0xffffff);

GPIO_ResetBits(GPIOB,GPIO_Pin_15);

Delay(0xffffff);

Delay(0xffffff);

Delay(0xffffff);

GPIO_SetBits(GPIOB,GPIO_Pin_12);

Delay(0xffffff);

GPIO_SetBits(GPIOB,GPIO_Pin_13);

Delay(0xffffff);

GPIO_SetBits(GPIOB,GPIO_Pin_14);

Delay(0xffffff);

GPIO_SetBits(GPIOB,GPIO_Pin_15);

Delay(0xffffff);

GPIO_ResetBits(GPIOB,GPIO_Pin_12);

GPIO_ResetBits(GPIOB,GPIO_Pin_13);

GPIO_ResetBits(GPIOB,GPIO_Pin_14);

GPIO_ResetBits(GPIOB,GPIO_Pin_15);

}

如此而已;这是最简单的实验,可以为此建立一个拥有自己特色的工程模板;

1.3Test注意

A、硬件必须首先确保正确;

B、开发环境搭建确保正确;

C、系统时钟的选择要清楚;仿真所处的区域要清楚;

D、外设时钟的配置是第一位的,其他配置都在其后;

2Time2Test(Time2定时实验)

Timer作为控制器和处理器的一个重要的组成部分,是几乎所有系统都需要的一个模块,可以提高程序的实时性、精确性,以及安全性,是最为重要的一个学习方面;

STM32有着丰富的Time系统,很容易使初次接触的人产生恐惧,不过,归咎起来,他的作用也只是定时和计数,只不过衍生的功能比较强大,有PWM,比较捕获,强制输出等,其实不需要所有的功能都掌握,您只需要用到什么功能再去学习某个功能即可;

本实验需要实现:

使用Time2进行定时的功能,使得LED灯进行相应时间的闪烁。

2.1硬件设计

在Time2上,主要是芯片内部实现,所以Time2无需关注硬件;

操作的LED,我们需要实现与PB12引脚相连的LED的亮灭;

2.2软件设计

#include"stm32f10x.h"

#include"main.h"

//#include"k_gpio.h"//已经转移到main函数中;

//#include"k_time2.h"//本实验增加部分,但已经转移到main函数中;

#defineVECT_TAB_RAM

voidmain()

{

GPIO_InitTypeDefgpio;

TIM_TimeBaseInitTypeDeftime2;//本实验增加部分

NVIC_InitTypeDefnvic;//本实验增加部分

SystemInit();

#ifdefVECT_TAB_RAM

//SettheVectorTablebaselocationat0x20000000

NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);

#else/*VECT_TAB_FLASH*/

//SettheVectorTablebaselocationat0x08000000

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);

#endif

//GPIOB端口配置

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

gpio.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;

gpio.GPIO_Speed=GPIO_Speed_50MHz;

gpio.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_Init(GPIOB,&gpio);

GPIO_SetBits(GPIOB,GPIO_Pin_12);

GPIO_SetBits(GPIOB,GPIO_Pin_13);

GPIO_SetBits(GPIOB,GPIO_Pin_14);

GPIO_SetBits(GPIOB,GPIO_Pin_15);

//以上已经有过详细的论述,可以参考先前的Test;

//以下是本实验增加的部分;

//Time2配置

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB2Periph_AFIO,ENABLE);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设置Time2中断向量相关;

nvic.NVIC_IRQChannel=TIM2_IRQn;

//nvic.NVIC_IRQChannelPreemptionPriority=0;

nvic.NVIC_IRQChannelSubPriority=1;

nvic.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&nvic);

TIM_DeInit(TIM2);//设置Time2相关;

time2.TIM_Prescaler=0;

time2.TIM_CounterMode=TIM_CounterMode_Up;

time2.TIM_Period=1000;

time2.TIM_ClockDivision=TIM_CKD_DIV1;

//TIM_TimeBaseStructure.TIM_RepetitionCounter

TIM_TimeBaseInit(TIM2,&time2);

TIM_PrescalerConfig(TIM2,0x8c9F,TIM_PSCReloadMode_Immediate);

TIM_ARRPreloadConfig(TIM2,DISABLE);

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

TIM_Cmd(TIM2,ENABLE);//启动Time2;

while

(1)

{

}

}

关于系统外设时钟的选择,可以参见相关手册,这是一个比较复杂的关系,这里给个简单的图:

(由红色框图中得知,Time2采用的是APB1之后的时钟系统)

由于本实验,涉及到中断,而且对于端口的操作,是在中断中进行的;

其中中断函数名称的由来,在startup_stm32f10x_hd.s(或其它)文件中,如图:

中断程序如下:

//-----------------------------------------

u8ledflag=0;

voidTIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)!

=RESET)

{

TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);

if(ledflag++%2)

{

GPIO_SetBits(GPIOB,GPIO_Pin_12);

}

else

{

GPIO_ResetBits(GPIOB,GPIO_Pin_12);

}

}

}

我想这么简单的中断程序应该没问题吧。

2.3Test注意

A、学会使用以前用过的模板,节省环境搭建时间;

B、学会查看数据手册,理解外设系统时钟的选择原因;

C、学会中断程序的编写,中断向量、函数的获取;

3USARTTest(串口收发实验)

只要是Project,只要是嵌入式开发,我想都免不了使用通讯,来和外界联系;只要使用通讯,最先想到的就是USART。

这是一个很是常用的和非常好用的通讯方式。

所有的处理器、控制器上,基本上都无一例外的增加USART功能。

初学者在经历了环境搭建、GPIO、Time定时之后,就需要接触USART相关了。

本实验需要实现:

USART的中断接收和发送,实现将收到的数据回发出去。

3.1硬件设计

查看开发板原理图,确定好通道连接情况:

引脚是否对,跳线是否短接。

图中显示:

使用PA9(TX)和PA10(RX)和STM32连接。

3.2软件设计

由上述两个实验,我们可以总结出:

1、外设时钟选择时钟是第一位的;

2、只要使用到端口,就需要初始化端口;

3、使用到其他外设,需要一一配置外设时钟;

4、使用中断的,需要配置好中断向量,以及编写中断函数;

本实验开始:

#include"stm32f10x.h"

#include"main.h"

//#incude"k_usart.h"//已经转移到main函数中;

#defineVECT_TAB_RAM

voidmain(void)

{

GPIO_InitTypeDefGPIO_InitStructure;

USART_InitTypeDefUSART_InitStructure;

NVIC_InitTypeDefnvic;

//USART_ClockInitTypeDefUSART_InitClockStructure;

SystemInit();

#ifdefVECT_TAB_RAM

//SettheVectorTablebaselocationat0x20000000

NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);

#else/*VECT_TAB_FLASH*/

//SettheVectorTablebaselocationat0x08000000

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);

#endif

//以下是USART的配置部分

//-------------------------------------------------------

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);

//-----------------------------------------------

//GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//-----------------------------------------------------------

nvic.NVIC_IRQChannel=USART1_IRQn;

nvic.NVIC_IRQChannelPreemptionPriority=3;

nvic.NVIC_IRQChannelSubPriority=2;

nvic.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&nvic);

//------------------------------------------------------------

//USART_StructInit(&USART_InitStructure);

USART_InitStructure.USART_BaudRate=115200;

USART_InitStructure.USART_WordLength=USART_WordLength_8b;

USART_InitStructure.USART_StopBits=USART_StopBits_1;

USART_InitStructure.USART_Parity=USART_Parity_No;

USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;

USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_Init(USART1,&USART_InitStructure);

/*

USART_InitClockStructure.USART_CPOL=USART_CPOL_Low;

USART_InitClockStructure.USART_CPHA=USART_CPHA_2Edge;

USART_InitClockStructure.USART_LastBit=USART_LastBit_Disable;

USART_InitClockStructure.USART_Clock=USART_Clock_Disable;

USART_ClockInit(USART1,&USART_InitClockStructure);

*/

USART_Cmd(USART1,ENABLE);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//先使能接收中断;

USART_ITConfig(USART1,USART_IT_TXE,DISABLE);//先禁止发送中断;

while

(1)

{

//接下来就交给中断处理;

}

}

USART1_IRQn中断函数在stm32f10x_it.c中:

//include"stdio.h"

uint32_tRxBuffer;

voidUSART1_IRQHandler(void)

{

if(USART_GetITStatus(USART1,USART_IT_RXNE)!

=RESET)

{

RxBuffer=USART_ReceiveData(USART1);

USART_ITConfig(USART1,USART_IT_TXE,ENABLE);

USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);

//printf("R");

}

if(USART_GetITStatus(USART1,USART_IT_TXE)!

=RESET)

{

USART_SendData(USART1,RxBuffer);

USART_ITConfig(USART1,USART_IT_TXE,DISABLE);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

//printf("S");

}

}

详细细节在这里不做论述,可以从命名中得知一般配置usart的步骤;可以F12去探究其缘由,以及涉及的相关寄存器;

3.3Test注意

1、在中断中,需要注意USART的中断条件,当发送中断ENABLE时,只要没有数据处理,就会进入中断,因此需要发送时才打开,不需要时,一定要关闭;

2、还是那句话,先配置外设时钟;

3、关于STM32中断相关配置,可以参考数据手册理解NVIC;

4USARTDMATest(串口DMA收发实验)

5Time3PWMTest(Time3PWM输出实验)

6I2CTest(I2C读写实验)

7ADCText(AD转换实验)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1