标签: avr

计算PWM的频率

这应该是一个简单的公式,但我无法弄清楚.

我有一个16mHZ的AVR芯片.

我需要运行一个PWM信号为24kHZ ..

什么是决定什么是最好的预分频器的公式.

我使用的是16位定时器.

c embedded math avr discrete-mathematics

2
推荐指数
1
解决办法
3366
查看次数

如何在Arduino中编译AVR代码?

为什么以下代码在Arduino中不起作用?

#include<avr/io.h>
void setup()
{
    DDRA = 0xFF;
}
void loop()
{
    PORTA = 0xAA;
    _delay_ms(1000);
    PORTA = 0x55;
    _delay_ms(1000);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误."DDRA未在此范围内宣布."

据我所知,arduino使用AVR微控制器,为什么我们不能在arduino板上使用AVR代码呢?

avr arduino

2
推荐指数
1
解决办法
3280
查看次数

使用Visual Studio编写AVR代码

我正在使用Visual Studio 2013为AVR编写代码.我一直在关注这个教程.

在编写代码的同时,我注意到Visual Studio继续强调像DDRB或者这样的东西,PORTB并且我继续得到错误Error: identifier "PORTB" is undefined,但是,程序正确编译.

有趣的是,在按下alt- F12视觉发现它们被定义了许多文件.

intellisense avr winavr visual-studio-2013

2
推荐指数
1
解决办法
5961
查看次数

如何在 Arduino Uno (ATmega328p) 的闪存中存储数据

我有一个使用 Arduino Uno 的项目,我需要存储一个对于 EPROM 来说太大的字符**。

我目前正在尝试使用串口来完成此操作,但如果需要的话我也可以使用 AVRISP 程序员(不推荐)

到目前为止,我已经研究了 avr/boot.h API,但我不太确定如何正确使用它,或者它是否是正确的方法。

avr atmega arduino

2
推荐指数
1
解决办法
8244
查看次数

将 IO 寄存器作为模板参数传递

我想使用 IO 寄存器(== 静态内存地址)作为模板参数。问题是,寄存器通常被定义为宏扩展到类似的东西(*(volatile uint8_t*)(11 + 0x20)),我不知何故无法正确使用我的模板。

我想编写如下代码:

Foo<PORTB> foo;
Run Code Online (Sandbox Code Playgroud)

这样我就可以轻松更改类使用的 IO 寄存器,而无需任何运行时开销(这对微控制器至关重要)。我在下面包含了一个完整的例子:

#include <stdint.h>
#include <stdio.h>
#include <utility>

#define PORTB  (*(volatile uint8_t*)(11 + 0x20))

template<volatile uint8_t* PortRegister>
class ControllerPtr final
{
public:
    static void SetHigh() { *PortRegister |= 0x2; }
};

template<volatile uint8_t& PortRegister>
class ControllerRef final
{
public:
    static void SetHigh() { PortRegister |= 0x2; }
};


int main()
{
    ControllerPtr<&PORTB> ptr;
    ControllerRef<PORTB> ref;

    ptr.SetHigh();
    ref.SetHigh();

    // Both statements should be equal to:
    // PORTB |= …
Run Code Online (Sandbox Code Playgroud)

c++ templates avr c++11

2
推荐指数
1
解决办法
552
查看次数

如何创建一个链接器只链接我的程序使用的函数的库?

我正在编译一个8位AVR微控制器(AVR-GCC)的应用程序.为了减少微控制器中的闪存使用,链接器必须仅链接应用程序代码使用的函数.我正在编写自己的库,我发现了以下声明.

"为每个代码模块编写一个函数.这将编译为每个对象模块一个函数" - 来源:http://nongnu.org/avr-libc/user-manual/library.html

这是什么意思?如何为每个函数创建单独的目标文件?现在我的库中只有一个.h文件和一个.c文件.

c microcontroller gcc avr avr-gcc

2
推荐指数
1
解决办法
122
查看次数

为什么 avr-gcc 会在函数的开头添加“push r1”指令?

我正在查看编译后编写的一些代码的生成程序集avr-gcc。具体来说,我是用-Os选项编译的。总的来说,输出是我所期望的,但我无法理解的是push r1正在发出的指令。更奇怪的是,函数末尾的补充指令是pop r0. 所以 的值r1正在被保存但它似乎被恢复到r0

根据此处的文档:

https://gcc.gnu.org/wiki/avr-gcc#Register_Layout

寄存器r1始终包含零,但函数可以在恢复寄存器时使用该寄存器。恢复它将是ldi r1, 0x0,不需要推动,从我的理解中弹出。

下面是编译版本的 C 代码和反汇编示例。它是用-Os. 它有点长,但我必须制作一个大函数才能让编译器发出它。

代码:

void mqtt_create_connect(mqtt_parser *p, mqtt_connect_config *cfg){
  uint8_t idx = 0;
  p->buffer[idx++] = MQTT_CTRL_CONNECT << 4;
  idx++; // skip remaining length for now
  p->buffer[idx++] = 0x0;
  p->buffer[idx++] = 0x4;
  p->buffer[idx++] = 'M';
  p->buffer[idx++] = 'Q';
  p->buffer[idx++] = 'T';
  p->buffer[idx++] = 'T';
  p->buffer[idx++] = 0x04; // protocol level 3.1.1
  p->buffer[idx++] = …
Run Code Online (Sandbox Code Playgroud)

assembly avr avr-gcc

2
推荐指数
1
解决办法
353
查看次数

AVR 微架构怎么可能仅在 1 个时钟周期内从 GP 寄存器获取 2 个操作数到 ALU?

根据 AVR 微控制器的数据表以及 AVR 架构的指令集数据表,某些指令,例如ADD,可以在仅 1 个时钟转换到 ALU 期间获取存储在 GP 寄存器中的 2 个操作数。指令的指令字ADD包括 2 个 GP 寄存器地址;每个 5 位宽,一个用于目标/源,一个用于源。但是这是如何在硬件级别上实现的呢?当他们试图通过相同的直接寻址总线访问 GP 寄存器时,2 个寄存器的 5 位不会相互干扰吗?

assembly avr cpu-architecture micro-architecture

2
推荐指数
1
解决办法
95
查看次数

void* (*)() 和 void* 有什么区别?

在我的一个程序中,我收到错误

invalid conversion from 'void* (*)()' to 'void*' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

我试图了解这两种数据类型之间的区别。这很令人困惑。

我认为这些数据类型是:
void* (*)()所以这个数据类型是一个指向 void ( void*)的指针,它还有另一个指针 ( (*)),并且出于某种奇怪的原因,它有空括号。所以我想象的这种数据类型的内存看起来像|--void address--|--pointer of unknown type--|--something denoting no arguments--|

然后是void*。这看起来很简单,它只代表一个函数的地址。内存模型应该像|--void address--|.

为什么这么奇怪,是抛出错误的函数如下。

void callFunction(void *voidThing){
void *testVariable = voidThing;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这会创建一个指针类型的 testVariable,并且该指针指向 void。该函数还接受一个指针类型的参数,该指针也指向 void。

为什么编译器会抛出错误,即使局部变量与参数类型相同?就两者的内存占用而言,变量之间有什么区别?

c++ microcontroller types pointers avr

2
推荐指数
1
解决办法
132
查看次数

是否可以对嵌入式软件的 C 宏进行单元测试?

我是如何为嵌入式软件测试一些特定的 C 宏的。

例如,如果我有以下宏:

/*
Set a pin as an input
port  (B,C, D or E) 
pin  - pin to set (0-7)
*/
#define _SET_INPUT_PIN(port,pin) DDR ## port &= ~(1<<pin)
#define SET_INPUT_PIN(...) _SET_INPUT_PIN(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

我想用两个端口测试它,一个存在(LED_OK)另一个不存在(LED_FAIL):

#define LED_OK   D,3
#define LED_FAIL D,8
Run Code Online (Sandbox Code Playgroud)

当我尝试测试它时,LED_OK 和 LED_FAIL 都可以正常工作,但某种警告/失败应该提醒 LED_FAIL 不存在,因为 PORTD 只定义了引脚 0 到 7。

那么,当我通过LED 时,如何检查“ pin ”是否在范围内?

c macros unit-testing avr

2
推荐指数
1
解决办法
75
查看次数