STM32/51单片机编程入门(点亮LED)
任务要求
1. 安装并熟悉Proteus 电路仿真软件,完成一个C51程序设计和仿真
2. 安装mdk5软件和stm32包,熟悉mdk开发环境,完成一个stm32的简单的通过寄存器方式,用某一个GPIO端口点亮LED等程序。安装过程、示例程序可以参考网上代码(注意:没有stm32开发板硬件之前,可只做程序的编译和仿真测试)
3. (理论概念-常见嵌入式岗位面试题) 通过以上实践,结合阅读ARM、STM32技术手册,深入思考STM32F103系列芯片的地址映射和寄存器映射原理,GPIO端口的初始化设置的一般步骤。回答:1)嵌入式C程序代码对内存(RAM)中的各变量的修改操作,与对外部设备(寄存器--->对应相关管脚)的操作有哪些相同与差别?2)为什么51单片机的LED点灯编程要比STM32的简单?
4. (理论概念-常见嵌入式岗位面试题) 与PC平台上的一般程序不同,嵌入式C程序经常会看见 register和volatile 关键字,请解释这两个变量修饰符的作用,并用C代码示例进行说明。
实验内容
任务1
完成一个C51程序设计和仿真
步骤1
安装Proteus
引用https://blog.csdn.net/ssj925319/article/details/108929227
下面来了解下如何安装Proteus软件,安装过程也十分简单。
首先需要下载Proteus的压缩包,链接如下。
链接:https://pan.baidu.com/s/1eURfI-nSSXHQfL1cgaSdKg
提取码:lse6
步骤2使用Proteus
创建工程
步骤3绘制原理图
步骤4编写51程序
//51单片机编程常用的头文件
#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);
}
}
步骤5将生成的hex文件加入protues仿真中去
步骤6仿真结果
任务2完成一个stm32的简单的通过寄存器方式,用某一个GPIO端口点亮LED
安装及使用参考教程
https://www.bilibili.com/video/BV1th411z7sn?p=4&vd_source=07ac35c902c946868feed868ebe4291d
步骤1安装keil并配置相关环境
步骤2初始化引脚
步骤3下载并测试
步骤4实验结果
任务3
1)嵌入式 C 程序代码对内存 (RAM) 中的各变量的修改操作,与对外部设备(寄存器--->对应相关管脚)的操作有以下相同与差别:
相同点:
a. 都是通过指令来完成,如数据传输指令、算术指令等。
b. 都需要考虑数据类型和数据宽度,如整型、浮点型等。
c. 都需要考虑访问权限,如只读、读写等。
差别:
a. 对内存中的变量操作,直接通过地址访问,而对外部设备操作需要通过寄存器间接访问。
b. 对内存中的变量操作,可以直接通过指针访问,而对外部设备操作通常需要通过特定的寄存器进行访问。
c. 对内存中的变量操作,通常不需要考虑时序问题,而对外部设备操作需要考虑时序,如读写操作的时序、锁存器等。
2)51 单片机的 LED 点灯编程比 STM32 的简单,主要原因有以下几点:
a. 51 单片机只有几个外部中断引脚,而 STM32 有丰富的外设引脚,如 USART、SPI、I2C 等,因此 STM32 的 GPIO 配置相对复杂。
b. 51 单片机的 GPIO 端口配置相对简单,通常只需配置方向寄存器和速度寄存器,而 STM32 的 GPIO 端口配置需要考虑更多的参数,如复用功能、时钟源等。
c. 51 单片机的 LED 驱动通常只需配置一个方向寄存器,即可实现点亮或熄灭,而 STM32 需要配置多个寄存器,如方向寄存器、速度寄存器、复用寄存器等。
d. 51 单片机的程序结构相对简单,而 STM32 的程序结构更复杂,需要处理更多的中断、任务等。
任务4
在嵌入式 C 程序中,register 和 volatile 是两个常用的变量修饰符,它们在 PC 平台上一般不常用。下面分别介绍这两个关键字的作用及使用示例:
- register 关键字:
register 关键字用于声明寄存器变量。在嵌入式系统中,由于存储空间有限,寄存器是一种较为常用的存储方式。使用 register 关键字可以告诉编译器该变量应该存储在寄存器中,而不是内存中。这样可以节省存储空间,同时提高程序的运行速度。
使用示例:
c复制代码
register int counter;
- volatile 关键字:
volatile 关键字用于声明易变(易被修改)的变量。在嵌入式系统中,有些变量的值可能会被其他程序或硬件设备实时修改,例如中断服务程序(ISR)或硬件设备驱动。使用 volatile 关键字可以确保编译器不会对这类变量进行优化,从而确保程序能够正确地读取到这些变量的最新值。
使用示例:
c复制代码
volatile int button_state;
这里是一个简单的嵌入式 C 程序,使用了 register 和 volatile 关键字:
c复制代码
#include <avr/io.h> #include <util/delay.h> register int counter = 0; volatile int button_state = 0; void isr_button_click() { button_state = 1; } int main() { DDRD |= (1 << PD2); // 设置 PD2 为输入 PORTD |= (1 << PD2); // 初始化 PD2 为高电平 while (1) { if (button_state) { counter++; _delay_ms(100); button_state = 0; } } }
在这个程序中,我们使用了 register 关键字声明了计数器变量 counter,使用 volatile 关键字声明了按键状态变量 button_state。计数器变量 counter 存储在寄存器中,以节省存储空间;按键状态变量 button_state 使用了 volatile 关键字,以确保在 ISR 中修改它的值时,主程序能够立即看到修改后的结果
CSDN-Ada助手: 非常感谢您分享关于嵌入式RTOS多任务程序设计的博客!恭喜您完成了第11篇博客,这是一个了不起的成就。您的文章内容非常有深度,对于嵌入式RTOS多任务程序设计这个话题进行了详尽的探讨。我真的很欣赏您在这个领域的专业知识。 在下一步的创作中,我建议您可以进一步探索嵌入式RTOS多任务程序设计中的实践案例。通过展示一些实际应用中的解决方案和技巧,您的读者可以更好地理解和应用这些概念。此外,您还可以考虑与其他领域的技术结合,例如物联网或人工智能,以探索更广阔的应用领域。 再次恭喜您的持续创作,期待您未来更多精彩的博客文章!
CSDN-Ada助手: 这是一篇很棒的博客,对于嵌入式系统编程入门非常有帮助。希望作者能够继续分享更多关于STM32/51单片机编程的内容,让更多初学者受益。 除了点亮LED,或许可以扩展一些其他常见的操作,比如按键输入、数码管显示等,这些也是初学者非常关心的内容。另外,可以介绍一些关于中断、定时器的知识,这些对于单片机编程也非常重要。期待作者继续分享更多深入的内容,相信会对读者有很大帮助的。 如何写出更高质量的博客,请看该博主的分享:https://blog.csdn.net/lmy_520/article/details/128686434?utm_source=csdn_ai_ada_blog_reply2
CSDN-Ada助手: 恭喜您在博客中分享了关于STM32F103的RTC原理和OLED屏显模块的应用,这对于学习嵌入式系统的朋友们来说非常有帮助。希望您能继续分享更多关于STM32F103的应用案例,比如如何利用RTC实现定时功能,或者如何通过SPI或IIC接口控制其他外设模块。期待您的下一篇精彩内容!
CSDN-Ada助手: 恭喜您在第10周实验中成功实现了IIC协议读取温湿度数据!这篇博客内容很实用,也让我对IIC协议有了更深入的了解。希望您能继续分享更多关于实验的经验和心得,也可以考虑加入一些实际应用场景或者对于未来研究方向的思考,这样会更加丰富您的博客内容。期待您的下一篇作品!
CSDN-Ada助手: 恭喜您写了第9篇博客,标题为“stm32+(4SPI)OLED显示数据”。您的持续创作真是令人钦佩!对于这篇博客,您详细介绍了如何使用stm32和4SPI OLED显示数据,为读者提供了有价值的技术知识。接下来,我建议您可以考虑探讨更多有关stm32和OLED的主题,或是进一步深入解析这个主题的其他方面。您的内容一直都非常有趣和富有教育性,我相信您的下一篇博客也会给读者带来新的启发和帮助。期待您的下一步创作!