stm32f107 新手入门笔记

合集下载

STM32学习笔记小结

STM32学习笔记小结

STM32学习笔记目录STM32学习笔记 (1)一、入门 (2)目标->实战项目 (2)STM32学习方法 (3)ARM简介 (4)二、外设功能模块 (5)GPIO原理与工作模式 (5)串行通信 (6)硬件下载与调试 (6)Cortex-M3复用功能(AF)和重映射功能 (6)Systick的使用 (7)通用定时器 (7)SPI与数码管 (7)I2C通信 (8)NVIC中断 (8)PWM基础 (9)RCC内部结构与原理 (9)ADC模数转换 (10)内部温度传感器 (10)窗口看门狗 (10)USB应用 (11)三、问题 (11)在线调试 (12)一、入门STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M内核,主要包括STM32F101“基本型”系列、STM32F103“增强型”系列、STM32F105、STM32F107“互联型”系列。

STM32微控制器满足嵌入式开发低功耗和高性能的要求,并且拥有简单易上手的固件函数库,避免了传统ARM单片机开发操作寄存器的模式,所以十分受欢迎,应用广泛。

作者只学过一些51单片机的基础,就直接上手STM32,边学边用。

该篇笔记也是随意的记录一下,要想系统的学习一下,个人认为资料手册(data sheet)、参考手册(Reference Manual)和用户手册(固件函数库)三个文档再有开发板实际操作,完全足够。

熟练掌握以上内容,触类旁通,成为STM32开发的高手指日可待。

目标->实战项目STM32学习方法开发环境(MDK/IAR)→寄存器or固件库→软件仿真&开发板硬件→学习难度建立不受库版本限制的工程项目:1.准备好文件(Startup Code、Lib、User)2.建立工程不添加Startup Code3.工程管理添加需要的库文件、自定义文件4.编译链接ARM简介ARM7衍生出全新的Cortex架构,三管齐下:Cortex-A:高性能应用处理器。

STM32学习笔记

STM32学习笔记

STM32学习笔记1、GPIO函数:输出:HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);//此例以PA12⼝为例HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); //此例以PA12⼝为例HAL_GPIO_ TogglePin(GPIOA,GPIO_PIN_12); //此例以PA12⼝为例2、串⼝函数:1、串⼝发送/接收函数HAL_UART_Transmit();串⼝轮询模式发送,使⽤超时管理机制HAL_UART_Receive();串⼝轮询模式接收,使⽤超时管理机制HAL_UART_Transmit_IT();串⼝中断模式发送HAL_UART_Receive_IT();串⼝中断模式接收HAL_UART_Transmit_DMA();串⼝DMA模式发送HAL_UART_Transmit_DMA();串⼝DMA模式接收2、串⼝中断函数HAL_UART_TxHalfCpltCallback();⼀半数据发送完成时调⽤HAL_UART_TxCpltCallback();数据完全发送完成后调⽤HAL_UART_RxHalfCpltCallback();⼀半数据接收完成时调⽤HAL_UART_RxCpltCallback();数据完全接受完成后调⽤HAL_UART_ErrorCallback();传输出现错误时调⽤例程:串⼝接收中断uint8_t aTxStartMessages[] = "\r\n******UART commucition using IT******\r\nPlease enter 10 characters:\r\n";uint8_t aRxBuffer[20];2、在main函数中添加两个语句通过串⼝中断发送aTxStartMessage数组的数据和接收数据10个字符,保存在数组aRxBuffer中HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)aTxStartMessages,sizeof(aTxStartMessages)); //sizeof()可读取⽬标长度HAL_UART_Receive_IT(&huart1,(uint8_t*)aRxBuffer,10);3、在main.c⽂件后⾯添加中断接收完成函数,将接收到的数据⼜通过串⼝发送回去。

stm32自学笔记共20页

stm32自学笔记共20页


LED0=1;

LED1=0;

