-
本仓库相关网址:
CSDN文章地址
Gitee工程和源码地址 - https://gitee.com/langcai1943/8051-from-boot-to-application -
相关仓库:
嵌入式整体介绍,里面也描述了部分8051的内容:
才鲸嵌入式 / 嵌入式知识图谱WiKi - https://gitee.com/langcai1943/embedded-knowledge-wiki
C语言框架讲解,让你对C语言要学哪些东西有一个完整的了解:
embedded_programming_skills/ 0_doc / 02-C语言框架讲解.md - https://gitee.com/langcai1943/embedded_programming_skills/blob/develop/0_doc/02-C语言框架讲解.md
一、工程与源码介绍
1)Hello world输出
-
本工程主要演示使用Keil创建一个R8051XC2的默认工程,使用Keil自带的Boot汇编文件,然后新建一个main.c文件,写一个printf函数 + 简单的串口0驱动,并能从软件窗口上看到printf的结果。
-
创建工程的步骤略,你可以省掉这步,直接打开现有的工程。
-
工程路径:本文档同级目录/01_proj_and_src/01_Hello_world/
-
你可以直接双击打开 ./01_proj_and_src/01_Hello_world/01_Hello_world.uvproj工程
-
然后编译:点击软件上面状态栏第三排左侧两个向下小箭头的图标。看到.\Objects\01_Hello_world" - 0 Error(s)表示编译通过。
-
然后开始运行:点击软件上面状态栏第二排右侧黑色放大镜+红色“d”的小图标;如果你的软件是官网下载的未破解的评估版,会出现一个弹窗,关掉那个弹窗不管它;程序会停在main()函数的第一行,先不要继续运行。
-
输出的结果会在Keil Debug状态下的UART #1窗口中;这个窗口Keil不会主动为你打开,你需要点击在软件上面第三排图标中的小串口带一个黑色串口的图标旁边的小三角形,选中里面的UART #1,然后软件右下角就会出现UART #1窗口。
-
继续运行:点击软件左上角一个向下箭头的图标,UART #1窗口中出现了Hello world!的输出。
-
额外的知识:
- Keil输出窗口选项中,除了有UART #1、UART #2和UART #3外,还有一个Debug (Printf) Viewer窗口,这个窗口C51是用不了的,这是Keil MDK为ARM等芯片准备的,例如调试STM32时,不需要写串口驱动,而且直接写串口驱动还有点麻烦,而直接对fputc()函数进行重定向之后,能直接在这个窗口看到printf()的输出;这和在PC上直接写C语言程序有点类似,就更方便了。
-
源码:
/*******************************************************************************
* \brief 在8051工程中打印hello world
* \note 参考资料
* [keil C51 重定向printf到串口]
* (https://blog.csdn.net/Wekic/article/details/77418443)
* \note File format: UTF-8
* \author 将狼才鲸
* \date 2022-10-29
******************************************************************************/
/********************************** 头文件 ************************************/
#include <reg51.h> /* 8051通用寄存器 */
#include <stdio.h> /* printf */
/******************************** 接口函数 ************************************/
/**
* \brief printf重定向的函数,这里重定向到串口0
* \param[in] c 承接printf中传入的一个字符
* \note 这里的函数注释格式是Doxygen,有兴趣的可以自行去了解
* \return 正常时返回c,错误时返回错误码
*/
char putchar(char c)
{
/* 空格和行尾注释使用Linux风格 */
ES = 0; /* 关串口中断 */
SBUF = c;
while (TI != 1); /* 等待发送成功 */
TI = 0; /* 清除发送中断标志 */
ES = 1; /* 开串口中断 */
return c;
}
/**
* \brief 程序C语言的入口,程序最开始的入口在汇编文件中
* \details 为什么main()函数后面的括号里面是空的,而没有写void?
* 因为main函数的实际格式是int main(int argc, char *argv[]),
* 而因为没有操作系统的嵌入式程序中都不会传入参数,所以把这个参数省略了,
* 8051的话,你在参数里写上void也是不会报错的,但有操作系统时会报错
*/
int main()
{
/* 这里省掉了串口0的初始化,仿真运行时默认是已经配好的 */
printf("Hello world!\n");
while(1); // 不加上死循环的话,程序执行完会默认上电重新执行,循环执行main()函数,导致输出窗口刷屏
//return 0;
}
/********************************** 文件尾 ************************************/