STM32F103的LED亮灭之版本1(寄存器地址版)

一. 实验目的

1、了解STM32f103c8t6最小核心板的主要引脚接口;

2、掌握Keil 开发stm32程序的环境搭建和设置;

3、使用GPIO引脚,外接LED灯,编写程序让LED灯周期性亮灭。

二、了解STM32最小系统核心板(STM32F103C8T6,国际上称为 STM32 Blue Bill开发板) 的电路原理图,用Proteus 设计一个STM32最小系统板+LED流水灯实验原理图,仿真运行

STM32最小系统板原理图如图所示:

STM32最小系统板在Proteus仿真软件中电路原理如图所示:

在Proteu仿真软件中利用STM32最小系统板的PA4、PB9和PC13设计LED流水灯,演示如图所示:(这里我在Proteus中未找到STM32F103C8T6原件,所以直接在开发上使用)

三、 STM32最小系统核心板(STM32F103C8T6)+面板板+3只_(或更多)红绿蓝LED 搭建电路,使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长1秒

3.1、开启GPIO口时钟

RCC时钟控制的起始地址为0x4002 1000,APB2外设时钟使能寄存器(RCC_APB2ENR)的偏移地址为0x18,所以APB2外设时钟使能寄存器(RCC_APB2ENR)的起始地址为0x4002 1000+0x18=0x4002 1018。当位2、3和4都为1时,开启GPIOA、GPIOB和GPIOC口时钟。所以开启GPIOA、GPIOB和GPIOC口时钟代码如下:

#define RCC_APB2ENR (*(unsigned int *)0x40021018)
​
// 打开时钟
RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟
RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟

3.2、初始化GPIO(选择推挽输出)

端口配置低寄存器(GPIOA_CRL、GPIOB_CRL、GPIOC_CRL,以GPIOA_CRL为例,注意起始地址)代码如下:

#define GPIOA_CRL (*(unsigned int *)0x40010800)
​
// 最后四位变为0001
GPIOA_CRL |= (1<<0);  // 最后一位变1
GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0

端口配置高寄存器(GPIOA_CRH、GPIOB_CRH、GPIOC_CRH,以GPIOA_CRH为例)代码如下:

#define GPIOA_CRH (*(unsigned int *)0x40010804)
​
// 最后四位变为0001
GPIOA_CRL |= (1<<0);  // 最后一位变1
GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0

初始化GPIO口的A4,B10,C15

// 设置 GPIO 为推挽输出
GPIOB_CRH&= 0xffffff0f; //设置位 清零        
GPIOB_CRH|=0x00000020;  //PB9推挽输出
 
GPIOC_CRH &= 0xff0fffff; //设置位 清零       
GPIOC_CRH|=0x00300000;  //PC15推挽输出


GPIOA_CRL &= 0xfff0ffff; //设置位 清零       
GPIOA_CRL|=0x00010000; //PA4推挽输出
 
// 3个LED初始化为不亮(即高点位)
GPIOB_ODR |= (1<<9); 
GPIOC_ODR |= (1<<13); 
GPIOA_ODR |= (1<<4); 

3.3、设置延时函数

延时函数代码如下:

void Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}

3.4、在开发板上实现

完整代码如下:

#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800
​
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
 
#define GPIOB_CRH (*(unsigned int *)0x40010C04)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)
 
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
    
 
 
void SystemInit(void);
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<800;i++);
}
 
void A_LED_LIGHT(){
    GPIOA_ODR=0x0<<4;       //PA4低电平
    GPIOB_ODR=0x1<<9;       //PB9高电平
    GPIOC_ODR=0x1<<13;      //PC13高电平
}
void B_LED_LIGHT(){
    GPIOA_ODR=0x1<<4;       //PA4高电平
    GPIOB_ODR=0x0<<9;       //PB9低电平
    GPIOC_ODR=0x1<<13;      //PC13高电平
}
void C_LED_LIGHT(){
    GPIOA_ODR=0x1<<4;       //PA4高电平
    GPIOB_ODR=0x1<<9;       //PB9高电平
    GPIOC_ODR=0x0<<13;      //PC13低电平   
}
 
int main(){
    int j=100;
    // 开启时钟
    RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    
    
    // 设置 GPIO 为推挽输出
    GPIOB_CRH&= 0xffffff0f; //设置位 清零        
    GPIOB_CRH|=0x00000020;  //PB9推挽输出
 
    GPIOC_CRH &= 0xff0fffff; //设置位 清零       
    GPIOC_CRH|=0x00300000;  //PC15推挽输出
 
 
    GPIOA_CRL &= 0xfff0ffff; //设置位 清零       
    GPIOA_CRL|=0x00010000; //PA4推挽输出
 
    // 3个LED初始化为不亮(即高点位)
    GPIOB_ODR |= (1<<9); 
    GPIOC_ODR |= (1<<13); 
    GPIOA_ODR |= (1<<4);  
    
    while(j){
        
        B_LED_LIGHT();
        Delay_ms(2000);//单片机上2000    100
 
        C_LED_LIGHT();
        Delay_ms(3000);//单片机上3000    200
 
        A_LED_LIGHT();
        Delay_ms(3000);//单片机上3000    200
    }
    
}
 
 
void SystemInit(){
    
}

演示如图所示:

3.5、将PC13应用于流水灯中,演示如图所示:

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103C8T6是一款常用的单片机,它具有丰富的外设和强大的性能。要实现定时一分钟LED亮灭的功能,可以使用定时器和GPIO控制。 首先,需要配置一个定时器来实现定时功能。可以选择TIM2或TIM3定时器,它们都具有足够的功能和灵活性。以下是实现步骤: 1. 配置定时器的时钟源和预分频系数,使得定时器的时钟频率为1MHz(假设系统时钟为72MHz)。 2. 设置定时器的自动重装载寄存器(ARR)为60000,这样定时器将在1分钟后溢出。 3. 使能定时器的更新中断,并设置优先级。 4. 启动定时器。 接下来,需要配置一个GPIO引脚来控制LED亮灭。假设LED连接在GPIOA的第5个引脚上。 1. 配置GPIOA的时钟使能。 2. 配置GPIOA的第5个引脚为推挽输出模式。 3. 设置GPIOA的第5个引脚输出高电平,使LED熄灭。 最后,在定时器的更新中断处理函数中,每次定时器溢出时,切换LED的状态,即将GPIOA的第5个引脚输出电平取反。 下面是相关代码示例: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { GPIOA->ODR ^= GPIO_Pin_5; // 切换LED状态 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位 } } int main(void) { // 配置定时器 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 60000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); // 配置LED引脚 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_5); while (1) { // 主循环中可以进行其他操作 } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值