delay_ms(300);

}
•}
第二章 跑马灯实验
• Led.c函数
• void LED_Init(void)
•{

RCC->APB2ENR|=1<<2; //使能PORTA时钟

GPIOA->CRH|=0XFFFFFFFF3;//PA8 推挽输出

GPIOA->ODR|=1<<8; //PA8 输出高
• JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD,在原理图上可以看 到PA13和PA15为键盘和JTAG与SWD所共用,而这两种方针接口,他们 和普通的IO口公用,当想使用普通IO口时,必须先把他们关闭。在这 个函数里面设置参数,如果为二进制数00,则代表全部使能,如果是 二进制数01,则是能SWD,如果是10,则表示全部关闭。JTAG是一种 国际标准测试协议,主要用于芯片内部的测试。
• }要想实现一个点亮led小灯的功能,最少只需对3个寄存器进行设 置,第一步是设置外设时钟使能先把PORTA时钟使能,接下来把IO
口设置为输出,在接下来设置输出为高电平还是低电平,这里使用 推挽输出(3.3v),推挽输出主要是增强驱动能力,为外部提供大电 流。
第二章 跑马灯实验
• #ifndef __LED_H • #define __LED_H • #include "sys.h" • #define LED0 PAout(8)// PA8 • #define LED1 PDout(2)// PD2 • void LED_Init(void);//初始化

STM32学习笔记

STM32学习笔记

串口:一. USART_ITConfig(USART1, USART_IT_TXE, ENABLE):只要发送寄存器为空,就会一直有中断,因此,要是不发送数据时,把发送中断关闭,只在开始发送时,才打开。

二.以下是字符发送的配置过程,注意第6点,在设置USART_CR1中的TE位时,会发送一个空闲帧作为第一次数据发送,所以即便你执行了USART_ClearFlag(USART1, USART_FLAG_TC); (这个函数肯定在空闲帧数据发送完成前执行),所以当空闲帧发送完后,就进入发送完成中断。

配置步骤:1. 通过在USART_CR1寄存器上置位UE位来激活USART2. 编程USART_CR1的M位来定义字长。

3. 在USART_CR2中编程停止位的位数。

4. 如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMA T)。

按多缓冲器通信中的描述配置DMA寄存器。

5. 利用USART_BRR寄存器选择要求的波特率。

6. 设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。

7. 把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。

在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。

8. 在USART_DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束。

当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。

