单片机学习小组
直播中

王玉兰

7年用户 1268经验值
私信 关注

如何利用STM32F103ji寄存器的方式点亮流水灯?

如何利用STM32F103ji寄存器的方式点亮流水灯?

回帖(1)

陆英史

2022-2-8 15:49:53
一、寄存器

        寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
二、GPIO

1、GPIO口

以看出AHB总线包含RCC时钟控制,GPIO是属于APB2的。
GPIO端口B的地址从0x4001 0C00开始。接下来只寻找时钟使能寄存器的地址:
  复位和时钟控制RCC的地址从0x4002 1000开始;
  可以在6.3.7小节找到APB2外设时钟使能寄存器(RCC_APB2ENR),偏移地址是0x18,所以APB2的地址就是0x4002 1018。
  看手册RCC_APB2ENR,位3是IOPBEN,名字是IO端口B时钟使能,就是我们想要的。把RCC_APB2ENR的位3赋值为1,就是开启GPIOB时钟。
控制LED需要输出高电平或是低电平,所以需要配置为输出。
  由于STM32的每个IO都需要4个位来配置,所以一个32位的寄存器最大只能配置8个IO(32位的单片机的寄存器就是32位的)。STM32中,用端口配置低寄存器(GPIOx_CRL)来配置引脚Px0-Px7, 用端口配置高寄存器(GPIOx_CRH)来配置引脚Px8-Px15。
  配置引脚PB8,使用的寄存器是GPIOB_CRH。下面我们来寻找这个寄存器的地址。


推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
  开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
  开漏是需要外接上拉电阻才可以输出高电平的,这里并不适合。所以需要设置为推挽输出。


所以我们控制LED延时闪烁也很简单,就是控制ODR寄存器先输出1,LED灯亮,延时一段时间,控制ODR寄存器先输出0,LED灯灭,一直循环,就能实现流水灯的效果。
代码如下:


GPIOC_ODR &= ~(1<<13);//配置输出低电平0
GPIOC_ODR |= (1<<13);//配置输出高电平1


2、GPIO口的初始化:





①对于单个GPIO口的初始化如下


GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);


第二步:设置GPIOA参数:输出OR输入,工作模式,端口翻转速率
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8; //设定要操作的管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz


第三步:调用GPIOA口初始化函数,进行初始化。
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA


第四步:调用GPIO-SetBits函数,进行相应为的置位。
GPIO_SetBits(GPIOA,GPIO_Pin_0); //输出高


②对于多个GPIO口的初始化如下


GPIO_InitTypeDef GPIO_InitStructure;
第一步:使能GPIOA,GPIOE的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);


第二步:设置GPIOA,GPIOE参数:输出OR输入,工作模式,端口翻转速率
第三步:调用GPIOA口初始化函数,进行初始化。
第四步:调用GPIO-SetBits函数,进行相应为的置位。


▶把第二、三、四步合并分别设置GPIOA和GPIOE
先设置GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 第四个口,PA4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOA,&GPIO-InitST); //根据设定参数初始化GPIOA
GPIO_SetBits(GPIOA,GPIO_Pin_4); //输出高


再设置GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 第三个口,PE3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOE,&GPIO-InitST); //根据设定参数初始化GPIOE
GPIO_SetBits(GPIOE,GPIO_Pin_3); //输出高


1.配置时钟使能


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //开启 GPIOB 端口时钟


2.初始化结构体


// @file    stm32f10x_gpio.h
typedef struct
{
  uint16_t GPIO_Pin;           /*!< 选择要配置的 GPIO 引脚 */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< 选择 GPIO 引脚的速率 */

  GPIOMode_TypeDef GPIO_Mode;    /*!< 选择 GPIO 引脚的工作模式 */
}GPIO_InitTypeDef;


3.配置输入输出模式  


GPIO_InitTypeDef   GPIO_InitStruct;
   
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;              //输出模式为通用推挽输出
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 ;                     //选定输出端口为GPIO_Pin_4
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;                //输出速度为2M
   
    GPIO_Init(GPIOA,&GPIO_InitStruct);
