STM32/51单片机led

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、51单片机led
  • 二、32单片机led
  • 嵌入式C程序代码对内存(RAM)中的各变量的修改操作,与对外部设备(寄存器--->对应相关管脚)的操作有哪些相同与差别?为什么51单片机的LED点灯编程要比STM32的简单?
  • 与PC平台上的一般程序不同,嵌入式C程序经常会看见 register和volatile 关键字,请解释这两个变量修饰符的作用,并用C代码示例进行说明。

一、51单片机led


    #include <reg51.h>
    #include <intrins.h>

    void delay_ms(int a)
    {
        int i,j;
        for(i=0;i<a;i++)
        {
            for(j=0;j<1000;j++) _nop_();
    
        }
    }
    
    void main(void)
    {
        while(1)
        {
            P0=0xfe;
            delay_ms(50);
            P0=0xfd;
            delay_ms(50);
            P0=0xfb;
            delay_ms(50);
            P0=0xf7;
            delay_ms(50);
            P0=0xef;
            delay_ms(50);
            P0=0xdf;
            delay_ms(50);
            P0=0xbf;
            delay_ms(50);
            P0=0x7f;
            delay_ms(50);
        }
    }
 

二、32单片机led

  #include "stm32f10x.h"
   
 
   #define LED_GPIO_PIN         GPIO_Pin_0
   #define LED_GPIO_PORT        GPIOB
   #define LED_GPIO_CLK        RCC_APB2Periph_GPIOB
      int main(void)
   {

       *(unsigned int *)0x40021018 |= (1 << 3);

       *(unsigned int *)0x40010C00 |= (1 << (4*0));

       *(unsigned int *)0x40010C0C &= ~(1 << 0);    
   }
   
   void SystemInit(void)
   {
   
   }
   

   void LED_GPIO_Config(void)
   {
      
       GPIO_InitTypeDef GPIO_InitStruct; 
       

       RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);
       

       GPIO_InitStruct.GPIO_Pin = LED_GPIO_PIN; 
       GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
       GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
  
       GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct); 
       

       GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN);

   
   }
   
   int main(void)
   {
          int main(void)
   {
   
       *(unsigned int *)0x40021018 |= (1 << 3);
 
       *(unsigned int *)0x40010C00 |= (1 << (4*0));

       *(unsigned int *)0x40010C0C &= ~(1 << 0);    
   }
   
   void SystemInit(void)
   {
  

       LED_GPIO_Config();
   }
   

三、嵌入式C程序代码对内存(RAM)中的变量修改操作和对外部设备(寄存器)的操作在某些方面相似,但也存在一些显著的差异。

相同点:

1. **寻址方式**:
   - 内存和寄存器都需要通过地址进行访问。内存中的变量也会有相应的地址,而外部设备通常会通过寄存器来访问。

2. **数据存取**:
   - 无论是内存还是寄存器,都需要读取和写入数据。这通常涉及到使用指针或者特定的寄存器操作指令。

差异点:

1. **访问速度**:
   - 内存访问速度相对较慢,而寄存器访问速度非常快,因为寄存器通常直接与CPU核心相连。

2. **中断处理**:
   - 对外部设备的操作通常会涉及中断处理程序,以响应外部事件。这在内存操作中不是一个常见的需求。

3. **特定硬件相关性**:
   - 对外部设备的操作往往会依赖于具体的硬件平台和外设。每个芯片/单片机都可能有自己独特的寄存器映射和配置方式。

4. **位级操作**:
   - 在对外设进行控制时,通常需要进行位级操作,即对寄存器的特定位进行设置或清除,以实现特定功能。这在内存中通常不会遇到。

关于为什么51单片机的LED点灯编程要比STM32简单,可能有以下一些原因:

1. **体系结构简单**:
   - 51单片机的体系结构相对简单,拥有较少的外设和寄存器,因此编程起来可能会更加直观和简单。

2. **资源限制**:
   - 51单片机通常具有更少的内存和外设,这可能会降低编程的复杂度。

3. **学习资源丰富**:
   - 由于51单片机历史悠久,因此有很多丰富的教学资源和示例代码可用,这使得学习和上手更容易。

4. **STM32更强大**:
   - STM32系列单片机通常拥有更强大的处理能力和更多的外设,因此可以实现更复杂的功能,但也会伴随着更复杂的编程。

5. **抽象层级**:
   - STM32通常使用标准库和HAL库等来提供高层次的抽象,这可以简化某些任务,但也会增加编程的复杂性。

总的来说,不同的单片机有不同的特性和优劣势,选择一个适合的单片机取决于项目的需求和开发者的经验水平。

四、register关键字用于向编译器建议将变量存储在寄存器中,以便在代码中更快地访问变量。使用register关键字并不是强制性的,编译器可以选择是否将变量存储在寄存器中。

volatile关键字用于告诉编译器,该变量的值可能会因为程序之外的因素(如硬件中断)而发生变化,因此编译器不应该对该变量进行优化操作,每次都应该从内存中读取更新的值。

以下是示例代码:

```c
#include <stdio.h>

int main() {
    register int count = 0; // 声明一个存储在寄存器中的变量
    volatile int flag = 0; // 声明一个易变的变量

    while (flag == 0) {
        count++; // 对寄存器中的变量进行操作
    }

    printf("count: %d
", count);

    return 0;
}
```

在上述示例中,变量count被声明为register,这告诉编译器将其存储在寄存器中,以便更快地进行操作。而变量flag被声明为volatile,这告诉编译器其值可能会因为程序之外的因素改变,因此编译器不应对其进行优化,而应每次都从内存中读取到最新的值。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值