STM32F103C8T6寄存器方式实现LED流水灯

一、设计思路

需要在 STM32F103C8T6 上面通过 初始化GPIO 来实现点亮 LED 灯。 外设实现的功能可能是完全不同的,但是,多数情况下,我们在设计程序的时候不需要考虑外设具体如何怎样实现功能,只需要给外设接在哪里、高电平有效还是低电平有效。因此,完成题目要求的时候,只需要找到 GPIOA-5、GPIOB-9、GPIOC-14 的地址,然后通过 GPIO的初始化,控制寄存器将片外引脚(我们称之为 IO口)拉低拉高, 输出高低电平,以控制LED亮灭。

点灯是所有学单片机的人都应该学会的一项技能。C51单片机和 stm32 点灯类似。

51单片机的点灯是,通过控制寄存器将片外引脚(我们称之为IO口)拉低拉高,输出高低电平,以控制LED亮灭。 其过程:单片机给指令->控制寄存器->给IO口电平->控制LED亮灭 stm32的点灯则是,通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,让其实现各种功能。其过程:CPU给指令->GPIO收到指令->配置内部寄存器->配置IO口模式(注意是模式)->控制LED亮灭 STM32开发板中包含较多寄存器,实现流水灯操作,需要对相应的引脚进行操作,对相应的引脚进行时钟配置、输入输出模式设置、最大速率设置。 于是利用 STM32F103C8T6 实现流水灯,要经过以下步骤:

时钟配置 输入输出模式设置 最大速率设置 烧录程序 运行

二、寄存器地址和参数

1、时钟配置

  • 找到时钟使能寄存器映射基地址

    找到端口偏移地址以及对应端口所在位置

    • 外设时钟使能寄存器,偏移量为0x18,起始地址0x4002 1000,该寄存器地址为0x4002 1018

    • 使能对应端口时钟 查询数据手册可发现,外设时钟使能寄存器,设偏移量为0x18,起始地址0x4002 1000,该寄存器地址为0x4002 1018

      #define RCC_AP2ENR  *((unsigned volatile int*)0x40021018) #时钟使能寄存器

      手册RCC_APB2ENR,位3是IOPBEN,名字是IO端口B时钟使能,就是我们想要的。把RCC_APB2ENR的位3赋值为1,就是开启GPIOB时钟

      RCC->APB2ENR|=1<<2;         //APB2-GPIOA外设时钟使能
      RCC->APB2ENR|=1<<3;         //APB2-GPIOB外设时钟使能  
      RCC->APB2ENR|=1<<4;         //APB2-GPIOC外设时钟使能
      //这两行代码可以合为 RCC_APB2ENR|=1<<3|1<<4;

      2、输入输出模式设置、最大速率设置

      本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上三个引脚。其中A4属于端口配置低寄存器偏移地址为0x00,B9、C14属于端口配置高寄存器偏移地址为0x04。

      找到GPIOx端口基地址

      • 配置对应引脚寄存器,基地址+偏移量 故而配置如下:
        //----------------GPIOA配置寄存器 -----------------------
        #define GPIOA_CRL       *((unsigned volatile int*)0x40010800)
        //----------------GPIOB配置寄存器 -----------------------
        #define GPIOB_CRH       *((unsigned volatile int*)0x40010C04)
        //----------------GPIOC配置寄存器 -----------------------
        #define GPIOC_CRH       *((unsigned volatile int*)0x40011004)

        设置输出模式为推挽输出,输出速度为2Mhz 例:将GPIOB-9配置成推挽输出模式,且最大速度为2MHz 首先,其为GPIOB9端口,其属于端口配置高寄存器模块,则由上图可知,CNF9和MODE9位为0,其余位为F,即:GPIOB_CRH&=0xFFFFFF0F;又因其为推挽输出模式,且最大速度为2MHz,所以4位寄存器的配置就是CNF9【00】MODE9【10】,0010换成十进制数就是2,即:GPIOB_CRH|=0x00000020

        GPIOA_CRL&=0xFFF0FFFF;      //设置位清零 
        GPIOA_CRL|=0X00200000;      //PA5推挽输出,把第23、22、21、20位变为0010
        GPIOA->ODR|=1<<5;           //设置PA5初始灯为灭
            
        GPIOB_CRH&=0xFF0FFFFF;      //设置位清零 
        GPIOB_CRH|=0x00000020;      //PB9推挽输出,把第7、6、5、4变为0010
        GPIOB->ODR|=0x1<<9;         //设置初始灯为灭
             
        GPIOC_CRH&=0xFF0FFFFF;      //设置位清零 
        GPIOC_CRH|=0x02000000;      //PC14推挽输出,把第27、26、25、24变为0010
        GPIOC->ODR|=0x1<<14;            //设置初始灯为灭   

