你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【MCU实战经验】STM32F407 Discovery开发实例心得分享

[复制链接]
仙人掌 发布时间:2014-4-19 11:11
      本人一直以来都在接触STM32方面的软硬件开发工作,最初的是做基于STM32F1的汽车电子相关的软件研发工作,有用到F1的一些基本功能,例如USART串口通信,IIC存储EEPROM芯片,SPI读写FLASH等等,内核的SYSTICKNVIC,中断,强大的定时器功能也总是用到,尤其是CAN总线,其稳定的工作机制和强大的纠错,适应能力,最适合汽车电子等工作环境不稳定的场合。最开始的这些研发工作使我对STM32情有独钟,其强大的外设资源,能满足绝大部分的应用需求,丰富的系列产品,能满足预算和功能的协调统一。
      有了一些基础之后,我在网上看到了STM32F4 Discovery的出现,高达168MHz的主频,1M的片内FLASH192KSRAM,内置RNGFPU等等,并且包含了F1系列的几乎所有功能,尤其支持USB OTG,强化了音视频解码,能做出更多的功能和有意思的探索。接下来就STM32F4 Discovery官方开发板,本人自己研究的一些过程经验和体会,分享给大家,限于本人能力有限,仅代表个人观点,还请大家多多指教。
   首先,对于开发方式,本人采用“MDK4.72 + 寄存器”进行开发,首先,此版本的MDK(keil)有在线纠错功能,让你能时刻看到自己写的语句是否有问题,虽然有时候的软件提示有少许BUG,但是瑕不掩瑜,还是很不错的功能,其次,新版本的MDK支持的芯片更多,可以方便你移植代码到其他平台上去。再就是用寄存器方式开发,这个纯属个人兴趣,我的方法是:比如我要写某个功能,我会先看官方或者网上一些高手写的库函数的代码,慢慢去分析他们的思路,和一些初始化或者配置的过程,最后总结出一个规律或者套路,再去看芯片的手册,找到相关寄存器,分析用到的每个位的作用,写出寄存器配置的代码,这个过程虽然枯燥无味,却能真正然你理解其中含义,非常清晰的看到一步步配置的过程,不会在云里雾里,所以我采用寄存器方式开发。这个适合时间充裕,想真正了解和学习内核的人。当然,萝卜白菜各有所爱。相关寄存器配置资料:
STM32F4_DISCOVERY    --   官方开发板的说明手册,外设介绍等等
RM0090 Reference Manual  --  寄存器手册,也是寄存器方式开发重点要看的
STM32F407数据手册        --   主芯片STM32F407VGT6的手册,主要看管脚对应功能,外设配置简介等
Cortex-M4 Devices Generic User Guide  --  Cortex-M4内核手册,包含NVIC,SYSTICK等等内核的详细说明
还可以去ST官网下载3.5的库函数,以及STM32F4 Discovery板的例程,经常看一看,借鉴学习下,非常有好处。
F4系列和F1系列的寄存器有少许差别,大家使用时可参考F1的相关例程,对照修改即可。

