《嵌入式C语言》C语言介绍及环境搭建

article/2025/8/22 19:21:39
                                                   --最具价值的嵌入式C语言

1 C语言简介

C语言是国际上广泛流行的高级语言,是在B语言的基础上发展起来的, 1970年, 美国贝尔实验室的D.M.Ritchie设计了B 语言, 并用于编写了第一个UNIX操作系统。 1973年, D.M.Ritchie 在B语言的基础上设计出了C语言, 对B取长补短, 并用之改写了原来的UNIX。
• 1983年-1987年,美国国家标准化协会(ANSI)根据C语言各种版本对C做了发展和扩充,制定了新的标准并发布ANSI C 。

##1.1什么是ANSI C、ISO C、C89、C90标准?
随着C语言使用得越来越广泛,出现了许多新问题,人们日益强烈地要求对C语言进行标准化。1983年,美国国家标准协会(ANSI)组成了一个委员会,为了创立 C 的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,这个版本的语言经常被称作ANSI C,或有时称为C89(为了区别C99)。在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会(ANSI)采纳为ISO/IEC 9899:1990。这个版本有时候称为C90或者ISO C。综上,ANSI C、ISO C、C89、C90其实是同一种标准。

什么是C99标准?

2000年3月,ANSI 采纳了 ISO/IEC 9899:1999 标准。这个标准通常指C99。 C99新增了一些特性,如:支持不定长的数组,即数组长度可以在运行时决定。变量声明不必放在语句块的开头,for语句提倡写成for(int i=0;i<100;++i) 的形式,即i只在for语句块内部有效。

#include <stdio.h>int main(void)
{// C99允许在for循环内定义循环变量,而C89不允许for (int i = 0; i < 5; i++)    {printf("hello world!\n");}return 0;
}

在C89标准下编译,结果为:

F:\A_work\C_Base\C_V3_code\CProject_Test\c99.c|6|note: (this will be reported only once per input file)|
F:\7|error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode|
F:\7|note: use option ‘-std=c99’, ‘-std=gnu99’, ‘-std=c11’ or ‘-std=gnu11’ to compile your code|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

编译报错原因为,在C89标准下,循环变量不能在for循环内定义,必须把标准改为C99标准。

2 两种计算机体系结构

2.1 冯.诺依曼结构

程序指令存储和数据存储合并在一起的存储器结构。
以复杂指令集(CISC)为代表。
命令字长短不一流水线容易出现阻塞停滞。
程序指令和数据的宽度相同机器字长。
通常采用小端字节序(little-endian)即低字节放在低地址。
如英特尔的x86系列、MIPS公司的MIPS处理器。
在这里插入图片描述

2.2 哈佛结构

程序存储与数据存储有单独的存储器。
精简指令集(RISC)为代表。
通常有大量内部存储设备避免存储恢复操作。
采用大端字节序(big-endian)即低字节放在高地址。
采用其他RISC技术。
在这里插入图片描述

哈佛体系结构
采用短指令机构通畅的流水线。
采用硬解码复杂指令集通常采用以可编程的控制存储器为核心控制逻辑部件速度更快。
如单片机51、Microchip 的PIC、ARM7、ARM9、ARM10、ARM11、摩托罗拉 的MC68的Z8处理器。

2.3 端模式介绍

端模式Endian的这个词出自书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big-Endian,从尖头开始将鸡蛋敲开的人被归为Littile-Endian。小人国的内战就源于吃鸡蛋时是究竟从大头Big-Endian敲开还是从小头Little-Endian敲开。
在计算机业Big Endian和Little Endian也几乎引起一场战争。在计算机业界Endian表示数据在存储器中的存放方式。

3 怎么理解程序及程序的运行过程

在这里插入图片描述

在这里插入图片描述

3.1 嵌入式C程序启动流程

a.上电初始化
1从CPU复位时的指定地址开始执行 
2跳转至汇编代码startup处执行 
3跳转至用户主程序main执行。
在main( )中完成
b.初试化各硬件设备
c.初始化各软件模块
d.进入死循环调用各模块的处理函数
下面是几个“著名”的死循环
1操作系统是死循环
2WIN32程序是死循环
3嵌入式系统软件是死循环
4多线程程序的线程处理函数是死循环。

永远的C语言

C语言有人叫它中间语言是介于汇编语言与高级语言之间的编程工具。它的运行速度在高级语言中是最快的据说只比汇编语言慢10%, 在嵌入式世界中除了汇编语言就是C语言。在8位机的控制系统(比如51单片机)中就是用C语言开发的。在嵌入式开发中C语言具有绝对优势。

运行效率高效,大部分嵌入式产品要求具有实时性C的运行速度的优势给实时现场控制提供可能。
数据结构丰富、运算操作丰富、结构化、功能强大。

3.2 简单的C程序介绍

为了说明C语言源程序结构的特点,先看以下几个程序。这几个程序由简到难,表现了
C语言源程序在组成结构上的特点。 虽然有关内容还未介绍, 但可从这些例子中了解到组成
一个 C 源程序的基本部分和书写格式。
【例 1.1】

void main()
{printf("Hello world!\n");
}

main 是主函数的函数名,表示这是一个主函数。
每一个 C 源程序都必须有,且只能有一个主函数(main 函数)。
函数调用语句, printf 函数的功能是把要输出的内容送到显示器去显示。
printf 函数是一个由系统定义的标准函数,可在程序中直接调用。
【例 1.2】

#include<math.h>
#include<stdio.h>
void main()
{double x,s;printf("input number:\n");scanf("%lf",&x);s=sin(x);printf("sine of %lf is %lf\n",x,s);
}

•include 称为文件包含命令
•扩展名为.h 的文件称为头文件
•定义两个实数变量,以被后面程序使用
•显示提示信息
•从键盘获得一个实数 x
•求 x 的正弦,并把它赋给变量 s
•显示程序运算结果
•main 函数结束
程序的功能是从键盘输入一个数 x,求 x 的正弦值,然后输出结果。 在 main()之前的两行称为预处理命令(详见后面)。 预处理命令还有其它几种,这里的 include 称为文件包含命令,其意义是把尖括号<>或引号""内指定的文件包含到本程序来,成为本程序的一部分。 被包含的文件通常是由系统提供的,其扩展名为.h。因此也称为头文件或首部文件。C语言的头文件中包括了各个标准库函数的函数原型。因此,凡是在程序中调用一个库函数时,都必须包含该函数原型所在的头文件。在本例中,使用了三个库函数:输入函数 scanf,正弦函数 sin,输出函数 printf。 sin 函数是数学函数,其头文件为 math.h 文件,因此在程序的主函数前用 include 命令包含了 math.h。 scanf 和 printf 是标准输入输出函数,其头文件为 stdio.h,
在主函数前也用 include 命令包含了 stdio.h 文件。
需要说明的是, C 语言规定对 scanf 和 printf 这两个函数可以省去对其头文件的包含命令。所以在本例中也可以删去第二行的包含命令#include<stdio.h>。在例题中的主函数体中又分为两部分,一部分为说明部分,另一部为分执行部分。说明是指变量的类型说明。例题 1.1 中未使用任何变量,因此无说明部分。C语言规定,源程序中所有用到的变量都必须先说明,后使用,否则将会出错。

	本例中使用了两个变量 x, s,用来表示输入的自变量和 sin 函数值。由于 sin 函数要求这两个量必须是双精度浮点型,故用类型说明符 double 来说明这两个变量。说明部分后的四行为执行部分或称为执行语句部分, 用以完成程序的功能。 执行部分的第一行是输出语句,调用 printf 函数在显示器上输出提示字符串,请操作人员输入自变量 x 的值。第二行为输入语句,调用 scanf 函数,接受键盘上输入的数并存入变量 x 中。第三行是调用 sin 函数并把函数值送到变量 s 中。第四行是用 printf 函数输出变量 s 的值,即 x 的正弦值。程序结束。运行本程序时,首先在显示器屏幕上给出提示串 input number,这是由执行部分的第一行完成的。用户在提示下从键盘上键入某一数,如 5,按下回车键,接着在屏幕上给出计算结果。

3.3 输入和输出函数

在前两个例子中用到了输入和输出函数 scanf 和 printf,在以后要详细介绍。这里我们
先简单介绍一下它们的格式,以便下面使用。
scanf 和 printf 这两个函数分别称为格式输入函数和格式输出函数。其意义是按指定的格式输入输出值。因此,这两个函数在括号中的参数表都由以下两部分组成:
“格式控制串” ,参数表
格式控制串是一个字符串,必须用双引号括起来,它表示了输入输出量的数据类型。 各
种类型的格式表示法可参阅第三章。 在 printf 函数中还可以在格式控制串内出现非格式控制字符,这时在显示屏幕上将原文照印。参数表中给出了输入或输出的量。当有多个量时, 用
逗号间隔。例如:
printf(“sine of %lf is %lf\n”,x,s);
其中%lf 为格式字符,表示按双精度浮点数处理。它在格式串中两次现,对应了 x 和 s 两个变量。 其余字符为非格式字符则照原样输出在屏幕上。
【例 1.3】

int max(int a,int b); /*函数说明*/
main() /*主函数*/
{int x,y,z; /*变量说明*/int max(int a,int b); printf("input two numbers:\n");scanf("%d%d",&x,&y);  /*输入 x,y 值*/z=max(x,y);            /*调用 max 函数*/printf("maxmum=%d",z); /*输出*/}int max(int a,int b) /*定义 max 函数*/{if(a>b){return a;}else{return b; /*把结果返回主调函数*/} 
}

上面例中程序的功能是由用户输入两个整数, 程序执行后输出其中较大的数。 本程序由两个函数组成,主函数和 max 函数。函数之间是并列关系。可从主函数中调用其它函数。max 函数的功能是比较两个数,然后把较大的数返回给主函数。 max 函数是一个用户自定义函数。因此在主函数中要给出说明(程序第三行)。可见,在程序的说明部分中,不仅可以有变量说明,还可以有函数说明。关于函数的详细内容将在以后第五章介绍。在程序的每行后用//括起来的内容为注释部分,程序不执行注释部分。
上例中程序的执行过程是,首先在屏幕上显示提示串,请用户输入两个数,回车后由
scanf 函数语句接收这两个数送入变量 x,y 中, 然后调用 max 函数, 并把 x,y 的值传送给 max函数的参数 a,b。在 max 函数中比较 a,b 的大小,把大者返回给主函数的变量 z,最后在屏幕上输出 z 的值。

3.4 C源程序的结构特点

1.一个C语言源程序可以由一个或多个源文件组成。
2.每个源文件可由一个或多个函数组成。
3.一个源程序不论由多少个文件组成,都有一个且只能有一个 main 函数,即主函数。
4.源程序中可以有预处理命令(include 命令仅为其中的一种), 预处理命令通常应放在源
文件或源程序的最前面。
5.每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”
之后不能加分号。
6.标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再
加空格来间隔。

3.5 书写程序时应遵循的规则

从书写清晰,便于阅读,理解,维护的角度出发,在书写程序时应遵循以下规则:

1.一个说明或一个语句占一行。
2.用{} 括起来的部分,通常表示了程序的某一层次结构。 {}一般与该结构语句的第一个字母对齐,并单独占一行。
3.低一层次的语句或说明可比高一层次的语句或说明缩进若干格后书写。 以便看起来更加清晰,增加程序的可读性。
4. 不同逻辑语句空一行。
在编程时应力求遵循这些规则,以养成良好的编程风格

4编程开发环境

4.1 MDK Keil

MDK Keil软件为基于8051、Cortex-M、Cortex-R4、ARM7、ARM9等多种处理器设备提供了一个完整的开发环境。专为微控制器应用而设计,不仅易学易用,而且功能强大,能够满足大多数苛刻的嵌入式应用。
MDK-ARM有四个可用版本,分别是MDK-Lite、MDK-Basic、MDK-Standard、MDK-Professional。所有版本均提供一个完善的C / C++开发环境,其中MDK-Professional还包含大量的中间库。

4.2 CodeBlock+MingGW

CodeBlock编辑器,为开发者们提供了对多种编程语言的内置支持,同时也会为这些语言提供丰富的代码补全和导航功能。
需要下载的工具:
CodeBlock
MingGW
免费下载地址 【CodeBlock +MingGW + Proteus 8.8(菜鸟直接安装版,且仿真不闪退)】
(访问密码:9781)

在这里插入图片描述


http://chatgpt.dhexx.cn/article/wvs2oFwE.shtml

相关文章

嵌入式C语言深入篇之 —— 变量

新建一个物联网行业交流学习QQ群&#xff0c;感兴趣可加&#xff1a;928840648 CUT 变量 可执行程序存储区 当一个C/C原码文件被编译链&#xff08;比如gcc/g&#xff09;编译及链接成为可执行程序后&#xff0c;由4个段组成&#xff0c;分别是&#xff1a;代码段&#xff…

嵌入式C语言编程技巧

基础语法编程技巧 变量 &#xff08;1&#xff09;变量名需见名知意&#xff0c;用英文单词命名&#xff0c;尽可能避免出现 a b 等单一字母的变量 &#xff08;2&#xff09;变量在定义同时进行初始化&#xff0c;防止乱码数据 &#xff08;3&#xff09;变量序号尽可能用英语…

嵌入式C语言强化学习——(嵌入式学习路线1)

前言 从零开始记录自己学习嵌入式&#xff0c;之前看稚晖君的视频&#xff0c;里面的费曼学习法觉得对自己很有帮助&#xff0c;所以准备把自己学习到的东西分享出来&#xff0c;便于学的更深&#xff08;符合费曼学习法&#xff09; 众所周知&#xff0c;嵌入式编一般是使用C…

嵌入式C语言开发

这是我的第一篇对ARM有有疑问并展开调查的文档总结&#xff0c;以备之后查阅。 首先的疑惑是发现之前的源码中都是在对寄存器做操作&#xff0c;所以对寄存器的地址是怎么被确定的就很疑惑。 搜索引擎关键词&#xff1a;嵌入式 寄存器 基地址 使用 参考《嵌入式15——HAL 库中…

嵌入式C语言编译过程

1.预处理 gcc -E -o a.i 001.c 把001.c输出为a.s文件。预处理的本质是把宏定义替换处理。#define ABC 123 2.编译 gcc -S -o a.s 001.c 3.汇编 gcc -c -i a.s 001.c 把c文件生成汇编文件 4.链接 gcc -o build 001.c把001.c生成build.exe可执行文件&#xff0c;从预处理开始。

嵌入式C语言自我修养分享课件

一.异构计算 1.背景&#xff1a; 随着物联网、大数据、人工智能时代的到来&#xff0c;海量的数据分析和大量复杂的运算对CPU 的算力要求越来越高&#xff0c;CPU 的大部分资源用于缓存和逻辑控制&#xff0c;适合运行各种复杂的串行程序&#xff0c;但是单核或者多核CPU处理性…

标准c语言与嵌入式,嵌入式C语言与C语言的区别

嵌入式C语言与C语言的区别&#xff1a;最常用的系统编程语言是C&#xff0c;它是在汇编语言中使用的一种简单的编程语言&#xff0c;源代码采用自由格式。Embeddedc是c语言用于编写嵌入式软件的扩展&#xff0c;这两者有什么区别&#xff1f; 首先是启动过程 1.普通C语言程序的…

嵌入式 C 语言(上)

目录 基础知识数据类型const 用法作用域与 static 用法extern 用法 基础知识 嵌入式C语言和普通C语言在语法上几乎没有差别&#xff0c;其主要差别在于普通C语言的运行环境是OS之上&#xff0c;有很多的标准库函数支撑调用&#xff0c;分配的内存是电脑的内存&#xff0c;其处…

嵌入式C语言

文章目录 一、学会使用char/short/int关键字二、学会使用 if & switch三、学会使用 for & while四、学会使用static关键字五、学会使用define关键字六、学会使用typedef关键字七、学会使用enum关键字八、学会使用struct类型九、学会使用指针类型十、学会使用回调函数十…

嵌入式开发之C语言基础(一)