解决的办法:方法一在执行USART_ITConfig(USART1, USART_IT_TC, ENABLE); 之前,先延时一段时间,基本上比一个字符发送的时间长一点就可以了,然后再执行USART_ClearFlag(USART1, USART_FLAG_TC);方法二:在执行USART_ITConfig(USART1, USART_IT_TC, ENABLE); 之前,USART_ClearFlag(USART1, USART_FLAG_TC);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){; //等待空闲帧发送完成后再清零发送标志}USART_ClearFlag(USART1,USART_FLAG_TC);三.TXE:发送缓冲器空闲标志RXNE:接收缓冲区非空IAP:一.问:这几天在折腾STM32的IAP,参考了两个例程,一个AN2557,然后一个就是标准外设库内的flash例程总结IAP:1.Flash解锁 FLASH_Unlock();2.清除Flash所有的未完成的标志位 FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);3.根据文件大小擦除Flashfor(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE ); EraseCounter++){FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));}4.编程Flashwhile((Address < EndAddr) && (FLASHStatus == FLASH_COMPLETE)){FLASHStatus = FLASH_ProgramWord(Address, Data);Address = Address + 4;}5.检验编入数据的正确性while((Address < EndAddr) && (MemoryProgramStatus != FAILED)){if((*(__IO uint32_t*) Address) != Data){MemoryProgramStatus = FAILED;}Address += 4;}在以上几步中,如果上面没有问题的话,提出下面几个疑问1.假如我的应用程序的地址应该从0x8003000开始,那么我把后面的页全部擦除是否可以? 虽然我的程序可能只占到0x8003000-0x8005000 那么这之后的页是否也可以一并擦除?2.在编程的时候有个很小的问题,因我的数据都是以字节(byte)的形式储存的,在写的时候因为只能以半字(16位)或一个字(32位)的方式编程,那么如果我的bin文件的最后一个字节并不够两个字节,怎么办?举例:我的bin文件的大小是501个字节(8位),我的写入方法是这样的:data[501] = {X,X,X...}//应用程序bin文件内容temp = data[0];temp = temp << 8;temp |= data[1];temp = temp << 8;temp |= data[2];teme = temp << 8;teme |= data[3];//待写入得数据FLASHStatus = FLASH_ProgramWord(Address, temp);//写入flash如果像这样的话,那么不能被4整除的那一个字节怎么办?3.IAP程序中有一处一直很迷惑,不能理解/* Test if user code is programmed starting from address "ApplicationAddress" */if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000){ /* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}程序的整体是要跳出IAP引导区跳到应用程序区.那么这句判断的依据是什么?if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)倘若我今天的程序是重0x8003000处开始,那么明天我升级一个程序,他的开始是0x80080000呢?这里需要改吗?0x2FFE0000 0x20000000 这两个数我在AN2557的例子代码里反复寻找,并没有哪里出现,那么又是怎么跟用户的应用程序关联的呢?还有如果将上面的例子直接这样更改,是否可以达到跳转到应用程序区的目的呢?/* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); //这里为何要+4 ?+了4不就跳过出应用程序的入口了吗?Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();4.关于Flash的写保护问题,在3.0标准外设库中Flash还有另外一个例子,就是关于保护的无疑flash的保护是对程序的一个安全保障,但目前我买的新片子(未进行过任何保护方面的操作)中,是否不需要考虑这些问题,直接擦除,然后编程即可?5.有什么理由要“今天的程序是重0x8003000处开始,明天又升级一个程序,他的开始是呢”?第1没有必要,第2是自寻烦恼。

STM32学习笔记

STM32学习笔记

STM32学习一、初识库(略)二、(略)三、(略)四、(略)五、(略)六、系统定时器1、注意外部函数的声明;2、与六相同,也使用了中断;3、Volatile是不让编译优化的意思;4、Extern即定义外部函数,static是静态变量的意思。

七、串口通信1、当使用printf时,记得要在“bsp_usart1.h”文件中把“stdio.h”包含进来2、NVIC是中断优先级配置函数3、注意使用微库右图中的Use Micro LIB要打勾4、八、DMA1、DMA含义:data memory access,直接内存访问,此时不经过CPU2、这种方式节省CPU资源,好像可以同时做两件事(ADC、SPI、I2C等),不同的外设通道不同,可参看数据手册,串口1是通道4九、ADC1、ADC为12位,时钟为14MHz,最小采样时间为1微秒2、要提高采集频率,可采用多通道交叉采样。

十、FSMC液晶显示1、FSMC含义:灵活的静态存储器控制器2、注意配置IO引脚的第二功能时应注意配置成“AF-pp”即复用推挽模式;3、注意片选BANK1-44、野火自带的屏的高度840,宽320十一、I2C总线1、I2C一般都是开漏输出2、一般向I2C写数据时,如不加限制,是从头开始,写到本页结束如果再写又回到本页开头,会覆盖原来内容,因此,为避免这种情况,加地址。

十二、SPI总线1、SPI总线的读写速度(特别是读速度)要比对SD卡的快,而且成本低;2、SPI总线模块可存汉字字库、图片等,一些掉电保护信息也可存于此;3、在“bsp_spi_flash.c”中,语句“RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOD, ENABLE);”中的D端口时钟不需要开,即“RCC_APB2Periph_GPIOD”是不必要的,可以删去;4、“sizeof()”是C语言的保留字,其用法在此有描述。

stm32学习笔记

stm32学习笔记

stm32学习笔记Stm32学习笔记—寄存器版本养成良好的编程能⼒很重要否则还以后的⽣活和⼯作当中会吃很⼤的亏的!⼀、在MDK中进⾏对stm32的学习中⽤寄存器进⾏学习只需要很简单的操作,⽐起⽤库函数进⾏学习⼤⼤降低了学习的难度。

1)⾸先将system⽂件夹中的delay、sys以及usart三个⽂件夹复制到⼯程⽂件夹中并添加进⼯程当中去,然后再把⼀个启动⽂件复制到⼯程当中去并添加即可。

⼆、LED跑马灯的学习:1)编写LED初始化函数,这其中包括GPIOX时钟的使能,然后就是对应LED的端⼝的设置,其中包括输⼊输出模式以及输出的形式(是⾼电平还是低电平);2)编写完成之后就是调⽤LED初始化函数进⾏试验。

代码如下:void LED_Init(void){RCC->APB2ENR|=1<<3; //使能PORTB时钟RCC->APB2ENR|=1<<6; //使能PORTE时钟GPIOB->CRL&=0XFF0FFFFF; //输出模式GPIOB->CRL|=0X00300000;//PB.5 推挽输出GPIOB->ODR|=1<<5; //PB.5 输出⾼GPIOE->CRL&=0XFF0FFFFF;GPIOE->CRL|=0X00300000;//PE.5推挽输出GPIOE->ODR|=1<<5; //PE.5输出⾼}3)stm32中的IO⼝初始化之后默认的形式是下拉的。

下⾯是⼏种常见的输⼊形式,最好记住三、⽤串⼝发送和接受数据1)⾸先肯定是使能串⼝时钟和串⼝所对应的io⼝时钟,设置io⼝的输⼊输出模式,然后复位串⼝、停⽌复位,设置波特率和校检位。