三、代码实现

新建LED文件夹 —> 点击 Project 下的 New uVision Project —> 输入文件名 LED

选择 STM32F103C8

将启动文件拷贝到 LED 工程文件夹下:

点击 Target1→Source Group1→双击→设置打开文件类型为 Asm Source file→选择 startup_stm32f10x_md.s→点击 Add,如下图所示:

在界面左侧的 Project 栏,打开 Target1,鼠标右键单击 Source Group1, 选择 Add New Item to Group ‘Source Group 1’…添加main.c文件

​
//--------------APB2使能时钟寄存器------------------------
#define RCC_APB2ENR     *((unsigned volatile int*)0x40021018)
​
//----------------GPIOA配置寄存器 ------------------------
#define GPIOA_CRL       *((unsigned volatile int*)0x40010800)
#define GPIOA_ODR       *((unsigned volatile int*)0x4001080C)
    
//----------------GPIOB配置寄存器 ------------------------
#define GPIOB_CRH       *((unsigned volatile int*)0x40010C04)
#define GPIOB_ODR       *((unsigned volatile int*)0x40010C0C)
    
//----------------GPIOC配置寄存器 ------------------------
#define GPIOC_CRH       *((unsigned volatile int*)0x40011004)
#define GPIOC_ODR       *((unsigned volatile int*)0x4001100C)
​
//函数声明
void Delay_ms(volatile  unsigned  int);
void A_LED_LIGHT(void);
void B_LED_LIGHT(void);
void C_LED_LIGHT(void);
​
//时延函数
void Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<10000;i++);
}
​
//控制灯亮灭
void A_LED_LIGHT()
    {
    GPIOA_ODR=0x0<<5;       //PA5低电平
    GPIOB_ODR=0x1<<9;       //PB9高电平
    GPIOC_ODR=0x1<<14;      //PC14高电平   
}
void B_LED_LIGHT()
    {
    GPIOA_ODR=0x1<<5;       //PA5高电平
    GPIOB_ODR=0x0<<9;       //PB9低电平
    GPIOC_ODR=0x1<<14;      //PC14高电平
}
void C_LED_LIGHT()
    {
    GPIOA_ODR=0x1<<5;       //PA5高电平
    GPIOB_ODR=0x1<<9;       //PB9高电平
    GPIOC_ODR=0x0<<14;      //PC14低电平
}
​
//------------------------主函数--------------------------
int main(){
​
    RCC_APB2ENR|=1<<2;          //APB2-GPIOA外设时钟使能
    RCC_APB2ENR|=1<<3;          //APB2-GPIOB外设时钟使能  
    RCC_APB2ENR|=1<<4;          //APB2-GPIOC外设时钟使能
//也可以写成 RCC_APB2ENR|=1<<3|1<<4;
    
​
  GPIOA_CRL&=0xFFF0FFFF;        //设置位清零 
  GPIOA_CRL|=0X00200000;        //PA5推挽输出,把第23、22、21、20位变为0010
    
  GPIOB_CRH&=0xFF0FFFFF;        //设置位清零 
  GPIOB_CRH|=0x00000020;        //PB9推挽输出,把第7、6、5、4变为0010
     
  GPIOC_CRH&=0xFF0FFFFF;        //设置位清零 
  GPIOC_CRH|=0x02000000;        //PC14推挽输出,把第27、26、25、24变为0010
​
    GPIOA_ODR |= (1<<5);  
    GPIOB_ODR |= (1<<9);      //设置灯的初始状态为灭
    GPIOC_ODR |= (1<<14); 
    
    while(1)
        {
          A_LED_LIGHT();
          Delay_ms(60);
          B_LED_LIGHT();
          Delay_ms(60);
          C_LED_LIGHT();
          Delay_ms(60);
    }
​
}

打开魔术棒,如下图所示勾选 Create HEX File

硬件连接

实验结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值