以下发表一些自己研究过程中的心得体会:若有错误,还请指正(以下代码均对应官方的STM32F4 Discovery板子,部分代码仅贴出最关键部分)
一,IO
最开始莫过于控制IO口的电平高低了,从这里开始,F4的寄存器就不同于F1,例如初始化LED的代码:
//PD12:绿灯,PD13:橙灯,PD14:红灯,PD15:蓝灯
void LED_Init(void)
{
   RCC->AHB1ENR |= 1OTYPER &= 0xFFFF0FFF;//设置PD12,13,14,15推挽输出
  GPIOD->OSPEEDR &= 0x00FFFFFF;//PD12,13,14,15速度100M
  GPIOD->OSPEEDR |= 0xFF000000;
  SYSCFG->CMPCR = 0x00000001;//GPIO速度超过50M的时候,使用IO补偿单元   
  GPIOD->UPDR &= 0x00FFFFFF;//PD12,13,14,15无上拉无下拉
  GPIOD->BSRRH = 0xF000;//配置完成后使所有等保持熄灭状态
}
配置过程:
1,开启GPIOD时钟 2,配置IO为通用输出模式  3,配置IO为推挽输出  4,配置IO输出速度  5,配置上下拉模式  (其中,使用IO补偿单元不是必须,只是官方历程中写到,实测不加此句也可以)                                                                                                                                 2,相关寄存器为:GPIOD->MODER      GPIOD->OTYPER       GPIOD->OSPEEDR       GPIOD->UPDR
二,USART
USART串口也是调试过程中,或者以后产品运行时与上位机软件通信的手段之一,十分重要,可以官方的开发板只有micro USB接到了USB OTG,虽说也可以配置通信,但是太复杂了,本人还没调通,暂时用把排针引线接到其他板子的USB转串口的芯片,再连接到电脑。
注意:一开始我连接到的是USART1,也就是PA9,PA10,但是怎么也调试不通,一直在串口调试软件中显示乱码,一开始以为是波特率有问题,可是怎么也调不成功。后来我看官方开发板的原理图,才发现PA9,PA10已经连接到了板载的一个芯片上,可能是做USB设备的驱动芯片吧。所以我换成了USART3,对应发送接收引脚PD8,PD9,检查无冲突之后,仅更改引脚,使用之前的相同配置,调试通过。代码如下:
USART初始化部分:
//初始化串口3
//USART1,6 84MHz  USART2,3,4,5 42MHz
//波特率不通过参数传入,直接通过计算得到,并写入USART_BRR
void MYUSART_Init(void)
{
         //使能PORTDUSART3时钟
         RCC->AHB1ENR |= 1OTYPER &= ~(1PUPDR |= 0x00040000;  //PD9 上拉
         //复位USART3
         RCC->APB1RSTR |= 1CFGR = 0x00000000;
  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;
  /* Reset PLLCFGR register */
  RCC->LLCFGR = 0x24003010;
  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
}

//STM32F4时钟配置
//关键是粗体部分的参数配置,此四个参数决定了配置后的MCU的主频,进而决定了整个系统的时基
//配置完成后系统主频为168MHz,注意,板载是8MHz晶振,所以要在MDK的设置里写为8
//还需要在文件stm32f4xx.h中第92中把25000000改为8000000
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      8
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7
void F4_Clock_Init(void)
{
         /* PLL (clocked by HSE) used as System clock source */
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
         
         F4_Clock_DeInit();
         
         /* Enable HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
         
         /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
         
         if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable high performance mode, System frequency up to 168 MHz */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_PMODE;  

    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
   
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    /* Configure the main PLL */
<strong>    RCC->LLCFGR = PLL_M | (PLL_N > 1) -1) CR & RCC_CR_PLLRDY) == 0)
    {
    }
                  
                   /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
         else
  { /* If HSE fails to start-up, the application will have wrong clock
         configuration. User can add here some code to deal with this error */
  }


