简述:本文使用了STM32芯片在面包板上进行点灯实验,实验中我们采用了查芯片手册和使用寄存器的方法来实现我们的目的,通过寄存器实验,我们对单片机的了解会进一步加深.
一、实验准备
在开始前我们需要下载keil软件,并且确保能找到STM32库,没有的话需要下载安装。另外还要下载一份STM32F10xxx参考手册,没有的话可以在以下链接下载:百度网盘 请输入提取码。其次还要准备的器材有STM32F10系列芯片一份(我使用的STM32F103C8T6)、面包板、LED灯、导线,没有器材可以用软件Proteus仿真代替。
二、实验步骤
打开芯片手册,我们需要找到时钟配置寄存器和通用IO口寄存器相关设置。
找到APB2ENR,并且找到开启A、B、C三个端口的位。
我们写代码修改寄存器的步骤就是:找到地址 、给地址赋值,简单两步就可以调用寄存器功能,为了实现打开A、B、C三个端口的时钟,我们就需要把使能寄存器的相关位赋值为1。
我们要用到的地址如下,在参考手册中表1可以查到:
下面是如何调用时钟使能寄存器
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
RCC_APB2ENR|= (1<<2);
RCC_APB2ENR|= (1<<3);
RCC_APB2ENR|= (1<<4);//这里采用的与或运算
//也可以直接写RCC_APB2ENR=0x0000 000e
启用时钟后,我们开始准备端口的相关配置。
端口操作分两步,第一步是配置寄存器,(主要是配置启动的端口,比如A3端口,另外的目的是确定输出频率和输出方式),第二步是数据寄存器,设置输出的高低电平。
输出方式一共分4种
1、推挽输出(GPIO_Mode_Out_PP)
2、开漏输出(GPIO_Mode_Out_OD)
3、复用推挽输出(GPIO_Mode_AF_PP)
4、复用开漏输出(GPIO_Mode_AF_OD)
本次实验我们使用推挽输出。
配置寄存器:
A、B、C三种类型的端口,每种类型有16个节点(单片机上接LED灯的端口)可以让我们修改,配置低寄存器可以修改0~7,配置高寄存器可以修改8~15;
由于我们使用推挽输出,我们需要在相应的节点上把CNF改为00,输出MODE改为01
使用相应的ABC端口地址需加上偏移地址:
#define GPIOA_CRL (*(unsigned int *)0x40010800)
#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
//A、B、C三个端口的地址
GPIOA_CRL=0;
GPIOB_CRL=0;
GPIOC_CRH=0;
GPIOA_CRL|=(1<<12);
GPIOB_CRL|=(1<<0);
GPIOC_CRH|=(1<<28);
//我们分别修改了A3、B0、C15端口的输出方式
数据寄存器:
修改数据,1为高电平,0为低电平
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
//ABC三个端口的输出数据
GPIOA_ODR=0;
GPIOB_ODR=0;
GPIOC_ODR=0;
//置0时LED熄灭
GPIOA_ODR|=(1<<3);
//A3亮
GPIOB_ODR|=(1<<0);
//B0亮
GPIOC_ODR|=(1<<15);
//C15亮,另外具体怎么亮还要取决于你的小灯泡是如何接的
总代码:
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOA_CRL (*(unsigned int *)0x40010800)//a3
#define GPIOB_CRL (*(unsigned int *)0x40010C00)//b0
#define GPIOC_CRH (*(unsigned int *)0x40011004)//c15
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
void Delay_1ms(unsigned int t)
{
while(t--)
for(int i=0;i<500;i++);
}
void A_S()
{
GPIOA_ODR|=(1<<3);
GPIOB_ODR=0;
GPIOC_ODR=0;
}
void B_S()
{
GPIOB_ODR|=(1<<0);
GPIOA_ODR=0;
GPIOC_ODR=0;
}
void C_S()
{
GPIOC_ODR|=(1<<15);
GPIOA_ODR=0;
GPIOB_ODR=0;
}
int main()
{
RCC_APB2ENR|= (1<<2);
RCC_APB2ENR|= (1<<3);
RCC_APB2ENR|= (1<<4);
int j=100;
GPIOA_CRL=0;
GPIOB_CRL=0;
GPIOC_CRH=0;
GPIOA_CRL|=(1<<12);
GPIOB_CRL|=(1<<0);
GPIOC_CRH|=(1<<28);
GPIOA_ODR=0;
GPIOB_ODR=0;
GPIOC_ODR=0;
while(j)
{
A_S();
Delay_1ms(10000);
B_S();
Delay_1ms(10000);
C_S();
Delay_1ms(10000);
}
}
三、效果展示
.
面包板连接图如下:
效果展示:
四、调用开发板自带LED
由于STM32最小系统核心板焊接好一个LED我们可以直接调用,它的位置在PC13,我们准备修改代码来实现点亮它。
具体步骤和上面实验一样:
1.修改配置寄存器。
2.修改数据寄存器。
位置:
代码:
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOA_CRL (*(unsigned int *)0x40010800)//a3
#define GPIOB_CRL (*(unsigned int *)0x40010C00)//b0
#define GPIOC_CRH (*(unsigned int *)0x40011004)//c15
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
void Delay_1ms(unsigned int t)
{
while(t--)
for(int i=0;i<500;i++);
}
void A_S()
{
GPIOA_ODR|=(1<<3);
GPIOB_ODR=0;
GPIOC_ODR=0;
}
void B_S()
{
GPIOB_ODR|=(1<<0);
GPIOA_ODR=0;
GPIOC_ODR=0;
}
void C_S()
{
GPIOC_ODR|=(1<<15);
GPIOA_ODR=0;
GPIOB_ODR=0;
}
int main()
{
RCC_APB2ENR|= (1<<2);
RCC_APB2ENR|= (1<<3);
RCC_APB2ENR|= (1<<4);
int j=100;
GPIOA_CRL=0;
GPIOB_CRL=0;
GPIOC_CRH=0;
GPIOA_CRL|=(1<<12);
GPIOB_CRL|=(1<<0);
GPIOC_CRH|=(1<<28);
GPIOC_CRH|=(1<<20);
GPIOA_ODR=0;
GPIOB_ODR=0;
GPIOC_ODR=0;
while(j)
{
A_S();
GPIOC_ODR|=(1<<13);
Delay_1ms(10000);
B_S();
Delay_1ms(10000);
C_S();
Delay_1ms(10000);
}
}
实现效果: