嵌入式基础知识-4

C++软件与嵌入式软件面经解析大全(蒋豆芽的秋招打怪之旅)


本章讲解知识点

  • 1.1 嵌入式计算机系统的发展
  • 1.2 嵌入式计算机系统的定义与组成
  • 1.3 嵌入式操作系统以及用户应用软件
  • 1.4 ARM简介
  • 1.5 ARM体系结构
  • 1.6 其他典型微控制器
  • 1.7 BootLoader
  • 1.8 典型的BootLoader——U-Boot
  • 1.9 驱动程序与设备
  • 1.10 总线
  • 1.11 串行与并行、同步与异步、半双工与全双工
  • 1.12 内部总线
  • 1.13 系统总线
  • 1.14 外部总线

受众:本教程适合于C/C++已经入门的学生或人士,有一定的编程基础。

本章节仅适合于嵌入式软件求职的学生或人士。

img

故事背景

img

蒋 豆 芽:小名豆芽,芳龄十八,蜀中人氏。卑微小硕一枚,科研领域苟延残喘,研究的是如何炒好一盘豆芽。与大多数人一样,学习道路永无止境,间歇性踌躇满志,持续性混吃等死。会点编程,对了,是面对对象的那种。不知不觉研二到找工作的时候了,同时还在忙论文,豆芽都秃了,不过豆芽也没头发啊。

隔壁老李:大名老李,蒋豆芽的好朋友,技术高手,代码女神。给了蒋豆芽不少的人生指导意见。

导 师:蒋豆芽的老板,研究的课题是每天对豆芽嘘寒问暖。

img

故事引入

img

蒋 豆 芽:老李,你最近在干嘛啊?我看你还挺忙的。

隔壁老李:(满头大汗)是啊,豆芽,累死我了。最近忙着筹备公众号。

蒋 豆 芽:(震惊)怎么了,老李,你难道要抛弃我了?

隔壁老李:(笑)说啥呢豆芽?公众号而已,就当个兴趣爱好来搞搞。就是更忙一点而已。

蒋 豆 芽:(吁气)那就好,那就好。什么类型的公众号啊?

隔壁老李:财经、政治、生活方面的。行了,不说这个了,我们继续学习吧!

蒋 豆 芽:好!我爱学习!


隔壁老李:豆芽,我们在前面已经讲完了有关嵌入式linux开发相关的东西,以及介绍了典型的ARM框架。这一章我们来讲讲剩余的嵌入式相关的杂项知识点。

img

1.10 总线

img

隔壁老李:我们先来讲讲一个重要的知识点,那就是总线

蒋 豆 芽:嗯?好像了解过,什么SPI啊、CAN总线啊。

隔壁老李:没错,我们来系统的讲一讲。你看看下面的设备连线。

img

蒋 豆 芽:我的妈呀,这也太恐怖了吧。

隔壁老李:是的,我们的微电子电路也是一个道理。任何一个微处理器都要与一定数量的部件外围设备连接,但如果将各部件和每一种外围设备都分别用一组线路与CPU直接连接,那么连线将会错综复杂,甚至难以实现。为了简化硬件电路设计、简化系统结构,常用一组线路,配置以适当的接口电路,与各部件和外围设备连接,这组共用的连接线路被称为总线

蒋 豆 芽:(恍然大悟)哦,原来总线是这么来的。

隔壁老李:总线在英语中,叫作“bus”,你看,这就很形象了,总线如同公交车,内部电子器件和外围设备就是一个个的站点,CPU发出的信号就通过总线这辆公交车到达它们指定的站点。

蒋 豆 芽:是的,太形象了!公交车只能在固定的线路上跑,所以有了总线,我们的线路就不会再乱了。

隔壁老李:微机中总线一般有内部总线系统总线外部总线。讲总线前,我们先明确一些概念,串行与并行同步与异步全双工与半双工

img

1.11 串行与并行、同步与异步、全双工与半双工

img

隔壁老李:这些概念不难,看图就特别直观了:我们先看串行和并行

img

串行是一个字节的数据,排成一行发送给接收设备。并行是一个字节的数据,排成一列发送给接收设备。那当然并行速率快、吞吐量大、不过消耗IO资源也很多。