⾄此串⼝已经初始化完毕。

串⼝的波特率是根据以下公式算的以下是初始化串⼝的函数void uart_init(u32 pclk2,u32 bound){float temp;u16 mantissa;u16 fraction;temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIVmantissa=temp; //得到整数部分fraction=(temp-mantissa)*16; //得到⼩数部分mantissa<<=4;//将最后的⼀个16进制位移开再与⼩数位相加mantissa+=fraction;RCC->APB2ENR|=1<<2; //使能PORTA⼝时钟RCC->APB2ENR|=1<<14; //使能串⼝时钟GPIOA->CRH&=0XFFFFF00F;//IO状态设置GPIOA->CRH|=0X000008B0;//IO状态设置RCC->APB2RSTR|=1<<14; //复位串⼝1RCC->APB2RSTR&=~(1<<14);//停⽌复位//波特率设置USART1->BRR=mantissa; // 波特率设置USART1->CR1|=0X200C; //1位起始,⽆校验位.#if EN_USART1_RX //如果使能了接收//使能接收中断USART1->CR1|=1<<8; //PE中断使能USART1->CR1|=1<<5; //接收缓冲区⾮空中断使能MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级#endif}四、外部中断事件1)初始化IO⼝为输⼊。

STM32学习笔记(初学者快速入门)a

STM32学习笔记(初学者快速入门)a
#include "stm32f10x_conf.h" #endif 看来,是这个 USE_STDPERIPH_DRIVER 没有被定义啊,于是,人为地去掉 条件: //#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h" //#endif 再次编译,果然就 OK 了。可是,可是,也不能就这么去掉啊,怎么办呢?万能 的网啊,一搜果然就有了。
说说我怎么学的吧。 找个例子,如 GPIO,可以看到其结构如下: SOURCE(文件夹)
- APP(文件夹) -CMSIS(文件夹) -STM32F10x_StdPeriph_Driver(文件夹) Lis(文件夹) OBJ(文件夹) 其中 SOURCE 中保存的是应用程序,其中又有好多子文件夹,而 CMSIS 文件 夹中和 STM32F10x_StdPeriph_Driver 文件夹中是 ST 提供的库,这样,如果要 做新的工程只要将这个文件夹整个复制过来就行,其中 APP 中保存自己的代码。 因为我们用 51 单片机时一般比较简单,有时就一个文件,所以通常不设置专 门的输出文件夹,而这里做开发,通常会有很多个文件加入一个工程中,编译过 程中会产生很多中间文件,因此设置专门的文件夹 LIS 和 OBJ 用来保存中间文 件。 下面就将设置简单描述一下。 将复到过来的 GPIO 根目录下的所有文件删除,因为我们要学着自己建立工程。
到设置 C/C++页面 在那个 define 中加入“USE_STDPERIPH_DRIVER,STM32F10X_HD” 当然,去掉条件编译前面的注释,回到原样。 再次编译,一切顺利。可是,原来的工程例子也没有加这个啊,怎么回事呢?再 次打开原来的例子,找到 stm32f10x.h,可以看到有这么一行:

STM32学习笔记

STM32学习笔记

STM32学习笔记MDK不会让你直接在入口参数处设置一个简单的字,因为这样代码可读性太差MDK一般把取值范围的宏定义放在判断有效性语句的上方,这样是为了方便大家查找可以通过|(或)的方式同时初始化多个IO口。

这样操作的前提是,他们的Mode和Speed参数相同,因为Mode和Speed参数并不能一次定义多种在tm32f10某.h看那些外设是挂载在那个总线之下GPIO操作步骤为:1)使能IO口时钟。

调用函数为RCC_APB2PeriphClockCmd()。

2)初始化IO参数。

调用函数GPIO_Init();3)操作IO。

按键一端接高电平时另一端接I/O口则I/O口设置为下拉输入,因为按键按下时I/O口变成高电平;反之接低电平时I/O口设置为上拉输入因为按键按下时I/O口状态为低电平Config意为配置voidNVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改当接收到从电脑发过来的数据,把接收到的数据保存在USART_R某_BUF中,同时在接收状态寄存器(USART_R某_STA)中计数接收到的有效数据个数,当收到回车(回车的表示由2个字节组成:0某0D和0某0A)的第一个字节0某0D时,计数器将不再增加,等待0某0A的到来,而如果0某0A没有来到,则认为这次接收失败,重新开始下一次接收。

如果顺利接收到0某0A,则标记USART_R某_STA的第15位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到0某0D,那么在接收数据超过USART_REC_LEN的时候,则会丢弃前面的数据,重新接收。

USART初始化需要设置的参数为:波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式(收,发)。

①串口时钟使能,GPIO时钟使能②串口复位③GPIO端口模式设置④串口参数初始化⑤初始化NVIC并且开启中断⑥使能串口SyTick是系统滴答计时器在E某TI_GetITStatu函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而E某TI_GetFlagStatu直接用来判断状态标志位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

对于STM32学习我的熟悉过程可以分以下阶段:1、入门程序的熟悉2、GPIOX的操作,各类寄存器原理的了解3、逐个寄存器熟悉4、中断,定时器的基础入门熟悉5、USART的了解,6、重复2345的步骤,加深对这些模块寄存器直接的协同了解突破,达到熟练。

在这里,我发下了STM32的USART基本字节发送非常简单,然后用这个来配合中断显示,在程序中插入各类输出显示,可以很清楚的知道程序中的运行状态,先后次序,对于程序调试有很大帮助。

STM32F107开发板入门篇一——第一个程序的理解:准备开发环境MDK4.0以上,最简单的入门方式就是先调用MDK里面自带的例程程序,然后最好是先看D:\Keil\ARM\Boards\Keil\MCBSTM32C\Blinky\Blinky.c这里我就拿例这个例程序分析,虽然每句都分析了,但是刚入手STM32可能还是会有很多疑问,所以暂时不考虑寄存器问题,这里先给出一个程序的概念以及一些基本注意的东西,后面会有寄存器的说明:阅读下面程序最好用MDK打开上面的程序配合看,效果更直观。

RCC->APB2ENR|=1<<6; //使能PE口时钟(STM32所有的寄存器操作都需要先使能时钟)GPIOE->CRH=0x33333333; //配置PE口的高八位输出方式每位由4位二进制数控制,这里每位都是0011 代表50MHZ的高速输出参考GPIO->CRHSystemInit();/* Setup and initialize ADC converter */RCC->APB2ENR |= 1 << 9; /* Enable ADC1 clock ADC1使能时钟*/GPIOC->CRL &= 0xFFF0FFFF; /* Configure PC4 as ADC.14 input ADC1在此芯片用PC4来作为模拟输入设置为输入(IO口使用前都必须对其功能设置)*/ ADC1->SQR1 = 0x00000000; /* Regular channel 1 conversion 主要是第1,2位设置为0表示单通道采集其他位置0不是用其他功能*/ADC1->SQR2 = 0x00000000; /* Clear register 清领SQR2寄存器不适用其他功能*/ADC1->SQR3 = 14 << 0; /* SQ1 = channel 14 选用通道14,就是PC4 */ADC1->SMPR1 = 5 << 12; /* Channel 14 sample time is 55.5 cyc 通道14的采样周期选择101 即55.5周期*/ADC1->SMPR2 = 0x00000000; /* Clear register 清0采样寄存器二*/ADC1->CR1 = 1 << 8; /* Scan mode on 开启扫描模式*/ADC1->CR2 = (1 << 20) | /* Enable external trigger */(7 << 17) | /* EXTSEL = SWSTART */(1 << 1) | /* Continuous conversion */(1 << 0) ; /* ADC enable 设置ADC控制寄存器配置,使能ADC */ADC1->CR2 |= 1 << 3; /* Initialize calibration registers 初始化校准寄存器,由于此步骤需要一些周期,多以必须等待完成后才开始下一步操作*/while (ADC1->CR2 & (1 << 3)); /* Wait for initialization to finish */ADC1->CR2 |= 1 << 2; /* Start calibration 开始校准,然后等待校准完成*/while (ADC1->CR2 & (1 << 2)); /* Wait for calibration to finish */ADC1->CR2 |= 1 << 22; /* Start first conversion 启动转换*/for (;;) { /* Loop forever */if (ADC1->SR & (1 << 1)) { /* If conversion has finished 转换完成状态寄存器的1位置1 */AD_val = ADC1->DR & 0x0FFF; /* Read AD converted value 转换结果保存在寄存器ADC1->DR 的低12位*/ADC1->CR2 |= 1 << 22; /* Start new conversion 读取数据后再次启动转换*/}// GPIOE->BSRR=~(AD_val<<4);/* Calculate 'num': 0, 1, ... , LED_NUM-1, LED_NUM-1, ... , 1, 0, 0, ... */num += dir;if (num >= LED_NUM) { dir = -1; num = LED_NUM-1; }else if (num < 0) { dir = 1; num = 0; }GPIOE->BSRR = led_mask[num]; /* Turn LED on */ for (i = 0; i < ((AD_val << 8) + 100000); i++); //这里的FOR 循环延时就是用来读取AD转换的高8位加上100000构成延时,通过改变AD控制延时时间,12位的低4 位不是很稳定,在这里可以忽略GPIOE->BSRR = led_mask[num] << 16; /* Turn LED off */看了这些分析后,一定有很多疑问,在入门篇二中将逐个解除这些疑问。