说明:以上是初始化的关键部分,SYSTICK频率默认为系统时钟的8分频,配置好了时钟,自然就可以轻松设置SYSTICK了。
四,定时器 PWM 输出
STM32的定时器很复杂功能也很多,此处仅说说TIM4作为PWM输出时的配置,效果是控制LED产生呼吸灯的效果。                                  此处仅配置TIM4-CH4的输出,其余几路输出同理:
//PD15 BLUE   TIM4-CH4
u16 TIM4_CCR4_Val = 0;
u16 PrescalerValue = 0;//预分频器值
u16 pwm_tempvalue=1;
//TIM4-CH4 PWM输出初始化
//必须对PD15的IO口进行重新配置
void TIM4_CH4_PWM_Init(u16 arr)
{
        //TIM4时钟使能
        RCC->APB1ENR |= 1OSPEEDR |= 0xC0000000;
        //当速度超过50MHz时使用IO补偿单元
        SYSCFG->CMPCR = 0x00000001;
        //PD15上拉,PUPDR15[1:0]即31,30位  01ull-up
        GPIOD->UPDR |= 0x40000000;
        //配置第二功能寄存器(必须开启),PD15对应GPIOD->AFRH
        //31,30,29,28位 AF2:0010
        GPIOD->AFR[1] |= 0x20000000;

        //计算预分频器值
        PrescalerValue = (u16)((SystemCoreClock/2)/28000000)-1;        
        //设置计数器自动重装载值
        TIM4->ARR = arr;
        //设置预分频器分频值
        TIM4->SC = PrescalerValue;
        //时基配置:Bits 9:8 00:t(DTS)=t(CK_INT)
        //TIM4->CR1 &= 0xFCFF;
        //计数模式配置:Bits 6:5 00
        //TIM4->CR1 &= 0xFF9F;        
        //配置TIM4的CH4为WM1模式输出
        //配置TIM4_CCMR2的OC4M(位14,13,12)为:110
        TIM4->CCMR2 |= 6CCR4的值来该表占空比,从而控制LED的亮度
        TIM4->CCR4 = TIM4_CCR4_Val;
}

主函数中:
TIM4_CH4_PWM_Init(800);//TIM4 CH4 PWM输出初始化
循环里调用TIM4_CH4_PWM_OutPut();  即可

说明:1,粗体部分是重点    2,IO要配置成第二功能模式     3,延时控制了呼吸灯的节奏,占空比控制了LED亮和灭的范围,这个可以自己多次设置后调试体会。

五,RNG 随机数生成器
这个是STM32F4比较有意思的一个功能,可以硬件产生一个随机数,更加方便易用,配置也相对简单:
void RNG_Init(void)//随机数寄存器初始化
{
  RCC->AHB2ENR |= 1CR |= 0x00000004;
  RNG->SR &= 0xFFFFFFFE;
  RNG->SR |= 0x00000001;  
}

int RNG_Generate(int y)//生成随机数
{
  int x;
  x=(RNG->DR) % y;  
  return x;
}
说明:开启相应时钟,简单的配置几个寄存器,然后再main中初始化:RNG_Init()就OK了,若要在其他外设文件中使用随机数,包含头文件rng.h,然后定义变量接收函数RNG_Generate(int y)的值即可,简单易用。
------------END
对于STM32F429,我还是很期待的,比较自带了LCD,还有SDRAM,更多的应用可以被做出来,更流畅的跑系统和需要大内存的应用了,本想自己画个板子,接LCD,然后插在STM32F407 Discovery板子上的,可是硬件设计又是个难题,万一设计错误就无法使用了,所以STM32F429是个不错的选择,官方的开发板,外设丰富很超值。
以上是本人研究的一些东西,给大家分享,本人也是菜鸟,希望大家多指导,共同进步
收藏 2 评论4 发布时间:2014-4-19 11:11

举报

4个回答
仙人掌 回答时间:2014-4-24 21:25:40

RE:【MCU实战经验】STM32F407 Discovery开发实例心得分享

最近在研究F4的ADC功能,发现跟F1的寄存器不同,比如:
1,选择触发方式为软件触发时,F1的寄存器有对应设置的位,但是F4中我没有找到,也不清楚到底有没有?
2,ADC校准,在F4的寄存器手册中找不到对应的寄存器的位,不校准,岂不是精度很差?
以上两个问题,请教下大家!希望有人能发表相关意见和经验!
bjybjy 回答时间:2014-6-18 17:12:57

RE:【MCU实战经验】STM32F407 Discovery开发实例心得分享

楼主你好,请教一下,STM32F407 Discovery USART CTS/RTS该怎么用,谢谢
youxiaoxiang 回答时间:2014-11-24 12:44:44
楼主你好。看了你的PWM 输出 做呼吸灯的问题。有一点疑惑。
具体是如何调节的?
巅峰残狼 回答时间:2014-11-24 13:01:16
谢谢分享

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版