您的位置:首页 > 其它

STM32寄存器开发(工程模板建立2)

2018-03-07 11:22 169 查看
调试了好几晚上,终于编写完属于自己版本的寄存器版本,今天主要编写STM32F103VET6的系统时钟寄存器版本文件,让程序能够编译下载到单片机,并且写了一个简单的LED闪烁程序,并加入了版主自己的编程格式
1.在上一篇的基础上,新建sys.c和sys.h保存到system文件夹下的新建文件夹sys,在工程中添加sys.c,添加DOC说明文件





2.下面开始正式编写sys文件(系统时钟初始化文件)void SysInit(uint8_t plln)
{
RCC->CR |= 0x00000001;//设置系统默认复位初始化时钟为内部高速时钟HSI,CR复位值0x0000xx83
RCC->CFGR |= 0x00000000;//复位CFGR寄存器:1.时钟输出,2.USB时钟选择,3.PLL,4.ADC,5.APB2,6.APB1,7.AHB,8.系统时钟切换
RCC->CR &= 0xFEF6FFFF;//复位(清零)PLLON,CSSON,HSEON(关闭PLL、时钟监测CSS、HES)
RCC->CR &= 0xFFFBFFFF;//复位(清零)HSEBYP(HSE晶振不旁路)
RCC->CFGR &= 0xFF80FFFF;//复位PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE,USB时钟为PLL1.5倍分频
RCC->CIR = 0x009F0000;//禁止中断,清除标志位
SetSysClock(0x2, 0x1, 0x0, plln);//选择PLL作为系统时钟,HSE不分频作为PLL输入
#ifdef VECT_TAB_SRAM //参考CM3与CM4权威指南7.9节,299页
SCB->VTOR = (1<<29) | ((SRAM_BASE| 0x0)&0x1FFFFF80); /* 设置向量中断表到SRAM,偏移地址为0x0 */
#else
SCB->VTOR = (0<<29) | ((FLASH_BASE| 0x0)&0x1FFFFF80); /* 设置向量中断表到FLASH,偏移地址为0x0 */
#endif
}
/**
* @brief  设置系统时钟函数
*					系统时钟频率sysClock,1.HSI作为系统时钟 sysClock= HSI;
*															 2.HSE作为系统时钟 sysClock= HSE;
*															 3.PLL作为系统时钟 HSI作为PLL时钟输入;sysClock= HSI/2*plln
*																								HSE不分频作为PLL时钟输入;sysClock=PLL= HSE*plln
*																								HSE二分频作为PLL时钟输入;sysClock=PLL= HSE/2*plln
* @param  @arg sysClkSel:0x0:HSI作为系统时钟,0x1:HSE作为系统时钟,0x2:PLL作为系统时钟
*					@arg plli:当选择PLL作为系统时钟时,PLL时钟输入选择0x0:HSI二分频后作为PLL时钟输入,0x1:HSE作为PLL时钟输入
*					@arg plliHSEDiv:当HSE作为PLL时钟输入时,0x0:HSE不分频输入,0x1:HSE分频输入
*					@arg plln:PLL时钟倍频因子0x0~0xE(2~16倍)
*								只有在前提条件下,参数才有作用
此程序只设置系统时钟,AHB=PLL,APB2=AHB,APB1=AHB/2
推荐值:8M晶振sysClkSel:0x2,plli:0x1,plliHSEDiv:0x0,plln:0x7,产生72M系统时钟
* @retval status:0x00设置失败,0x01设置成功
*/
uint8_t SetSysClock( uint8_t sysClkSel, uint8_t plli, uint8_t plliHSEDiv, uint8_t plln)
{
uint32_t ReadyTime = 0x00;
uint8_t status = 0x00;
switch(sysClkSel | plli)
{
case 0x0 :	RCC->CR |= 1;//开启HSI时钟
do
{
ReadyTime++;
}while(ReadyTime<0x1FFF && ((RCC->CR & (1<<1)) == 0));//等待HSI准备就绪并计时(计时511个指令周期)
case 0x1 | 0x2 | 0x3:
RCC->CR |= 1<<16;//开启HSE时钟
do
{
ReadyTime++;
}while(ReadyTime<0x1FFF && ((RCC->CR & (1<<17)) == 0));//等待HSE准备就绪并计时(计时511个指令周期)
break;
}
if(ReadyTime == 0x1FFF)
{
status=0x00 ;//HES时钟准备超时
}
else
{
ReadyTime = 0x00;
status = 0x01;//时钟开启成功
if(sysClkSel == (0x0 | 0x1))//选择HSI或者HSE作为系统时钟
{

}
else if(sysClkSel == 0x2)//选择PLL作为系统时钟
{
RCC->CFGR &= ~((1<<17) | (1<<16) | (0xF<<18));//清零HES分频位,PLL时钟源选择位,PLL倍频位
RCC->CFGR |= (plli<<16) | (plln<<18);//PLL输入时钟选择,PLL倍频
if(plli == 0x1)
{
RCC->CFGR |= (plliHSEDiv << 17);
}

RCC->CR |= 1<<24;//使能PLL时钟
while(((RCC->CR & (1<<25)) == 0));//等待PLL准备就绪
}
FLASH->ACR |= 1<<4;//使能外设预存储指令寄存器
FLASH->ACR &= ~(0x7);//清零FLASH LATENCY延时位
FLASH->ACR |= 0x02;//	0x0:零等待状态,当 0 < SYSCLK ≤ 24MHz
// 0x1:一个等待状态,当 24MHz < SYSCLK ≤ 48MHz
// 0x2:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
RCC->CFGR &= ~((0xF<<4)|(0x7<<8)|(0x7<<11));//AHB、APB1、APB2清零(不分频)
RCC->CFGR |= (0x4<<8);//APB1 2分频(由于APB1最高时钟为36M)
RCC->CFGR &= ~(0x3);//清零系统时钟选择位(也即选择为HSI)
RCC->CFGR |= sysClkSel;//系统时钟选择,0x0HSI,0x1HSE,0x2PLL
while(((RCC->CFGR & (0x03<<2)) != (sysClkSel<<2)));//等待系统时钟切换就绪
}
return status;
}

完整工程链接:下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: