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

调试了好几晚上,终于编写完属于自己版本的寄存器版本,今天主要编写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;
}

完整工程链接: 下载源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值