面试(五)

news2024/10/7 8:30:32

目录

1. 知道大顶端小顶端吗,代码怎么区分大顶端小顶端

2. 计算机中栈地址与内存地址增长方向相反吗?

3. %p和%d输出指针地址

4. 为什么定义第二个变量时候,地址反而减了

5. 12,32,64位中数据的占字节?

6. IIC可以接入多少个设备

7. STM32的三级流水线

8. STM32F4中初始化硬件IIC代码

9. STM32启动流程:初始化确定启动方式->sp,pc指针->系统时钟初始化->初始化用户堆栈->跳到main()

10. STM32F4初始化蓝牙串口和蓝牙HC-05所有配置的代码

11. MCU/DSP

12. 学一个新板子,我们要先知道什么

13. STM32F4中函数怎么压栈到寄存器

14. STM32为什么中断会进入UART4_IRQHandler()

15. STM32收到串口数据时寄存器的状态

16. C++中链表的插入,删除


1. 知道大顶端小顶端吗,代码怎么区分大顶端小顶端

(1)大顶端: 将数据的最高有效字节存储在起始地址,即高位字节在前。小顶端: 将数据的最低有效字节存储在起始地址,即低位字节在前。

假如现有一32位int型数0x12345678,那么其MSB(Most Significant Byte,最高有效字节)为0x12,其LSB (Least Significant Byte,最低有效字节)为0x78,在CPU内存中有两种存放方式:(假设从地址0x4000开始存放)[一个地址下存放一个字节]

(2) 代码区分大顶端和小顶端。

代码1:

#include <stdio.h>

int main() {
    unsigned int x = 0x12345678;
    unsigned char *p = (unsigned char *)&x;

    if (*p == 0x78) {
        printf("小端");
    } else if (*p == 0x12) {
        printf("大端");
    } else {
        printf("未知");
    }

    return 0;
}

指针类型为char而不是int,是因为我们只关心内存中的最低有效字节(LSB),即最低位的字节。在这个例子中,我们想要检查一个整数的字节序,所以我们需要将整数的地址转换为一个字符指针,然后通过解引用这个指针来访问最低有效字节。这样我们就可以根据这个字节的值来判断整数的字节序是大端还是小端。

代码2:

#include <stdio.h>

union {
    unsigned int i;
    unsigned char c[4];
} u;

int main() {
    u.i = 0x12345678;

    if (u.c[0] == 0x78) {
        printf("小端");
    } else if (u.c[0] == 0x12) {
        printf("大端");
    } else {
        printf("未知");
    }

    return 0;
}
在这个例子中,我们使用了一个联合体,它包含一个整数和一个字符数组。我们将整数赋值给联合体的整型成员,然后通过访问字符数组的第一个元素来判断字节序。如果第一个元素的值是0x78,那么就是小端;如果第一个元素的值是0x12,那么就是大端;否则就是未知。

2. 计算机中栈地址与内存地址增长方向相反吗?

计算机内存地址增长的方向是自小到大。栈地址增长方向与内存地址增长方向相反。

3. %p和%d输出指针地址

是把指针变量p中存储的a的地址以十六进制形式输出,%d是吧p中存储的a的地址以十进制形式输出。输出的都是p的值,不要理解成%p,是把p的地址输出。

//3和4的代码
#include <stdio.h>

int main()
{
    int a = 2;
    int b = 3;
    char c = 'a';
    int *p = &a;
    
    printf("%d\r\n",&a);
    printf("%p\r\n",&a);
    printf("%p\r\n",&b);
    printf("%p\r\n",&c);
    printf("%p\r\n",p);
    p++;
    printf("%p\r\n",p);
    return 0;
}

4. 为什么定义第二个变量时候,地址反而减了

因为栈向下增长,所以先声明的地址大,后声明的地址小。栈的这种向下增长的设计使得它在处理函数调用时非常高效。每次函数调用时,都会在栈顶创建一个新的栈帧,用来存放该函数的局部变量和返回地址。当函数执行完毕返回时,对应的栈帧会被自动清理,栈顶恢复到调用前的位置。

5. 12,32,64位中数据的占字节?

8位系统32位系统64位系统
字符型1字节1字节1字节
整型2字节4字节4字节

长整型

4字节4字节4字节

浮点型

无统一标准4字节4字节

双精度浮点型

无统一标准8字节8字节

指针类型

无统一标准4字节8字节

6. IIC可以接入多少个设备

IIC最多可以接入2的7次方-1个设备,一共是127个。
第一个字节(为slave address)由7位地址和一位R/W读写位组成的,这字节是个器件地址。
首先,你要知道:常用IIC接口通用器件的器件地址是由种类型号,及寻址码组成的,共7位。
如格式如下: 
  D7 D6 D5 D4 D3 D2 D1 D0
1-器件类型由:D7-D4 共4位决定的。这是由半导公司生产时就已固定此类型的了,也就是说这4位已是固定的。

2-用户自定义地址码:D3-D1共3位。这是由用户自己设置的,通常的作法如EEPROM这些器件是由外部IC的3个引脚所组合电平决定的(用常用的名字如A0,A1,A2)。这也就是寻址码。
所以为什么同一IIC总线上同一型号的IC只能最多共挂8片同种类芯片的原因了。

3-最低一位就是R/W位。这位不用我多说了

7. STM32的三级流水线

三个主要步骤:取值,译码和执行,取指阶段是从存储器中加载指令到指令寄存器;译码阶段是解释指令含义并准备执行所需的操作;执行阶段则实际完成指令的操作,并将结果写回寄存器。流水线允许多个指令在不同的阶段同时进行处理。例如,当第一条指令处于执行阶段时,第二条指令可能正在进行译码,而第三条指令则在取指阶段

8. STM32F4中初始化硬件IIC代码

#include "stm32f4xx.h"

void I2C1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    // 开启I2C1时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    // 开启GPIOB时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    // 配置PB6和PB7为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 连接PB6和PB7到I2C1的SCL和SDA引脚
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

    // 初始化I2C1
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000; // 设置I2C时钟速率为100kHz
    I2C_Init(I2C1, &I2C_InitStructure);

    // 使能I2C1
    I2C_Cmd(I2C1, ENABLE);
}

9. STM32启动流程:初始化确定启动方式->sp,pc指针->系统时钟初始化->初始化用户堆栈->跳到main()

10. STM32F4初始化蓝牙串口和蓝牙HC-05所有配置的代码

#include "stm32f4xx.h"
#include "usart.h"
#include "bluetooth.h"

void Bluetooth_Init(void)
{
    // 初始化USART1,用于蓝牙通信
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600; // 设置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 设置数据位长度为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1; // 设置停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No; // 不使用奇偶校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 设置为收发模式
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE); // 使能USART1

    // 初始化蓝牙模块
    Bluetooth_Config();
}

void Bluetooth_Config(void)
{
    // 发送AT指令来配置HC-05模块
    // 设置蓝牙名称
    Bluetooth_SendCommand("AT+NAME=HC-05");
    // 设置蓝牙配对密码
    Bluetooth_SendCommand("AT+PSWD=1234");
    // 设置蓝牙工作模式为可连接模式
    Bluetooth_SendCommand("AT+MODE=0");
    // 开启蓝牙模块
    Bluetooth_SendCommand("AT+POWE=1");
}

11. MCU/DSP

MCU是将计算机的主体部分集成在一块半导体上的单片机。DSP是专门用于数字信号处理的微处理器,特别是擅长处理如离散余弦变换、快速傅里叶变换等复杂计算。

12. 学一个新板子,我们要先知道什么

  • 核心处理器:了解SOC使用的中央处理单元类型,如ARM Cortex系列,以及其基本参数,包括频率、核心数量等。
  • 存储选项:研究SOC的内存布局,包括RAM和FLASH的容量,及其对程序执行和数据存储的影响。
  • 输入输出端口:熟悉可用的GPIO数量及其配置选项,理解如何通过这些接口与外部设备进行交互

13. STM32F4中函数怎么压栈到寄存器

在STM32F4中,函数压栈到寄存器涉及对特定寄存器的保存与恢复,确保程序的正常运行和中断处理的正确返回。具体来说,当进行函数调用或响应中断时,处理器自动把PSR, PC, LR, R12, R3, R2, R1, R0等寄存器的内容按照一定顺序压入栈中.手动需要压栈的寄存器包括R11, R10, R9, R8, R7, R6, R5, R4.

