STM32点亮LED灯

STM32点亮LED灯

一.使用寄存器点亮LED灯

新建main.c

写入以下内容

   int main(void)
   {
   	//打开GPIOB的时钟
   	*(unsigned int *)0x40021018 |= (1 << 3);
   	//配置IO口为输出
   	*(unsigned int *)0x40010C00 |= (1 << (4*0));
   	// 控制 ODR 寄存器
   	*(unsigned int *)0x40010C0C &= ~(1 << 0);	
   }
   
   void SystemInit(void)
   {
   	//函数外定义SystemInt(), 骗过编译器不报错
   }
   

将内容保存为.c文件并添加到Source group1中
在这里插入图片描述

二.使用固件点亮LED灯

新建main.c文件

写入以下内容

   #include "stm32f10x.h"
   
   //定义宏,提高程序的可移植性
   #define LED_GPIO_PIN 		GPIO_Pin_0
   #define LED_GPIO_PORT		GPIOB
   #define LED_GPIO_CLK		RCC_APB2Periph_GPIOB
   
   void LED_GPIO_Config(void)
   {
       //定义GPIO_InitTypeDef结构体
   	GPIO_InitTypeDef GPIO_InitStruct; 
   	
   	//开启时钟
   	RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);
   	
   	//端口配置
   	GPIO_InitStruct.GPIO_Pin = LED_GPIO_PIN; //配置位(I/O口)
   	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
   	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //配置输出速度
   	//GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 参数一:端口,参数二:GPIO_InitTypeDef结构体指针
   	GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct); //初始化GPIO
   	
   	//点亮LED
   	GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN);
   	//熄灭LED
   	//GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
   }
   
   int main(void)
   {
   	// 程序来到 main 函数之前,启动文件:statup_stm32f10x_hd.s 已经调用
   	// SystemInit()函数把系统时钟初始化成 72MHZ
   	// SystemInit()在 system_stm32f10x.c 中定义
   	// 如果用户想修改系统时钟,可自行编写程序修改
   	LED_GPIO_Config();
   }
   

三.使用Proteus进行仿真

1.在keil5工程目录下进行配置,点击魔法棒->output->Create HEX FILE。
在这里插入图片描述
2.打开Proteus新建工程文件,并引入LED RES 以及stm32f103R6
3.仿真点亮PB0端口上的LED灯,电路图如下
在这里插入图片描述
4.配置电网
设计->配置供电网->将未链接电网增加到网络连接到GND

在这里插入图片描述
5.双击stm32芯片,连接MDK生成的.hex文件
6.运行后成功。

问题思考

1)嵌入式c程序代码对内存(RAM)中的各变量的修改操作,与对外部设备的操作有哪些相同与差别

相同之处:

都需要采用相应的编程语言实现;
都需要使用相应的编程工具进行开发和测试;
都需要遵循相应的编程规范和标准,以确保编写出高质量、可靠、安全的代码;
都需要在程序中使用相应的数据类型、函数库等,以实现相应的功能。

差异之处:

对于内存中的变量修改操作,是直接读写内存地址的方式进行的,而对于外部设备的操作,则需要使用相应的硬件接口或协议来进行通信;

2)为什么51单片机的LED灯编程要比stm32的简单?

简单的编程风格,编程难度低,硬件资源相对简单,基础教学资料丰富。

3)与PC平台上的一般程序不同,嵌入式C程序经常会看见 register和volatile 关键字,请解释这两个变量修饰符的作用,并用C代码示例进行说明。

register关键字:
在嵌入式C程序中,register关键字用于提示编译器将变量存储在寄存器中,以便提高程序的执行效率。它用于修饰变量声明,并且不能修饰全局变量或指针类型的变量。

使用register关键字的主要目的是通过减少内存访问次数来提高代码的执行速度。由于寄存器的访问速度比内存要快得多,因此将经常使用的变量放置在寄存器中可以有效地减少对内存的访问。然而,由于寄存器的数量有限,编译器可能会忽略register关键字的请求。

示例代码:

void main() {
   register int x = 10;  // 使用register关键字修饰变量x
   
   // 对变量x进行操作
   x = x + 5;
   
   // 将变量x的值输出
   printf("x = %d", x);
}

volatile关键字:
在嵌入式C程序中,volatile关键字用于告诉编译器该变量可能会在程序执行期间发生变化,以防止编译器对这些变量进行优化。它常用于修饰与外部设备或并发任务相关的变量,以确保对其进行准确的读写操作。

使用volatile关键字后,编译器将不会对该变量的读写操作进行优化,以避免出现不可预料的结果。这是因为volatile关键字告知编译器,在每次引用该变量时都需要从内存中读取最新的值,而不使用缓存的数据。

示例代码:

volatile int sensorValue;  // 使用volatile关键字修饰变量sensorValue

void main() {
   // 从传感器中读取数值
   sensorValue = readSensor();
   
   // 检测传感器数值是否发生变化
   while (1) {
      if (sensorValue != readSensor()) {
         // 传感器数值发生变化
         printf("Sensor value changed!");
         break;
      }
   }
}

在上述代码中,由于sensorValue变量被修饰为volatile,编译器会确保每次访问该变量时都从内存中读取最新值,以便及时检测传感器数值是否发生变化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值