串行和并行区别如下:

  1. 数据传送方式不同:串行口传输方式为数据排成一行、一位一位送出数据;并行口传输8位数据一次送出。
  2. 针脚不同:串行口针脚少,消耗IO资源少;并行口针脚多,消耗IO资源多。
  3. 用途不同:串行口主要用在速度要求不高、有一定距离的传输场景,如UART,I2C通信;并行口多用于传输速率要求高、吞吐量大的场景,如FSMC(Flexible Static Memory Controller,可变静态存储控制器),DVP(Digital Video Port,数字视频接口)等接口。

隔壁老李:我们再来看同步与异步

img

我们注意到在字节与字节之间,同步发送数据是不留间隙的,而异步发送数据可以间隙任意。这是最主要的区别。我们再看看表格:

通信类型 字节与字节之间间隙 位与位之间间隙 时钟频率 起始位、终止位
同步 无间隙 间隙固定 相同 不需要
异步 间隙任意 间隙固定 不同 需要

我们给出同步与异步通信的区别:

  1. 同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流,字节与字节之间没有间隙;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节。
  2. 同步通信效率高,异步通信效率较低。
  3. 同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。
  4. 同步通信可用于多点对多点,异步通信只适用于点对点。

隔壁老李:我们最后看看全双工与半双工

img

半双工和全双工的区别很明显,半双工只有一条数据线,既要用作发送数据,又要用作接收数据,是单向的;而全双工一条数据线用作发送数据,一条数据线用作接收数据,是双向的。

那么两者最大区别就是速率了,全双工通信速率理论上是半双工的两倍。

隔壁老李:好了,豆芽,基本概念我们就清楚了,接下来就可以进入总线的讲解了。我们先讲内部总线。

img

1.12 内部总线

img

隔壁老李内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连。内部总线就是我们很熟悉的了。I2C、SPI都是内部总线。

隔壁老李:我们先讲I2C总线,很重要,面试喜欢考。

隔壁老李:I2C总线的特点是:

I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。 可以看出I2C总线是半双工同步总线。

SDA:双向数据线,为OD (Open Drain,漏极输出) 门,与其它任意数量的OD与OC (Open Collector,集电极开路) 门成\线与\关系。

SCL:上升沿将数据输入到每个I2C从设备中;下降沿驱动I2C从设备输出数据。(边沿触发)

隔壁老李I2C通信的时候,通信双方地位是不对等的,而是分为主设备和从设备。通信由主设备发起,由主设备主导,从设备只是按照I2C协议被动的接收主设备的通信,并及时响应。

蒋 豆 芽:那具体怎么选择从设备呢?

隔壁老李:系统中的所有外围器件通常具有一个7位的从器件专用地址码,其中高4位为器件类型,由生产厂家制定,低3位为器件引脚定义地址,由使用者定义 (I2C还支持10位寻址)。

主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构,如图。

img

终端挂载在总线上,有主端和从端之分,主端必须是带有CPU的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。

蒋 豆 芽:哦,明白了。

隔壁老李:然后我们就要讲I2C总线的协议了,太喜欢考了

我们看到时序图:

img
  1. 空闲状态:I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。

  2. 起始信号:当SCL为高电平期间,SDA由高到低的跳变

  3. 停止信号:当SCL为高电平期间,SDA由低到高的跳变

隔壁老李:然后我们来看看如何传输数据的,如图:

img

数据传输以字节为单位。

主设备在SCL线上产生每个时钟脉冲,将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位(ACK),此时才认为一个字节真正的被传输完成

当然,并不是所有的字节传输都必须有一个应答位,比如:当从设备不能再接收主设备发送的数据时,从设备将回传一个否定应答位。

隔壁老李:为了加深理解,我们要代码实操一下,比如平常我们使用存储芯片AT24C02,就采用的I2C协议,我们使用51单片机来访问AT24C02,那51单片机没有I2C接口,我们就不得不利用IO模拟I2C时序,这非常有利于我们学习I2C协议。

我们从时序图左边开始,当SCL为高电平期间,SDA由高到低的跳变,那么这就是起始信号,这里要注意,SCL要在几us内完成跳变呢?

