Stm32外围模块编程初始化步骤:
一、外部中断 1)初始化 IO 口为输入。 这一步设置你要作为外部中断输入的 IO 口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。 2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。 STM32 的 IO 口与中断线的对应关系需要配置外部中断配置寄存器 EXTICR,这样我们要先开启复用时钟,然后配置 IO口与中断线的对应关系。才能把外部中断与中断线连接起来。 3)开启与该 IO 口相对的线上中断/事件,设置触发条件。 这一步,我们要配置中断产生的条件,STM32可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置。同时要开启中断线上的中断,这里需要注意的是:如果使用外部中断,并设置该中断的EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置 EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置 EMR 位。 4)配置中断分组(NVIC),并使能中断。 这一步,我们就是配置中断的分组,以及使能,对 STM32的中断来说,只有配置了 NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。关于 NVIC 的详细介绍,请参考前面章节。 5)编写中断服务函数。 这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。 通过以上几个步骤的设置,我们就可以正常使用外部中断了。
二、定时器中断 1)TIM3时钟使能。 这里我们通过 APB1ENR 的第 1 位来设置 TIM3 的时钟,因为 Stm32_Clock_Init 函数里面把 APB1 的分频设置为 2 了,所以我们的 TIM3 时钟就是 APB1 时钟的2 被,等于系统时钟。 2)设置 TIM3_ARR和 TIM3_PSC 的值。 通过这两个寄存器,我们来设置自动重装的值,以及分频系数。这两个参数加上时钟频率就决定了定时器的溢出时间。 3)设置 TIM3_DIER允许更新中断。 因为我们要使用 TIM3 的更新中断,所以设置 DIER 的 UIE 位,并使能触发中断。 4)允许 TIM3 工作。 光配置好定时器还不行,没有开启定时器,照样不能用。我们在配置完后要开启定时器,通过 TIM3_CR1 的CEN位来设置。 5)TIM3中断分组设置。 在定时器配置完了之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器,以使能TIM3 中断。 6)编写中断服务函数。 在最后,还是要编写定时器中断服务函数,通过该函数来处理定时器产生的相关中断。在中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作,在处理完中断之后应该向 TIM3_SR 的最低位写 0,来清除该中断标志。
三、1)开启 TIM3 时钟,配置 PA7 为复用输出。 要使用 TIM3,我们必须先开启 TIM3的时钟(通过 APB1ENR 设置),这点相信大家看了这么多代码,应该明白了。这里我们还要配置 PA7 为复用输出,这是因为 TIM3_CH2 通道是以 IO复用的形式连接到 PA7 上的,这里我们要使用复用输出功能。 2)设置 TIM3 的 ARR和 PSC。 在开启了TIM3的时钟之后,我们要设置ARR和PSC两个寄存器的值来控制输出PWM的周期。 3)设置 TIM3_CH2的 PWM 模式。 接下来,我们要设置 TIM3_CH2 为 PMW 模式(默认是冻结的)。 4)使能 TIM3 的 CH2 输出,使能 TIM3。 在完成以上设置了之后,我们需要开启 TIM3 的通道 2 输出以及 TIM3。前者通过TIM3_CCER1 来设置,是单个通道的开关,而后者则通过 TIM3_CR1 来设置,是整个 TIM3 的总开关。只有设置了这两个寄存器,这样我们才能在 TIM3的通道 2 上看到 PWM 波输出。 5)修改 TIM3_CCR2 来控制占空比。 最后,在经过以上设置之后,PWM 其实已经开始输出了,只是其占空比和频率都是固定的,而我们通过修改 TIM3_CCR2 则可以控制 CH2 的输出占空比。 通过以上 5个步骤,我们就可以控制 TIM3的 CH2 输出 PWM 波了。
四、TFTLCD 1)设置 STM32 与 TFTLCD 模块相连接的 IO。 这一步,先将我们与 TFTLCD模块相连的 IO口设置为输出,具体使用哪些 IO口,这里需要根据连接电路以及 TFTLCD模块的设置来确定。 2)初始化 TFTLCD模块。 其实这里就是上和上面 OLED模块的初始化过程差不多。通过向 TFTLCD写入一系列的设置,来启动 TFTLCD的显示。为后续显示字符和数字做准备。 3)通过函数将字符和数字显示到 TFTLCD模块上。 这里就是通过我们设计的程序,将要显示的字符送到 TFTLCD模块就可以了,这些函数将在软件设计部分向大家介绍。 通过以上三步,我们就可以使用 ALIENTEK TFTLCD模块来显示字符和数字了, 并且可以显示各种颜色的背景。
五、RTC 1)使能电源时钟和备份区域时钟。 前面已经介绍了,我们要访问 RTC 和备份区域就必须先使能电源时钟和备份区域时钟。这个通过 RCC_APB1ENR 寄存器来设置。 2)取消备份区写保护。 要向备份区域写入数据,就要先取消备份区域写保护(写保护在每次硬复位之后被使能),否则是无法向备份区域写入数据的。我们需要用到向备份区域写入一个字节,来标记时钟已经配置过了,这样避免每次复位之后重新配置时钟。 3)复位备份区域,开启外部低速振荡器。 在取消备份区域写保护之后,我们可以先对这个区域复位,以清除前面的设置,当然这个操作不要每次都执行,因为备份区域的复位将导致之前存在的数据丢失,所以要不要复位,要看情况而定。然后我们使能外部低速振荡器,注意这里一般要先判断 RCC_BDCR 的 LSERDY位来确定低速振荡器已经就绪了才开始下面的操作。 4)选择 RTC 时钟,并使能。 这里我们将通过 RCC_BDCR 的 RTCSEL 来选择选择外部 LSI 作为 RTC的时钟。然后通过RTCEN位使能 RTC 时钟。 5)设置 RTC 的分频,以及配置 RTC时钟。 在开启了 RTC 时钟之后,我们要做的就是设置 RTC 时钟的分频数,通过 RTC_PRLH 和RTC_PRLL 来设置,然后等待 RTC 寄存器操作完成,并同步之后,设置秒钟中断。然后设置RTC的允许配置位(RTC_CRH的CNF位),设置时间(其实就是设置RTC_CNTH和RTC_CNTL两个寄存器)。 6)更新配置,设置 RTC中断。 在设置完时钟之后,我们将配置更新,这里还是通过 RTC_CRH的 CNF来实现。在这之后我们在备份区域 BKP_DR1 中写入0X5050 代表我们已经初始化过时钟了,下次开机(或复位)的时候,先读取 BKP_DR1 的值,然后判断是否是 0X5050 来决定是不是要配置。接着我们配置 RTC 的秒钟中断,并进行分组。 7)编写中断服务函数。 最后,我们要编写中断服务函数,在秒钟中断产生的时候,读取当前的时间值,并显示到TFTLCD模块上。 通过以上几个步骤,我们就完成了对 RTC 的配置,并通过秒钟中断来更新时间。
六、待机唤醒 1)设置 SLEEPDEEP 位。 该位在系统控制寄存器(SCB_SCR)的第二位(详见《CM3 权威指南》 ,第182 页表13.1),我们通过设置该位,作为进入待机模式的第一步。 2)使能电源时钟,设置 WK_UP 引脚作为唤醒源。 因为要配置电源控制寄存器,所以必须先使能电源时钟。然后再设置 PWR_CSR 的EWUP位,使能 WK_UP用于将 CPU从待机模式唤醒。 3)设置 PDDS 位,执行 WFI 指令,进入待机模式。 接着我们通过 PWR_CR设置 PDDS 位,使得 CPU进入深度睡眠时进入待机模式,最后执行 WFI指令开始进入待机模式,并等待 WK_UP中断的到来。 4)最后编写 WK_UP 中断函数。 因为我们通过 WK_UP中断(PA0 中断)来唤醒 CPU,所以我们有必要设置一下该中断函数,同时我们也通过该函数里面进入待机模式。 通过以上几个步骤的设置,我们就可以使用 STM32 的待机模式了,并且可以通过 WK_UP来唤醒 CPU。
七、ADC 1)开启 PA口时钟,设置 PA0 为模拟输入。 STM32F103RBT6 的 ADC通道 0 在 PA0 上,所以,我们先要使能 PORTA的时钟,然后设置 PA0 为模拟输入。 2)使能 ADC1 时钟,并设置分频因子。 要使用 ADC1,第一步就是要使能 ADC1 的时钟,在使能完时钟之后,进行一次 ADC1 的复位。接着我们就可以通过 RCC_CFGR 设置 ADC1 的分频因子。分频因子要确保 ADC1 的时 钟(ADCCLK)不要超过 14Mhz。 3)设置 ADC1 的工作模式。 在设置完分频因子之后,我们就可以开始 ADC1 的模式配置了,设置单次转换模式、触发方式选择、数据对齐方式等都在这一步实现。 4)设置 ADC1 规则序列的相关信息。 接下来我们要设置规则序列的相关信息,我们这里只有一个通道,并且是单次转换的,所以设置规则序列中通道数为 1,然后设置通道 0的采样周期。 5)开启 AD转换器,并校准。 在设置完了以上信息后,我们就开启 AD 转换器,执行复位校准和 AD 校准,注意这两步是必须的!不校准将导致结果很不准确。 6)读取 ADC值。 在上面的校准完成之后,ADC 就算准备好了。接下来我们要做的就是设置规则序列 0里面的通道,然后启动 ADC 转换。在转换结束后,读取 ADC1_DR 里面的值就是了。 通过以上几个步骤的设置,我们就可以正常的使用 STM32 的 ADC1 来执行 AD 转换操作了。
八、ADC 1)设置外设地址。 设置外设地址通过 DMA1_CPAR4 来设置,我们只要在这个寄存器里面写入&USART1_DR 的值就可以了。该地址将作为 DMA 传输的目标地址。 2)设置存储器地址。 设置存储器地址,我们通过 DMA1_CMAR4 来设置,假设我们要把数组 SendBuf 作为存储器,那么我们在该寄存器写入&SendBuf就可以了。该地址将作为 DMA 传输的源地址。 3)设置传输数据量。 通过 DMA1_CNDTR4 来设置DMA1 通道 4的数据传输量, 这里面写入此次你要传输的数据量就可以了,也就是 SendBuf 的大小。该寄存器的数值将在 DMA启动后自减,每次新的 DMA 传输,都重新向该寄存器写入要传输的数据量。 4)设置通道 4 的配置信息。 配置信息通过 DMA1_CCR4 来设置。这里我们设置存储器和外设的数据位宽均为 8,且模式是存储器到外设的存储器增量模式。优先级可以随便设置,因为我们只有一个通道被开启了。假设有多个通道开启(最多 7 个),那么就要设置优先级了,DMA 仲裁器将根据这些优先级的设置来决定先执行那个通道的 DMA。优先级越高的,越早执行,当优先级相同的时候,根据硬件上的编号来决定哪个先执行(编号越小越优先)。 5)使能DMA1 通道 4,启动传输。 在以上配置都完成了之后,我们就使能 DMA1_CCR4 的最低位开启 DMA 传输,这里注意要设置 USART1 的使能 DMA 传输位,通过 USART1->CR3的第七位设置。 通过以上 5步设置,我们就可以启动一次 USART1 的DMA 传输了。
九、SPI 1)配置相关引脚的复用功能,使能 SPI1 时钟。 我们要用 SPI1,第一步就要是能 SPI1 的时钟,SPI1 的时钟通过 APB2ENR 的第 12 位来设置。其次要设置 SPI1 的相关引脚为复用输出,这样才会连接到 SPI1 上否则这些 IO口还是默认的状态,也就是标准输入输出口。这里我们使用的是 PA5、6、7 这3 个(SCK.、MISO、MOSI,CS使用软件管理方式),所以设置这三个为复用 IO。 2)设置 SPI1 工作模式。 这一步全部是通过 SPI1_CR1 来设置,我们设置 SPI1 为主机模式,设置数据格式为 8位,然后通过 CPOL 和 CPHA 位来设置 SCK时钟极性及采样方式。并设置 SPI1 的时钟频率(最大18Mhz),以及数据的格式(MSB 在前还是 LSB在前)。 3)使能 SPI1。 这一步通过 SPI1_CR1 的 bit6 来设置,以启动 SPI1,在启动之后,我们就可以开始 SPI通讯了。