当这些基本疑问解决后,就可以运用STM32的基本功能了。

STM32入门篇二——端口的认识理解端口控制—GPIOSTM32系列给每个端口都分配了一个地址空间,然后通过对地址的赋值操作来完成对端口的控制,差不多端口也就是寄存器控制。

每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。

根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。

─ 输入浮空─ 输入上拉─ 输入下拉─ 模拟输入─ 开漏输出─ 推挽式输出─ 推挽式复用功能─ 开漏复用功能每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。

GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。

在这里要说下前面用的GPIOX->CPL,ADC1->DR等等,寄存器的表示方式都是在库文件stm32f10x_cl.c中定义的,这个库文件也可以根据自己的习惯去定义,但是初学建议不要去动里面的文件,因为后面的例程都是以这个为基础编写的。

这个文件必须要先去熟悉,在里面找到上一节提到的所有的寄存器,然后差不多就能看明白这些命名规律,继续后面的学习了。

CPIOX_CRL/CRH 寄存器如下:CPIOX_CRL/CRH寄存器各位代表的端口模式:GPIOX_的高8位和低8位控制寄存器都一样寄存器都是32位的每4位控制IO口的一位。

然后介绍GPIOX的数据存储器,分为输入和输出存储器IDR和ODR;IDR是一个端口输入数据寄存器,只用了低16位。

该寄存器为只读寄存器,并且只能以16位的形式读出。

该寄存器各位的描述如下图所示:图3.1.1.2 端口输入数据寄存器IDR各位描述要想知道某个IO口的状态,你只要读这个寄存器,再看某个位的状态就可以了。

使用起来是比较简单的。

ODR是一个端口输出数据寄存器,也只用了低16位。

该寄存器虽然为可读写,但是从该寄存器读出来的数据都是0。

只有写是有效的。

其作用就是控制端口的输出。

该寄存器的各位描述如下图所示:图3.1.1.3 端口输出数据寄存器ODR各位描述这些都是16位操作,如果需要为操作就可以用到寄存器BSRR和BRR 这个也是我们前面的例程中用到的寄存器,描述如下:BRR寄存器和BSRR相反:对于ADC 寄存器还有其他类型寄存器可以参考《STM32编程手册》对于相应部分的介绍,这里暂时就介绍这么多。

下一章我们将简单的实现ADC 的配置。

BRR 寄存器描STM32入门篇三——ADC的基本操作在前面介绍的例程中有ADC的详细解释,现在我们结合前面的ADC部分,解释ADC的单通道采样的实现:STM32F107具有双12位ADC采样模块,采样时间达到1us. 支持单通道,多通道,交叉采样,自动校准,可编程采样时间,支持DMA。

在这里对我们要用到的状态寄存器比较多,在程序中有相应的说明,要查看其他功能可以参考《STM32编程手册》ADC寄存器模块。

在这里我们要说明下我们选的通道,ADC可以选择单通道也可以选择多通道,这里我们选择单通道,并且选择14通道,从STM32数据手册可以看到:14通道对应的是PC4口,因此ADC得输入应该由这里接入。

相关文档
最新文档