14. STM32为什么中断会进入UART4_IRQHandler()

原因是在于STM32微控制器的中断处理机制,该机制通过硬件触发和自动执行预定义的中断服务程序来响应特定的事件。

中断初始化和配置:在STM32中,要使能串口的中断功能,首先要正确配置相关的控制寄存器和中断向量。这包括启用UART4时钟,配置UART4的工作模式(如波特率、数据位等),以及设置中断优先级和使能特定类型的中断源(例如接收中断、发送完成中断等)

中断向量表的角色:启动文件startup_stm32f4xx.s中包含了一个中断向量表,该表为每个中断源指定了一个处理函数。对于UART4,这个向量表中会包含DCD UART4_IRQHandler这样的指令,直接指向了UART4_IRQHandler()函数的内存地址。当UART4的中断条件满足时,处理器会自动跳转到这个地址执行中断服务程序。

硬件自动压栈操作:响应中断时,Cortex-M内核将自动进行压栈操作,保存被中断的程序执行状态,包括程序计数器(PC)、状态寄存器(PSR)、以及一些关键的寄存器如R0-R3、R12、LR、PC、xPSR的值。这一过程完全由硬件自动完成,确保了中断处理完成后能够恢复到原来被打断的程序继续执行。

中断服务程序的执行:一旦处理器响应了中断并进入了UART4_IRQHandler(),它就会执行该函数中的代码来处理具体的中断事件。这包括读取UART4的数据寄存器以获取接收到的数据,或者根据设置处理其他类型的UART中断事件。

从中断返回:处理完中断事件后,UART4_IRQHandler()函数执行结束,内核会自动恢复之前保存的寄存器值,并从中断发生前的指令继续执行。这个过程称为异常退出处理,确保了程序的正确流程和数据的完整性。

错误处理和调试:如果中断处理过程中遇到问题,如硬件错误或配置不当,可能会触发额外的错误处理机制。在这种情况下,开发人员应检查配置是否正确,以及硬件连接是否稳定可靠。

15. STM32收到串口数据时寄存器的状态

STM32的USART是用于处理串口通信的外设,具备发送和接收数据的能力。而串口接收时,主要是状态寄存器和数据寄存器发生变化。

状态寄存器(USART_SR):此寄存器用于检测USART的当前状态,其中包括多个状态位,如发送寄存器空位、发送完成位、读数据寄存器非空位等。其中最重要的两位是RXNE(读数据寄存器非空)和TC(发送完成)