目前是一名大二升大三的学生&#xff0c;早就有想法写博文了&#xff0c;但是因为自己的拖延一直到现在才开始着手。关于博文&#xff0c;我有以下打算&#xff1a;把C语言再重新过一遍&#xff0c;毕竟嵌入式开发C语言的重要性不言而喻&#xff1b;接下来我还会有一些关于单片…

极简嵌入式C语言教程——从入门到入土(1)

文章目录 第一章&#xff1a;入门1.Hello World!2.C语言标识符与关键字(1)标识符&#xff1a;(2)关键字 3.数据类型与运算符(1)变量与常量<1>变量<2>变量的定义<3>常量 (2)运算符<1>算术运算符<2>自增、自减运算符<3>赋值与赋值组合运算符…

STM32中常用的C语言知识点,开始复习!

要学嵌入式&#xff0c;关注我要学嵌入式&#xff0c;嵌入式猛男的加油站。 C语言是单片机开发中的必备基础知识&#xff0c;这里就列举部分STM32学习中会遇见的C 语言基础知识点。 01 位操作 下面我们先讲解几种位操作符&#xff0c;然后讲解位操作使用技巧。C语言支持如下6中…

嵌入式C语言(入门必看)

目录 STM32的数据类型 const关键字 static 关键字 volatile关键字 extern关键字 struct结构体 enum typedef #define 回调函数 #ifdef 、#ifndef、#else 、#if 嵌入式开发中既有底层硬件的开发又涉及上层应用的开发,即涉及系统的硬件和软件,C语言既具有汇编语言操…

用单层感知器完成逻辑或运算的学习过程

用单层感知器完成逻辑或运算的学习过程 这道题目是我“认知科学”&#xff08;专业必修/doge&#xff09;课程的结课作业题之一&#xff0c;目的在于加深对单层感知器的理解&#xff0c;对于后续学习神经网络打下基础。 有关知识&#xff1a; B站有关视频 单层感知器的学习过…

python中逻辑运算_【多选题】Python 中用于表示逻辑与、逻辑或、逻辑非运算的关键字分别是( ) A. and B. add C. or D. not...

【多选题】Python 中用于表示逻辑与、逻辑或、逻辑非运算的关键字分别是( ) A. and B. add C. or D. not 更多相关问题 A.He has been asked to join the committee.B.There are several new people on the c A.fill inB.equipC.fitD.prove A.encounterB.discernC.seeD.fre…

逻辑运算符简介, 逻辑与,逻辑或,逻辑非和逻辑运算符里的短路运算规则

1&#xff0c;逻辑与 && 符号两边都为true&#xff0c;结果才为true 一假则假 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"…

R语言的逻辑与、逻辑或和元素逻辑与、元素逻辑或的区别

版权声明&#xff1a;转载请注明作者&#xff08;独孤尚良dugushangliang&#xff09;出处&#xff1a;https://blog.csdn.net/dugushangliang/article/details/116463648 参阅&#xff1a;https://www.runoob.com/r/r-basic-operators.html 下图为R运行结果。首先对a、b赋值&a…

Java逻辑操作符——逻辑非、逻辑与、逻辑或和逻辑异或

先上一段java代码&#xff0c;通过具体例子来理解抽象概念 public class 布尔值 {public static void main(String[] args) {boolean 逻辑非的值_测试1 true;boolean 逻辑非的值_测试2 false;System.out.println("逻辑非的值_测试1:"!逻辑非的值_测试1);System.ou…

逻辑与和按位与、逻辑或和按位或的区别

首先分别明确一下他们各自的概念。 按位与和按位或 按位与和按位或都属于位操作符。 注意&#xff1a;位操作符的操作数必须是整数。 按位与“&” 按二进制位对应的位进行与运算&#xff0c;对应位都为1时&#xff0c;结果才为1 3&5 3的二进制&#xff1a; 00000…

JS中的逻辑与和逻辑或

JS中的逻辑或||符号&#xff1a; 从字面上来说&#xff0c;只有前后都是 false 的时候才返回 false&#xff0c;否则返回 true。 console.log(5 > 6|| 6 > 5) //返回true5>6为false 但是 6>5为true 所以返回 true 总结&#xff1a;一真为真 特殊运算方法&#xff…