这个时候我们就要看芯片手册了,下面是我截取的AT24C02芯片手册的一部分,我们需要注意一个时间,就是t(SU.STA),我们这里假定当AT24C02工作在1.8v时,这个时间的最小保持时间是4.7us,而我们的51单片机使用外接12M的晶振时,一个指令周期1us。意思就是SDA跳变时需要再插入时延。包括时间t(HD.STA)t(Low)t(High),都是大于4.0us的,所以,都要插入时延,因为I2C时序要求并不是很严格,一般我们插入10us时延。好了,我们来看代码。

img
img

先看到起始信号:

void IIC_Start(){
    SDA = 1;     // 51单片机在读取数据之前要先置一,表示数据输入
    delay10us(); // 插入时延10us
    SCL = 1;
    delay10us(); // 插入时延10us
    SDA = 0;
    delay10us(); // 插入时延10us,保持时间是>4.7us
    SCL = 0;    
    delay10us(); // 插入时延10us
}

终止信号如下:

void IIC_Stop(){
    SDA = 0;
    delay10us(); // 插入时延10us
    SCL = 1;
    delay10us(); // 插入时延10us,建立时间大于4.7us
    SDA = 1;
    delay10us(); // 插入时延10us    
}

我们再给出字节读取、传送代码:

//通过I2C发送一个字节。在SCL时钟信号高电平期间, 发送信号SDA保持稳定
uchar I2C_SendByte(uchar dat, uchar ack){
    uchar a = 0,b = 0;      // 最大255,一个机器周期为1us,最大延时255us。            
    for(a=0; a<8; a++){     // 要发送8位,从最高位开始
        SDA = dat >> 7;        // 起始信号之后SCL=0,所以可以直接改变SDA信号
        dat = dat << 1;
        delay10us();
        SCL = 1;
        delay10us();        //建立时间>4.7us
        SCL = 0;
        delay10us();        //时间大于4us        
    }
    SDA = 1;
    delay10us();
    SCL = 1;
    /*
    主设备在SCL线上产生每个时钟脉冲,将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位(ACK),此时才认为一个字节真正的被传输完成
    */
    while(SDA && (ack == 1)){ // 等待应答,也就是等待从设备把SDA拉低
        b++;
        if(b > 200){        // 如果超过200us没有应答发送失败,或者为非应答,表示接收结束
            SCL = 0;
            delay10us();
            return 0;
        }
    }
    SCL = 0;
    delay10us();
     return 1;        
}

// 使用I2c读取一个字节
uchar I2C_ReadByte(){
    uchar a = 0,dat = 0;
    SDA = 1;              //起始和发送一个字节之后SCL都是0
    delay10us();
    for(a=0; a<8; a++){   // 接收8个字节
        SCL = 1;
        delay10us();
        dat <<= 1;
        dat |= SDA;
        delay10us();
        SCL = 0;
        delay10us();
    }
    return dat;        
}

蒋 豆 芽:懂了懂了,下次面试官再考时序图,就再也不用担心了。

隔壁老李:我们再介绍SPI。

SPI是串行外设接口 (Serial Peripheral Interface) 的缩写。是 Motorola 公司推出的一 种同步串行接口技术,是一种高速的,全双工,同步的通信总线。

PI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多 个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI (数据输入)、SDO (数据输出)、SCLK (时钟)、CS (片选)。

  1. SDO/MOSI – 主设备数据输出,从设备数据输入;
  2. SDI/MISO – 主设备数据输入,从设备数据输出;
  3. SCLK – 时

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

<p> - 本专刊适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专刊适合于互联网C++软件开发、嵌入式软件求职的学生或人士。 - 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构等一系列知识点的讲解,并且最后总结出了高频面试考点(附有答案)共近400道,知识点讲解全面。不仅如此,教程还讲解了简历制作、笔试面试准备、面试技巧等内容。 </p> <p> <br /> </p>

全部评论
SDA上传输的数据必须在SCL为高电平期间保持稳定,在SCL为低电平期间变化
1 回复 分享
发布于 2024-03-26 11:25 江苏

相关推荐

点赞 评论 收藏
分享
头发暂时很多的KFC总裁:找廉价劳动力罢了
点赞 评论 收藏
分享
评论
点赞
3
分享
牛客网
牛客企业服务