STM32学习笔记1——点亮第一盏LED灯

本文不特殊说明都以stc32F103C8为例,软件平台为KEIL5V5.15
首先这次我们用寄存器直接点亮LED灯
LED电路图如下图:

STM32学习笔记1——点亮第一盏LED灯_第1张图片

可以看出如果需要点亮一盏LED灯只需要IO口输出高电平即可,本次以GPIOB为例子。

点亮LED灯

控制IO输出高电平通常需要三步:
1.开启时钟:因为STM32为了节约消耗,故上电时候外设时钟默认不开启。故我们需要开始GPIO的时钟。
2.设置GPIO输出模式:stm32F103提供了4种输出模式和3种输出速度:
- 通用输出推挽
- 通用输出开漏
- 复用输出推挽:串口输出
- 复用输出开漏:IIC

推挽输出电路如下图:
STM32学习笔记1——点亮第一盏LED灯_第2张图片
两个三极管都是半个周期导通,轮流导通。从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。所以推挽输出可以输出高低电平,但输出幅度取决于输入,不可控。

开漏输出电路如下图:
STM32学习笔记1——点亮第一盏LED灯_第3张图片
从图中可以看出,当没有上拉电平和上拉电阻,当IN输出低电平时候,OUT输出低电平,当IN输出高电平时,OUT处于开漏状态,电平状态未知,当加上拉电阻时候,则上拉电平跟上拉电阻有关。
开漏输出相当于三极管集电极,故它只能输出低电平,需要接上拉电阻才能得到高电平。开漏是用来连接不同电平的器件。很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度 。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)
而且可以将多个开漏输出的管脚,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。

3.输出高电平

寄存器设置

1.设置时钟寄存器
首先GPIO是挂载在APB2总线上的,APB2时钟使能寄存器为RCC_APB2ENR,如下图
STM32学习笔记1——点亮第一盏LED灯_第4张图片
故只需开启GPIOB的时钟,即将RCC_APB2ENR第3位置1

2.设置IO口输出状态
有关寄存器为GPIOB_CRL和GPIOB_CRH,如下图:
STM32学习笔记1——点亮第一盏LED灯_第5张图片
可以看出只需要设置MODEx[1:0]即可,我们可将他置01,设置成中速即可,则默认为推挽输出

3设置IO口输出电平
IO电平有3个寄存器有关,分别是GPIOB_ODR,GOIOB_BSRR,和GPIOB_BRR;其中GOIOB_BSRR为置位/复位寄存器,GPIOB_BRR为复位寄存器,这两个寄存器都是间接控制GPIOB_ODR即端口数据输出寄存器,故为了初学方便,我们直接控制GPIOB_ODR寄存器。寄存器相关内容如下:
STM32学习笔记1——点亮第一盏LED灯_第6张图片
因为寄存器可以写和读,故可以直接置1即可。

注意事项:
1.需要提前设定相关总线和寄存器地址,如下表:
STM32学习笔记1——点亮第一盏LED灯_第7张图片 STM32学习笔记1——点亮第一盏LED灯_第8张图片
2.初学者为了简单,通常都操作GPIOx_ODR寄存器,但实际上我还是推荐使用GPIOx_BSRR寄存器,因为BSRR只有写操作,和ODR要经历读——写操作,时间显然慢很多,而且使用BSRR不会被中断打断。

以下附代码(灯接GPIOB_8~15)

/*定义相关寄存器地址*/
#define GPIOB_ODR            *(unsigned int *)(0x40010C00+0x0c)
#define GPIOB_CRH            *(unsigned int *)(0x40010C00+0x04)
#define RCC_APB2ENR          *(unsigned int *)(0x40021000+0x18)
/*延时函数*/
void delay(){
    unsigned long n = 30000,j;
    while(n--){
        j = 12;
        while(j--);
    }
}
int main(){
    unsigned char i;

    /*开启时钟*/
    RCC_APB2ENR |= 1<<3;

    /*配置PB8到PB15推挽输出,中速模式*/
    GPIOB_CRH |= 0x33333333;        

    while(1){
        /*闪烁两次*/
        GPIOB_ODR |= 0XFF00;
        delay();
        GPIOB_ODR &= ~0XFF00;
        delay();

        GPIOB_ODR |= 0XFF00;
        delay();
        GPIOB_ODR &= ~0XFF00;
        delay();
        GPIOB_ODR = 0x0100;
        /*流水灯*/
        for(i = 0;i<7;i++){
            GPIOB_ODR<<=1; 
            delay();
        }
        for(i = 0;i<7;i++){
            GPIOB_ODR>>=1; 
            delay();
        }

    }

}

你可能感兴趣的:(STM32)