EDN首页   博客首页

26

关于投票
STM32F103的复位及时钟控制模块头文件

    在处理器正常工作前,肯定要做一些初始化工作,其中最主要的一个就是初始化各种时钟。圈圈通过对STM32F103的复位及时钟控制(RCC)模块分析之后,自己写了一个RCC的头文件,这样使用起来更方便。头文件中首先定义了最基本的几个寄存器,然后再对每个寄存器中的域使用结构体做了定义,可以直接使用寄存器中的位来操作。注意设置系统时钟时要先设置好FLASH的等待周期,不然程序就可能会跑飞,参看http://blog.ednchina.com/computer00/140713/message.aspx

    该测试工程是在以前的GPIO实验的基础上增加系统时钟初始化代码,设置系统时钟为72M。通过流水灯可以看到,比未配置系统时钟之前(8M)流水灯的速度快了很多。从这里下载完整的测试工程:点击下载

系统时钟初始化的代码如下:

//以下时钟配置为最高性能
void SystemClockInit(void)
{
 //设置flash等待周期为2,否则设置为72M系统时钟时就会跑飞
 FLASH_ACR=0x32; 
 
 pbRCC_CR->HSEON=1;          //使能外部高速时钟
 while(!(pbRCC_CR->HSERDY)); //等待外部高速时钟稳定
 pbRCC_CFGR->MCO=0;          //MCO无时钟输出
 pbRCC_CFGR->USBPRE=1;       //USB时钟1.5分频
 pbRCC_CFGR->PLLMUL=9-2;     //PLL倍频设置为9倍(外部时钟8M,PLL输出72M)
 pbRCC_CFGR->PLLXTPRE=0;     //HSE不分频
 pbRCC_CFGR->PLLSRC=1;       //HSE选作做为PLL时钟源输入
 pbRCC_CFGR->ADCPRE=0;       //ADC时钟2分频
 pbRCC_CFGR->PPRE2=1+6;      //APB2设置为1分频
 pbRCC_CFGR->PPRE1=2+6;      //APB1设置为2分频
 pbRCC_CFGR->HPRE=0;         //AHB无分频
 pbRCC_CR->PLLON=1;          //启动PLL
 while(!(pbRCC_CR->PLLRDY)); //等待PLL稳定
 pbRCC_CFGR->SW=2;           //选择PLL输出为时钟源
 //pbRCC_AHBENR->SRAMEN=1;
 //pbRCC_AHBENR->FLITFEN=1;
 
 //IO口第二功能时钟使能
 pbRCC_APB2ENR->AFIOEN=1;
 
 //各通用IO口时钟使能
 pbRCC_APB2ENR->IOPAEN=1;
 pbRCC_APB2ENR->IOPBEN=1;
 pbRCC_APB2ENR->IOPCEN=1;
 pbRCC_APB2ENR->IOPDEN=1;
 pbRCC_APB2ENR->IOPEEN=1;
 
 //ADC时钟使能
 pbRCC_APB2ENR->ADC1EN=1;
 pbRCC_APB2ENR->ADC2EN=1;
 
 //定时器1时钟使能
 pbRCC_APB2ENR->TIM1EN=1;
 
 //SPI1时钟使能
 pbRCC_APB2ENR->SPI1EN=1;
 
 //串口1时钟使能
 pbRCC_APB2ENR->USART1EN=1;
 
 //定时器2、3、4时钟使能
 pbRCC_APB1ENR->TIM2EN=1;
 pbRCC_APB1ENR->TIM3EN=1;
 pbRCC_APB1ENR->TIM4EN=1;
 
 //窗口看门狗时钟不使能
 pbRCC_APB1ENR->WWDGEN=0;

 //SPI2时钟使能
 pbRCC_APB1ENR->SPI2EN=1;

 //串口2、3时钟使能
 pbRCC_APB1ENR->USART2EN=1;
 pbRCC_APB1ENR->USART3EN=1;
 
 //I2C1、2时钟使能
 pbRCC_APB1ENR->I2C1EN=1;
 pbRCC_APB1ENR->I2C2EN=1;
 
 //USB时钟使能
 pbRCC_APB1ENR->USBEN=1;

 //CAN时钟使能
 pbRCC_APB1ENR->CANEN=1;
 
 //备份接口时钟使能
 pbRCC_APB1ENR->BKPEN=1;
 
 //电源接口时钟使能
 pbRCC_APB1ENR->PWREN=1;
 
 //外部低速时钟启动
 pbRCC_BDCR->LSEON=1;
 pbRCC_BDCR->LSEBYP=0;
 pbRCC_BDCR->RTCSEL=1; //选择外部时钟为RTC时钟
}

系统分类: 单片机
用户分类: STM32
标签: STM32F103 复位及 时钟控制 头文件
来源: 原创
发表评论 阅读全文(2419) | 回复(2)

20

关于投票
STM32配置时钟时注意设置FLASH等待周期

    今天是2008年7月28日,广州天气热啊,热得叫人受
不了。中午回来啥活都不想干了,还是玩玩手头上的
STM32板吧。
    兴致勃勃地把复位及时钟控制(RCC)的寄存器定义写
完了,没得午觉睡倒算了,还累得满头大汗……看来这
事有点吃力不讨好,真想用别人现成的头文件算了,最后
还是咬咬牙自己写吧,至少可以让自己对寄存器结构熟悉
一些。
    傍晚回来再写个测试程序,满以为一次就OK的,可
是调试时却发现,运行到选择PLL时钟后程序就跑飞……
顿时就傻眼了……检查各个寄存器配置,似乎没什么问题
啊:选择外部8M时钟,不分频输入到PLL,设置PLL为9倍
频(注意实际写入到寄存器中为7),AHB、ABP2不分频,
ABP1为2分频(注意设置为8才是2分频),都没有超过最大
频率啊。看来想要搞个72M的主频遇到麻烦了……试着将倍
频降下来,当主频为48M时,系统可以正常工作了,莫非是
USB模块的时钟没有设置为1.5分频?再检查,没错啊,是
1.5分频的。找不到原因,额头上开始冒出了豆大的汗珠,
还好今天天气热,被掩饰过去了,不然让那些行家看到笑
死...莫非俺的片子是被人打磨过的...
    最后去论坛问了下,斑竹提示说是否忘记了设置FLASH
等待周期?哈哈,好象我的程序是没有这个步骤,因为手册
里没有关于FLASH的寄存器描述,所以把它给忽略了...不过
里面也有提到系统时钟不同时,需要设置不同的等待周期,
24M以下使用0等待,24M~48M使用1等待,48M~72M使用2等
待。找到FALSH的手册,看了下上电复位后的等待设置为0,
晕,72M主频不跑飞才怪了。在配置时钟之前,增加了一句
FLASH_ACR=0x32,将等待周期设置为2,再次运行程序,
流水灯流了起来~~~
    根据圈圈以往的经验,通常像访问存储器的相关寄存
器,复位后都会设置为最坏条件下的值(例如等待周期设置
为最大),然后再由用户自己配置以达到最佳性能。不过,
STM32这个是内部的FLASH,上电复位后系统将自动使用内部
8M时钟做为系统时钟,因而设置为0等待是没问题的。

系统分类: 单片机
用户分类: STM32
标签: STM32 配置时钟 设置FLASH 等待周期
来源: 原创
发表评论 阅读全文(2374) | 回复(0)
总共 , 当前 /