【发布时间】:2020-08-26 01:14:10
【问题描述】:
前言:作为应用程序开发人员工作了几年后,软件工程的世界变得比以前更加晦涩难懂。原因是真正的东西隐藏在无数层抽象之下:操作系统、框架等。年轻一代被剥夺了使用类似 PDP 的机器工作的乐趣,所有编程都是通过电气开关切换完成的。另一个问题是现代编程语言的短暂性。曾经有 Python 2.x,现在它已被弃用,而 Python 3.x 又将在几个月内被弃用。其他语言的同上。 ANSI C 看起来像胡夫金字塔:它在 70 年代就在那里,我不怀疑它会在太阳变成红矮星之后在那里。
现在看来,了解硬件和软件之间交互的唯一方法就是玩嵌入式开发。从教学的角度来看,物理芯片非常方便,因为它们可以解决 C 语言中最困难的部分,即指针。在 OS 环境中编码时,*/& 表示法仍然非常混乱,因为它指的是虚拟内存中某处的某个位置。在你了解什么是虚拟内存之前,你必须阅读一些关于操作系统开发等的专着。你可能会觉得这很愚蠢,但我真的很想知道现在哪个晶体管占据了我的位置。至少,我可以将物理引脚电压连接到编程抽象。
目前我正在使用 Atmel 芯片和 WinAVR 包,因为有大量的教科书和可访问的硬件。尽管所有书籍都承诺使用纯 C 来教授 AVR 编码,但现实情况是所有指针都隐藏在 PORTA、DDRB 等宏后面。所有代码示例都包含头文件“io.h”,它又引用了其他特定的头文件对于像“iomx8.h”这样的给定芯片。到目前为止,我在这些标题中找不到任何宏定义。增加 Atmega168 上物理引脚 14 电压的代码如下所示
DDRB = 0x01;
PORTB = 0x01;
幸运的是,Microchip 网站提供了一些基本文档,其中说明了,例如,如果我想提高物理引脚 14 上的电压,我需要按照以下步骤操作:
unsigned char *ddrB;
ddrB = (unsigned char*)0x24; // the address of ddrB is 0x24
*ddrB |= 0x01; // set up low impedance/ high current state for the transistor 0
unsigned char *portB;
portB = (unsigned char*)0x25;
*portB |= 0x01; // voltage on
*portB &= ~(0x01); // voltage off
不幸的是,这是我在潜伏一周后得到的唯一信息。现在我正在进行 USART 编程,所有这些 UBRR0H、UCSR0C 使事情变得更加复杂。由于提供的头文件不包含任何寄存器的宏定义,我还能在哪里找到它?
几年前有人问过类似的问题:accessing AVR registers with C?。然而,提供的答案有些无用,除了 GCC 本身可以将一些神话 PORTB 映射到真实物理位置的线索。有人能描述一下映射背后的机制吗?
【问题讨论】:
-
你的程序是哪个AVR?
-
"由于提供的头文件不包含任何寄存器的宏定义,我还能在哪里找到它?"你检查过数据表吗?
-
指向 SFR 的指针应声明为指向 volatile 的指针。
-
@12431234123412341234123, Atmega168
-
@12431234123412341234123,为什么不稳定?据说它们是内存映射的,即它们的地址将始终相同。它不像 Intel 芯片可以由处理器重新分配 eax-edx 地址。
标签: c pointers avr atmel avr-gcc