STM32单片机学习笔记(一)-点亮LED(寄存器版)(一)

写在前面:本系列内容均为自学笔记,参考资料为野火指南者开发板资料及芯片参考手册等,使用野火指南者开发板进行学习,该系列内容仅用于记录笔记,不做其他用途,笔记的内容可能会存在不准确或者错误等,如有大佬看到错误内容还望能够评论指正,感谢各位。
本节的程序,请参考野火开发板资料,里面由更加清晰的教学,野火B站账号:野火官方B站账号链接

学习目标

1、点亮一个LED灯;
2、实现LED灯的闪烁。

一、点亮一个LED灯

本次用到下方电路图,在其基础上实现点灯和灯的闪烁。
图1-1:绿色LED灯点灯电路
野火开发板点灯简略图(绿灯)
由图1-1可知,当PB0端输出低电平时,LED灯被点亮;在STM32F103的GPIO相关寄存器中有一个名为端口输出数据寄存器(GPIOx_ODR)的寄存器,可实现IO口的数据输出,由此将该寄存器第0位置零即可

图1-2:端口输出数据寄存器(截图来自官方参考手册)端口输出数据寄存器

	//设置PB0_0为低电平
	*(unsigned int*)0x40010C0C &= ~(1<<0);

上述程序即为ODR置零程序,其中*(unsigned int*)表示强制转换为(unsigned int*)型并取值,0x40010C0C表示ODR寄存器的地址,GPIOB的起始地址为0x40010C00,加上偏移地址,即为程序中的地址,&= ~(1<<0)表示将第0位置零并且不改变其他位的数据;
但以上程序不足以点亮LED灯,还需要将相应IO口置为输出状态,由于LED灯在第0位,所以需要用到端口配置低寄存器(GPIOx_CRL);
图1-3:端口配置低寄存器(截图来自官方参考手册)
在这里插入图片描述

	//设置端口为输出模式
	*(unsigned int*)0x40010C00 |= (1<<(4*0));

上述程序中,0x40010C00表示CRL寄存器的地址,由图1-3可知CRL寄存器地址偏移为0,,所以与GPIOB的起始地址相同,|= (1<<(4*0))表示,将图1-3中前4位置为0001状态,表示PB0被置为输出态且最大速度为10MHz,并且其他位的状态不受程序影响;
最后,由于STM32F103芯片在输出时需要打开使能时钟,但芯片使能时钟在正常状态下处于关闭状态,所以需要提前打开时钟,该部分需要用到RCC寄存器;
图1-4:APB2外设时钟使能寄存器(截图来自官方参考手册)
在这里插入图片描述
在这里插入图片描述
上面两图为相应使能时钟说明,RCC寄存器起始地址为0x40021000,由此可得以下程序

	//使能GPIOB时钟
	*(unsigned int*)0x40021018 |= (1<<3);

上述程序中,0x40021018表示寄存器RCC_APB2ENR的地址,|= (1<<3)表示使能GPIOB;
综上所述,得到以下程序

#include "stm32f10x.h"

int main(void)
{
	//使能GPIOB时钟
	*(unsigned int*)0x40021018 |= (1<<3);
	//设置端口为输出模式,速率为10MHz
	*(unsigned int*)0x40010C00 |= (1<<(4*0));
	//设置PB0_0为低电平
	*(unsigned int*)0x40010C0C &= ~(1<<0);
}

void SystemInit(void)
{
	//函数体为空,目的是骗过编译器
}

上述程序中,stm32f10x.h文件为空,仅作为编译通过用,函数void SystemInit(void);也时仅用于编译通过;使用上述程序可实现LED灯的常亮。

二、LED灯闪烁

构思:设定LED灯先亮一段时间,之后熄灭,在经过与之前相同时间后,LED灯再次亮起,依次循环。

#include "stm32f10x.h"

int i=0;   //设置计时变量

int main(void)
{
	//使能GPIOB时钟
	*(unsigned int*)0x40021018 |= (1<<3);
	//设置端口为输出模式,速率为10MHz
	*(unsigned int*)0x40010C00 |= (1<<(4*0));
	
	while(1)
	{
		i++;
		if(i > 500000)
			i = 0;     //计时,使LED灯能以一定的频率闪烁
		if(i<250000)
			*(unsigned int*)0x40010C0C &= ~(1<<0);
		else
			*(unsigned int*)0x40010C0C |= (1<<0);
	}
}

void SystemInit(void)
{
	//函数体为空,目的是骗过编译器
}

程序中,i的作用是计时,假设当i累加到500000时为一次循环,此时i重置为0,则当i小于250000时LED灯亮,反之则灭,将上述放到while(1)死循环中,即可实现LED灯的闪烁;当然这个功能还有更好的方法,上述程序也存在改进的空间,当学到更好的方法时会更新此贴。
以上仅作笔记参考,不作教学,感谢观看。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值