我是第一年开始学习微控制器开发的计算机科学专业的学生.我想使用8051,因为它常见于污垢,并且在现实世界中经常使用.
在我大三或大四的时候,我将采用基于PIC微控制器的嵌入式设计课程,所以我现在不想做PIC; 否则,在那个课程中我会觉得很无聊.
我看到的大多数商业套件都是AVR或PIC系列微处理器.我只是在寻找具有良好开发工具,文档和足够附件的东西,以保持我的新手在夏天自我占用.
有关8051系列套件的任何建议吗?谢谢!
好的,所以我之前打开了usb驱动器,我明白他们使用通用MCU来控制NAND闪存.我在想的是,如果有人可以重新编程它们,在插入USB端口时启动应用程序,那么它对于大量应用程序(例如自动复制文件)可能很有用.我知道不同的MCU可能会/可能不会使用完全不同的ASM代码,但也存在如何与其进行通信的问题(即协议等).这有可能吗?我听说过像MP Tools这样的东西(理论上)可以低级格式化并将驱动器重置为出厂默认值,但不能编辑其上使用的任何代码.
我有一个关于 I2C 协议的问题。我在维基百科页面上找到了这个。
“如果发送器看到 1 位 (NACK),它就会了解到:
1) 从机无法接受数据。2) 没有这样的从站 3) 无法理解命令 4) 无法接受更多数据。”
第一点和第四点似乎是相互矛盾的。场景是:我正在尝试在微控制器之间进行通信,因此,一个将充当主控制器,另一个将充当从控制器。我从主控制器传输 10 个字节,而从控制器在我的实现中只能接收 5 个字节。
所以我的问题是根据 i2c 协议从机何时应该发送 NACK?1) 收到第5个字节后。2) 收到第6个字节后。
我对嵌入式系统和一个库有疑问。
我目前正在使用一种名为 Ambiq [3] 的设备,该设备使用 Cortex M-4,我想在其上使用 FANN(快速人工神经网络)库 [2]。我能够编译和链接所有内容,但问题是 FANN 库在启动时需要读取 2 个文件。
现在,我有一个嵌入式系统,所以我没有任何文件系统,也没有操作系统。我很确定我可以以某种方式将该文件的内容写入闪存,但我真的不知道如何将第一个文件地址链接到 C 文件函数,例如“fopen”需要文件名作为输入。我只需要文件名和文件物理地址之间的某种联系,如果它存在(或者接受与文件名不同的内容的 C 函数),我就完成了。
我已经尝试过的一件事是使用 xxd -i [文件名] [1] 将文件的内容硬编码到 C 数组中,但我不知道应该如何链接 FANN 库使用的 fopen。我还启动了一些 cleaver 解析器,但它似乎非常耗时。
如果您有什么建议,请告诉我。先感谢您。此致。贾斯基拉特
附加信息: - 用于编译的软件:带有 makefile 的 Eclipse。- 编译器:eabi-none-gcc 工具箱 - 我正在使用应在 Cortex M4 上运行的 Ambiq 微控制器应用程序直接编译 FANN 库源代码。
参考资料: [1]在编译时将文件读入字符串 [2] FANN LIBRARY UFFICIAL SITE http://leenissen.dk/fann/wp/ [3] AMBIQ MICRO: http: //ambiqmicro.com/
我已经看到这个主题已经在许多其他问题中讨论过,但我无法找到适合我的具体情况的答案。
我正在使用 STM32F0 微控制器。SPI 接收/发送 FIFO 的顶部可通过存储器访问进行访问。这个特殊的微控制器允许我从 FIFO 顶部读取/写入 8 位或 16 位。更准确地说,当执行 LDRB/STRB 指令时,将 8 位从 FIFO 弹出/推送到 FIFO,而当执行 LDRH/STRH 指令时,将从 FIFO 弹出/推送 16 位。
STMicroElectronics 提供的硬件抽象层提出了这种语法来读取 SPI FIFO。
return *(volatile uint8_t*)&_handle->Instance->DR; // Pop 1 byte
return *(volatile uint16_t*)&_handle->Instance->DR; // Pop 2 byte
*(volatile uint8_t*)&_handle->Instance->DR = val; // Push 1 byte
*(volatile uint16_t*)&_handle->Instance->DR = val; // Push 2 bytes
Run Code Online (Sandbox Code Playgroud)
SPI FIFO 顶部的DR一个指针在哪里uint32_t*
我已经使用这种语法构建了我的软件,并且它工作得很好。唯一的问题是 g++ 抛出了很多关于类型双关的警告。更确切地说:
Inc/drivers/SPI.h:70:50:警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]
return *(volatile uint16_t*)&_handle->Instance->DR;
经过一些阅读后,看起来在 C++ 中使用 union 并不是一个好主意。无论如何我确实尝试过但遇到了一些问题。实际上,通过联合中的指针访问内存会使我的微控制器崩溃,就像未对齐的内存访问一样。
static_cast …
我正在研究一款 Freesacle 微控制器。该微控制器有多个复位源(例如时钟监视器复位、看门狗复位等)。假设由于看门狗的原因,我的微控制器被重置。如何在重置发生之前保存一些数据?我的意思是,例如,我如何理解看门狗重置之前程序计数器在哪里。通过这种方法,我想知道哪里有错误(换句话说,很长的过程)导致看门狗重置。
大家好,
这里有人以前遇到过这个问题吗?
在我将代码运行到 stm32f446re 中后,我无法在最后一个代码之后上传任何代码,并给出此错误“未找到 STM32 目标”
我尝试执行以下选项:-
1- 更新我的 ST-Link 驱动程序并将其作为“dpinst_amd64”运行。
2-更新我的 ST-Link 固件,它是从 STM32CubeProgrammer 运行并更新的,如图所示。
但这些解决方案都不起作用。
由 Arduino IDE 执行的 ESP32 flash 命令似乎刷新了两个引导加载程序文件:boot_app0.binat offset0xe000和bootloader_dio_80m.binat offset0x1000。我想知道这两个引导加载程序文件实际上是做什么的,以及为什么有两个。下面我提供一些更多信息。
我所在的团队正在为微控制器开发一种新的免费 IDE:Embeetle IDE。我们计划在不久的将来支持 ESP32 微控制器系列。因此,我现在正在研究 ESP32 构建系统 - 两者ESP-IDF ESP32 项目的工具和 Arduino IDE 方法。
构建.elf文件后,Arduino IDE 会启动一个命令将其转换为二进制文件:
python esptool.py --chip esp32 elf2image
--flash_mode dio
--flash_freq 80m
--flash_size 4MB
-o /tmp/arduino_build_852524/WiFiScan.ino.bin
/tmp/arduino_build_852524/WiFiScan.ino.elf
Run Code Online (Sandbox Code Playgroud)
最后,该WiFiScan.ino.bin文件与两个引导加载程序文件和分区表一起闪存到主板上:
python esptool.py --chip esp32
--port /dev/ttyUSB0
--baud 921600
--before default_reset
--after hard_reset write_flash
-z
--flash_mode dio
--flash_freq 80m
--flash_size detect …Run Code Online (Sandbox Code Playgroud) 我正在研究嵌入式设备的微控制器。这些控制器提供多个使用寄存器进行配置和控制的外设。外设通常具有与其关联的特定寄存器组。多个相同类型的外设(例如,Timer0、Timer1...)具有相同的寄存器组,但它们位于不同的基地址。
通常制造商提供头文件来定义每个外设的寄存器和相关地址。
例如,可以提供定时器外设的头文件:
typedef struct {
uint32_t IR;
uint32_t TCR;
uint32_t TC;
uint32_t MCR;
uint32_t MR[4];
} CTIMER_Type;
#define CTIMER0_BASE (0x40008000u)
#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE)
#define CTIMER1_BASE (0x40009000u)
#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE)
#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1 }
Run Code Online (Sandbox Code Playgroud)
这些头文件特定于特定设备。在此示例中,提供了有关定时器外设的信息:有两个定时器,它们的寄存器组分别位于CTIMER0 a
nd CTIMER1。
使用 C,我可以使用以下命令将基址寄存器地址列表拉CTIMER_BASE_PTRS入我的实现中:
static CTIMER_Type * ctimers[] = CTIMER_BASE_PTRS;
static int timers_count = sizeof(ctimers)/sizeof(*ctimers);
Run Code Online (Sandbox Code Playgroud)
现在使用 C++,我想编写一个驱动程序类并包含可用计时器的列表CTIMER_BASE_PTRS。我还想计算可用计时器的数量。
我想出了这段代码,您可以自己尝试一下:
#include <stdio.h>
#include <type_traits>
#include <stdint.h>
/* usually provided by chip manufacturer …Run Code Online (Sandbox Code Playgroud) 我注意到一个无法解释的行为:函数的执行时间似乎取决于它在闪存 ROM 中的位置。我使用的是 STM32F746NGH 微控制器(基于 ARM-cortex M7)和 STM32CubeIDE(适用于 ARM 的 GCC 编译器)。
这是我的测试:
我初始化了 SysTick 计数器以触发固定周期 T = 1ms 的中断。在中断处理程序中,我在两个线程之间切换(像 RTOS):让我们将它们命名为 Thread1 和 Thread2。
每个线程只是简单地递增一个变量。
这是两个线程的代码:
uint32_t ctr1, ctr2;
void thread1(void)
{
while(1)
{
ctr1++;
}
}
void thread2(void)
{
while(1)
{
ctr2++;
}
}
Run Code Online (Sandbox Code Playgroud)
在监视这些变量时,我注意到 ctr2 的增量比 ctr1 快得多。
使用此代码:线程1的地址是0x08000418,线程2的地址是0x0800042C。
然后,我尝试将另一个函数放在 thread1 之前的内存中:我们将其命名为 thread0。
所以我的新代码是:
uint32_t ctr0, ctr1, ctr2;
void thread0(void)
{
while(1)
{
ctr0++;
}
}
void thread1(void)
{
while(1)
{
ctr1++;
}
}
void thread2(void)
{
while(1) …Run Code Online (Sandbox Code Playgroud)