数据寄存器(USART_DR这是一个双向寄存器,分为发送数据寄存器(TDR)和接收数据寄存器(RDR)。向USART_DR写入数据时,数据会被存储在TDR内,用于后续的发送操作;从USART_DR读取数据时,会自动从RDR提取数据。

16. C++中链表的插入,删除

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

// 在链表头插入节点
void insertAtHead(ListNode* &head, int val) {
    ListNode* newNode = new ListNode(val);
    newNode->next = head;
    head = newNode;
}

// 在链表尾部插入节点
void insertAtTail(ListNode* &head, int val) {
    ListNode* newNode = new ListNode(val);
    if (head == NULL) {
        head = newNode;
        return;
    }
    ListNode* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
}

// 在指定位置插入节点
void insertAtPosition(ListNode* &head, int position, int val) {
    if (position == 0) {
        insertAtHead(head, val);
        return;
    }
    ListNode* newNode = new ListNode(val);
    ListNode* temp = head;
    for (int i = 1; i < position && temp != NULL; i++) {
        temp = temp->next;
    }
    if (temp == NULL) {
        cout << "Invalid position!" << endl;
        return;
    }
    newNode->next = temp->next;
    temp->next = newNode;
}

// 删除指定值的节点
void deleteNode(ListNode* &head, int val) {
    if (head == NULL) {
        return;
    }
    if (head->val == val) {
        ListNode* temp = head;
        head = head->next;
        delete temp;
        return;
    }
    ListNode* temp = head;
    while (temp->next != NULL && temp->next->val != val) {
        temp = temp->next;
    }
    if (temp->next == NULL) {
        cout << "Value not found!" << endl;
        return;
    }
    ListNode* toDelete = temp->next;
    temp->next = temp->next->next;
    delete toDelete;
}

// 删除指定位置的节点
void deleteAtPosition(ListNode* &head, int position) {
    if (head == NULL) {
        return;
    }
    if (position == 0) {
        ListNode* temp = head;
        head = head->next;
        delete temp;
        return;
    }
    ListNode* temp = head;
    for (int i = 1; i < position && temp != NULL; i++) {
        temp = temp->next;
    }
    if (temp == NULL || temp->next == NULL) {
        cout << "Invalid position!" << endl;
        return;
    }
    ListNode* toDelete = temp->next;
    temp->next = temp->next->next;
    delete toDelete;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1795973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

告别维修响应慢、费用纠纷,物业报修系统为客服人员减压增效

大家都知道物业报修系统是物业服务企业的得力助手&#xff0c;不仅帮助物业服务企业提升了业主满意度&#xff0c;还增强了物业和业主之间的粘度。但是&#xff0c;我们却忽略了物业报修系统对于物业客服人员带来了哪些工作上的便捷&#xff1f; 作为物业客服人员的你&#xff…

14 个必须了解的微服务设计原则

想象一下&#xff0c;一个机场有各种各样的业务&#xff0c;每个部门都是一个精心设计的微服务&#xff0c;专门用于预订、值机和行李处理等特定操作。机场架构必须遵循这个精心设计的架构的基本设计原则&#xff0c;反映微服务的原则。 例如&#xff0c;航空公司独立运营&…

搜索与图论:宽度优先搜索

搜索与图论&#xff1a;宽度优先搜索 题目描述参考代码 题目描述 输入样例 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0输出样例 8参考代码 #include <iostream> #include <algorithm> #include <cstring> using namespace std;const int N …

chatglm-6b部署加微调

这里不建议大家使用自己的电脑&#xff0c;这边推荐使用UCloud优刻得-首家公有云科创板上市公司 我们进去以后会有一个新人优惠&#xff0c;然后有一个7天30元的购买&#xff0c;购买之后可以去选择镜像&#xff0c;然后在镜像处理的这个位置&#xff0c;可以选择镜像&#xf…

浙江零排参加全国水科技大会暨技术装备成果展览会(成都)并作主论坛演讲

2024年5月13日-15日中华环保联合会、福州大学、上海大学等联合举办的2024年全国水科技大会暨技术装备成果展览会在成都顺利举办。浙江零排城乡规划发展有限公司司受邀参加&#xff0c;首日有幸听取徐祖信院士、任洪强院士、汪华林院士等嘉宾的主旨报告。主旨报告后&#xff0c;…

麒麟操作系统rpm ivh安装rpm包卡死问题分析

夜间变更开发反应&#xff0c;rpm -ivh 安装包命令夯死&#xff0c;无执行结果&#xff0c;也无报错 排查 &#xff1a; 1、top 查看无进程占用较高进程存在&#xff0c;整体运行平稳 2、df -h 查看磁盘并未占满 3、其他服务器复现该命令正常执行 4、ps -ef|grep rpm 查看安装…

江苏省汽车及零部件产业协作配套对接会在苏州举行

5月28日&#xff0c;江苏省汽车及零部件产业协作配套对接会暨“百场万企”大中小企业融通对接活动在苏州举办。本次活动以“深化整零协作&#xff0c;促进大中小企业融通发展”为主题&#xff0c;由江苏省工业和信息化厅、中国中检所属中国汽车工程研究院股份有限公司&#xff…

跑图像生成模型GAN时,遇到OSError: cannot open resource 报错解决办法

报错信息如下&#xff1a; Traceback (most recent call last): File "/root/autodl-tmp/ssa-gan/pretrain_DAMSM.py", line 276, in <module> count train(dataloader, image_encoder, text_encoder, File "/root/autodl-tmp/ssa-gan/pretrain_DAMSM.py…

安卓SystemServer进程详解

目录 一、概述二、源码分析2.1 SystemServer fork流程分析2.1.1 [ZygoteInit.java] main()2.1.2 [ZygoteInit.java] forkSystemServer()2.1.3 [Zygote.java] forkSystemServer()2.1.4 [com_android_internal_os_Zygote.cpp]2.1.5 [com_android_internal_os_Zygote.cpp] ForkCom…

C语言数据结构(超详细讲解)| 二叉树的实现

二叉树 引言 在计算机科学中&#xff0c;数据结构是算法设计的基石&#xff0c;而二叉树&#xff08;Binary Tree&#xff09;作为一种基础且广泛应用的数据结构&#xff0c;具有重要的地位。无论是在数据库索引、内存管理&#xff0c;还是在编译器实现中&#xff0c;二叉树都…

springboot 社区疫苗管理网站系统-计算机毕业设计源码89484

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 社区疫苗管理网站系统&#xff0c;主要的模块包括查看首页、网站管理&#xff08;轮播图、公告信息&#xff09;人员管理&#xff08;管理员、…

Liunx音频

一. echo -e "\a" echo 通过向控制台喇叭设备发送字符来发声&#xff1a; echo -e "\a"&#xff08;这里的 -e 选项允许解释反斜杠转义的字符&#xff0c;而 \a 是一个响铃(bell)字符&#xff09; 二. beep 下载对应的包 yum -y install beep 发声命令 be…

金融创新浪潮下的拆分盘投资探索

随着数字化时代的步伐加速&#xff0c;金融领域正经历着前所未有的变革。在众多金融创新中&#xff0c;拆分盘作为一种新兴的投资模式&#xff0c;以其独特的增长机制&#xff0c;吸引了投资者的广泛关注。本文将对拆分盘的投资逻辑进行深入剖析&#xff0c;并结合具体案例&…

TikTok广告投放攻略——广告类型详解

TikTok广告是品牌或创作者付费向特定目标受众展示的推广内容&#xff08;通常是全屏视频&#xff09;。TikTok 上的广告是一种社交媒体营销形式&#xff0c;通常旨在提高广告商的知名度或销售特定产品或服务。 就 TikTok广告投放而言&#xff0c;其组织层级分为三个层级&#x…

【SpringBoot + Vue 尚庭公寓实战】项目初始化准备(二)

尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09; 文章目录 尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09;1、导入数据库2、创建工程3、项目初始配置3.1、SpringBoot依赖配置3.2、创建application.yml文件3.3、创建…

RabbitMQ(五)集群配置、Management UI

文章目录 一、安装RabbitMQ1、前置要求2、安装docker版复制第一个节点的.erlang.cookie进入各节点命令行配置集群检查集群状态 3、三台组合集群安装版rabbitmq节点rabbitmq-node2节点rabbitmq-node3节点 二、负载均衡&#xff1a;Management UI1、说明2、安装HAProxy3、修改配置…

代码随想录算法训练营第四十六 | ● 139.单词拆分 ● 关于多重背包,你该了解这些! ● 背包问题总结篇!

139.单词拆分 视频讲解&#xff1a;https://www.bilibili.com/video/BV1pd4y147Rh https://programmercarl.com/0139.%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86.html class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<st…

springboot vue 开源 会员收银系统 (6) 收银台的搭建

前言 完整版演示 前面我们对会员系统 分类和商品的开发 完成了收银所需的基础信息 下面我们开始完成收银台的开发 简单画了一个收银的流程图大家参考下 从这张图我们可以分析一下几点 可以选择会员或散客收银选择会员使用相应的会员价结算使用会员卡则在价格基础根据卡折扣…

sql server:数据库处于单用户模式,当前某个用户已与其连接

在 SQL Server 中&#xff0c;数据库可以设置为不同的用户模式&#xff0c;以便根据需要限制对数据库的访问。单用户模式&#xff08;Single-User Mode&#xff09;是其中一种模式&#xff0c;它限制了对数据库的访问&#xff0c;使得一次只能有一个用户连接到数据库。 单用户…

七月份大理站、ACM独立出版、高录用稳检索,2024年云计算与大数据国际学术会议(ICCBD 2024)

【ACM独立出版 | 高录用 | EI核心检索稳定】 2024年云计算与大数据国际学术会议&#xff08;ICCBD 2024) 2024 International Conference on Cloud Computing and Big Data (ICCBD 2024) 一、重要信息 大会官网&#xff1a;www.iccbd.net &#xff08;点击投稿/参会/了解会…