我是第一年开始学习微控制器开发的计算机科学专业的学生.我想使用8051,因为它常见于污垢,并且在现实世界中经常使用.
在我大三或大四的时候,我将采用基于PIC微控制器的嵌入式设计课程,所以我现在不想做PIC; 否则,在那个课程中我会觉得很无聊.
我看到的大多数商业套件都是AVR或PIC系列微处理器.我只是在寻找具有良好开发工具,文档和足够附件的东西,以保持我的新手在夏天自我占用.
有关8051系列套件的任何建议吗?谢谢!
好的,所以我之前打开了usb驱动器,我明白他们使用通用MCU来控制NAND闪存.我在想的是,如果有人可以重新编程它们,在插入USB端口时启动应用程序,那么它对于大量应用程序(例如自动复制文件)可能很有用.我知道不同的MCU可能会/可能不会使用完全不同的ASM代码,但也存在如何与其进行通信的问题(即协议等).这有可能吗?我听说过像MP Tools这样的东西(理论上)可以低级格式化并将驱动器重置为出厂默认值,但不能编辑其上使用的任何代码.
我一直在试图用C在Keil写我的一些测试代码TM4C123G,它使用的ARM微控制器.我不知道ARM assembly,但我已经为AVR microcontroller过去编写了一些汇编代码.
存储变量的值在哪里,如果我们在C中声明一个变量global,而不是声明它main?
关于是否应该声明一个变量global而不是main(在为微控制器编写C时)是否有一般指导原则?
我正在研究一款 Freesacle 微控制器。该微控制器有多个复位源(例如时钟监视器复位、看门狗复位等)。假设由于看门狗的原因,我的微控制器被重置。如何在重置发生之前保存一些数据?我的意思是,例如,我如何理解看门狗重置之前程序计数器在哪里。通过这种方法,我想知道哪里有错误(换句话说,很长的过程)导致看门狗重置。
我正在尝试将OpenOCD用于不常见的事情。除了连接芯片,我只想检测芯片。
我想到的过程将如下所示:
使用参数作为探针的配置文件(例如
stlink.cfg)启动OpenOCD-f。因此,OpenOCD知道要使用哪种探针,但不知道它将找到哪种芯片。OpenOCD检测到芯片并以某种方式报告该错误(例如,向stdout写一些东西)。如果可能的话,此操作不应对芯片造成干扰(例如将其重置)。
OpenOCD关闭。
以下是有关该过程的更多说明:
注意1:如果OpenOCD没有达到服务器状态(我需要设置Telnet或GDB客户端才能与其进行交互),那将是很好的。我很乐意以更方便的方式获得芯片检测报告,例如在stdout通道上获取芯片信息。
注2:检测不应对芯片造成干扰。但是,如果OpenOCD找不到任何东西,我希望有一种备份方法,其中OpenOCD尝试更积极地查找芯片(例如按住nRST销)。如果需要,我可以自己调用其他方法(因此,无需OpenOCD自动执行此操作)。
注意3:首先,我将仅在具有STLinkV2或STLinkV3探针的STM32芯片上应用此“芯片检测”功能,然后再将其应用于其他探针和芯片。
注4:某些板仅具有SWD连接(无JTAG)。
注意5:我正在Windows 10计算机上工作,并从https://www.playembedded.org/blog/download/下载了最新的OpenOCD版本(版本0.10.0_dev00921,于2019年7月6日构建)。
Tommy Murphy先生向我介绍了OpenOCD参考手册中的10.7节(请参阅http://openocd.org/doc/pdf/openocd.pdf)。我已经阅读了本节,并观察了以下示例:
# openocd.cfg file
# -----------------
source [find interface/olimex-arm-usb-tiny-h.cfg]
reset_config trst_and_srst
jtag_rclk 8
Run Code Online (Sandbox Code Playgroud)
因为我的芯片通过STLink探针连接并且使用SWD传输协议(而不是JTAG),所以我对该示例进行了一些修改:
# openocd.cfg file
# -----------------
source [find interface/stlink.cfg]
transport select hla_swd
reset_config srst_only
adapter_khz 480
Run Code Online (Sandbox Code Playgroud)
我将NUCLEO_F303K8板连接到PC进行此测试。然后,在控制台中发出以下命令:
> openocd -s "C:\...\scripts" …
因此,我目前正在学习 STM32 微处理器课程,但是,我似乎连最基本的事情都失败了:打开 LED。完整的代码位于这篇文章的底部。
重要的:
首先,我们要弄清楚内置LED在哪个引脚上。根据制造商手册,LED 应位于引脚 D13 (PB3) 上。

好的,我们正在寻找 PB3。根据 STM32L432KC 的数据表,PB3 位于 B 端口,因此连接到高性能总线,如下图所示。

凉爽的。所以我们的总线是 AHB2,我们正在使用 GPIOB。现在我们必须使用 RCC_AHB3ENR 寄存器启用该总线上的时钟。现在,这是我可能会犯错误的部分(否则这篇文章就不会存在),所以请密切注意。如果我理解正确,我希望将位 1 设置为 1,因为这表示“GPIOBEN”设置为“IO 端口 B 时钟启用”。

这让我相信我应该按如下方式设置总线寄存器:
RCC->AHB2ENR |= 0x2;
Run Code Online (Sandbox Code Playgroud)
接下来我必须将 GPIO 引脚的模式设置为输出。根据课程和我的文档,这是使用 GPIOx_MODER 完成的。

这让我相信我应该按如下方式设置 GPIO 模式:
GPIOB->MODER |= 0x40;
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是,要打开实际的 LED,我们必须设置输出数据寄存器,即 GPIOx_ODR。

这让我相信我应该将数据设置如下:
GPIOB->ODR = 0x8;
Run Code Online (Sandbox Code Playgroud)
我不确定我哪里出了问题,但这是我第一次在如此深入的层面上使用寄存器。我一定忽略了一些事情,但我尝试了多个例子但没有成功。感谢所有帮助。这是完整的代码:
// PB3 - User LED
// RCC->AHB2ENR
// GPIOx_MODER
// GPIOx_ODR
#include "stm32l4xx.h"
int main(void)
{
RCC->AHB2ENR |= 0x2;
GPIOB->MODER |= 0x40;
while(1)
{
GPIOB->ODR = 0x8; …Run Code Online (Sandbox Code Playgroud) 大家好,
这里有人以前遇到过这个问题吗?
在我将代码运行到 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)