三、点亮流水灯

1、生成hex文件
首先创建工程:


三、点亮流水灯


1、生成hex文件

首先创建工程:
在在魔法棒中设置选择生成hex文件:

编写代码:


加入延时函数:


//延时函数
void  Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}
代码如下:


main.c


/*GPIOA外设基地址*/
#define GPIOA_BASE 0x40010800
/*GPIOB外设基地址*/
#define GPIOB_BASE 0x40010C00
/*GPIOC外设基地址*/
#define GPIOC_BASE 0x40011000

/*RCC的AHB1时钟使能寄存器地址,强制转换成指针*/
#define RCC_APB2ENR        *((unsigned volatile int*)0x40021018)

/*GPIOA寄存器地址,强制转换为指针*/
#define GPIOA_CRH        *((unsigned volatile int*)0x40010804)
#define        GPIOA_ODR        *((unsigned volatile int*)0x4001080C)
/*GPIOB寄存器地址,强制转换为指针*/
#define GPIOB_CRL        *((unsigned volatile int*)0x40010C00)
#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  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}

/*主函数*/
int main()
{
        RCC_APB2ENR|=1<<2;                          /*APB2-GPIOA外设时钟使能*/
        RCC_APB2ENR|=1<<3;                          /*APB2-GPIOB外设时钟使能*/
        RCC_APB2ENR|=1<<4;                          /*APB2-GPIOC外设时钟使能*/
       
        GPIOA_CRH&=0xFFF0FFFF;                /*设置位 清零*/
        GPIOA_CRH|=0x00020000;                /*PA12推挽输出*/
        GPIOA_ODR&=1<<12;                            /*设置初始灯为亮*/
       
        GPIOB_CRL&=0xFFFFFF0F;                /*设置位 清零*/
        GPIOB_CRL|=0x00000020;                /*PB1推挽输出*/
        GPIOB_ODR|=0<<1;                            /*设置初始灯为灭*/       
       
        GPIOC_CRH&=0xF0FFFFFF;                /*设置位 清零*/
        GPIOC_CRH|=0x02000000;           /*PC14推挽输出*/
        GPIOC_ODR|=0<<14;                            /*设置初始灯为灭*/       
        while(1)
        {       
                GPIOA_ODR&= ~(1<<12);                /*PA12高电平*/
                Delay_ms(3000000);
                GPIOA_ODR|= (1<<12);                /*PA12低电平*/
                Delay_ms(3000000);
               
                GPIOB_ODR&= ~(1<<1);                /*PB1高电平*/
                Delay_ms(3000000);
                GPIOB_ODR|= (1<<1);                  /*PB1低电平*/
                Delay_ms(3000000);
               
                GPIOC_ODR&= ~(1<<14);                /*PC14高电平*/
                Delay_ms(3000000);
                GPIOC_ODR|= (1<<14);                /*PC14低电平*/
                Delay_ms(3000000);
        }
}



CH341SeSetep也安装上
打开界面如图所示:
如果 USB 转串口驱动安装成功,USB 线跟板子连接没有问题,在计算机->管理->设备管理器->端口中可识别到串口。

打开C8T6数据手册,查找TXD和RXD管脚位置
PA9——TX
PA10——RX




  • PA9——RXD
    PA10——TXD
    3.3V接电
    GND接地
  • 在FlyMcu界面勾选编程后执行,选择好读取的hex文件路径,在最下角选择RTS低电平复位,DTR高电平进BootLoader



  设置bps和烧入的hex文件之后点击开始编程,上图所示就是程序烧入成功的
3、结果


四、总结

这次的实验内容是用寄存器的GPIOA、GPIOB、GPIOC口来点亮流水灯,在这个过程中,遇到了很多的问题,首先是关于寄存器的初始化,必须要查阅stm32f103c8芯片的手册,还在其他的博客上查阅关于面包板的使用,还有就是关于实物的连接都遇到了困难,不过好在网上的资料很多,在翻阅资料的过程中,学到了很多的东西,还有对于嵌入式的了解更加深入了。




举报

更多回帖

发帖
×
20
完善资料,
赚取积分