提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、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,这告诉编译器其值可能会因为程序之外的因素改变,因此编译器不应对其进行优化,而应每次都从内存中读取到最新的值。