标签: avr

我用一个太大的程序溢出AVR的闪存吗?

我有一个项目,其中ATtiny2313V正在控制7x5 LED矩阵以显示滚动文本.为了显示文本,我构建了一个字体,该字体与程序的其余部分一起存储在闪存中.

整个程序,包括整个字体,占用1106个字节.但是当我把它加载到芯片中时,它似乎没有运行; 相反,它只是点亮了几个LED,就是这样.

但是,当我删除大部分字体,并仅使用字母A到J进行编译时,程序的大小为878字节,运行正常.

这是因为AVR闪存的某种溢出?

ATtiny2313V的数据表显示它有2KB的闪存!1106字节怎么样太多了?

更新:为了清楚起见,我使用的工具链是AVR Studio(编译代码)然后AVRDude将其上传到微控制器.据我所知,AVR Studio使用avr-gcc版本来编译代码.

avr flash-memory

3
推荐指数
1
解决办法
5636
查看次数

在嵌入式系统中存储大整数/值

我正在开发一种可以测试大量电线(最多360个)的嵌入式系统 - 本质上是一个连续性检查系统.系统通过在测试向量中计时并从另一端读取输出来工作.然后将输出与存储结果(将在SD卡上)进行比较,该结果告诉输出应该是什么.测试向量只是一个步行,所以不需要将它们存储在任何地方.这个过程有点像:

  1. 时钟输出测试矢量(步行)
  2. 读入输出测试向量.
  3. 从SD卡读取相应的输出测试向量,告诉输出向量应该是什么.
  4. 比较步骤2和3的测试向量.
  5. 记下单独数组中的错误/错误.
  6. 除非检查所有电线,否则继续返回步骤1.
  7. 将错误/故障输出到LCD.

我的硬件包含一个大型移位寄存器,用于输入AVR微控制器.对于每个测试向量(也可能是360位),我需要读取360位.因此,对于360线,数据总量将是360*360 = 16kB左右.我已经知道我不能在一个通做到这一点(即读取整个数据,然后进行比较),所以它必须通过测试向量测试向量.

由于没有固有类型可以容纳如此大的数字,我打算使用长度为360位的位数组.现在,我的问题是,我应该如何将这个位数组存储在txt文件中?

一种方法是存储原始值,即在每行存储我从移位寄存器读入的原始二进制数据.因此,对于8线,它将是0b10011010.但是对于高达360线的线路来说这可能会变得很难看 - 每条线路都包含360个字节.

另一种方法是存储十六进制值 - 这只是8位的两个字符(上面的9A)和360位的大约90个字符.这会,但是,需要我在文本阅读 - 逐行 - 并转换位阵列中表示的十六进制值,不知何故.

那么这个问题的最佳解决方案是什么?我需要解决方案完全"确定性" - 我不能调用malloc等.从我读过的内容来看,它们在嵌入式系统中有点禁忌.

摘要

我需要存储无法用任何传统变量类型表示的大值.目前我打算将这些值存储在一个bitarray中.将这些值存储在SD卡上的文本文件中的最佳方法是什么?

c embedded avr avr-gcc

3
推荐指数
1
解决办法
405
查看次数

FFT bin宽度澄清

我正在为8位Atmega32开发频谱分析仪,输出到LCD显示器上.最大采样频率为40kHz,最大频率为20kHz,符合fs> 2B.目前,我正在内部生成信号,然后将FFT应用于此信号并在LCD上查看频谱.

请注意,这是用伪代码编写的:

 #define SIG_N 128 //Number of samples in signal buffer
 #define FFT_N 64  //2*Output bins 
 uint_8 signal[SIG_N];
 uint_8 spektrum[FFT_N];

 for (int i = 0; i < SIG_N; i++){
   signal[i] = 255*sin(2*3.14*f*i / SIG_N);
 }
 computeFFT(signal,spektrum,FFT_N); //arbitrary method computes signal outputs spektrum
Run Code Online (Sandbox Code Playgroud)

输出频谱目前具有FFT_N/2 = 32个频段,每个频段代表1Hz.因此,我的频谱目前代表的最高频率(我已经测试过) - 32Hz.如何增加这些箱的"频率宽度",使每个箱子代表625Hz?请记住,由于存在内存限制,我无法将FFT_N的大小增加到64~128以上.

c avr signal-processing fft spectrum

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

为什么C++'new'运算符的实现有效?

我发现AVR uCs的C++编译器不支持newdelete运算符,但也有一个快速修复:

void * operator new(size_t size) 
{ 
  return malloc(size); 
} 

void operator delete(void * ptr) 
{ 
  free(ptr); 
}
Run Code Online (Sandbox Code Playgroud)

我假设现在可以打电话了new ClassName(args);.

但是,我不确定这是如何工作的.例如,实际上在size_t这里返回什么?我认为构造函数不返回任何东西......

难道new现在应该以不同的方式使用(与之结合使用sizeof())?

c++ memory malloc avr libc

3
推荐指数
1
解决办法
182
查看次数

AVR ATmega在主循环之前使用printf时保持重置

我正在AVR ATmega328P微控制器上使用avr-libc开发一个C应用程序.由于我没有ICE调试器,因此我按照这些说明本教程进行了诸如能够使用硬件UART等功能.stdio.hprintfstdout

这是有效的,我可以看到连接到我的目标板的PC终端上的输出,但奇怪的是:当我只有一个printf在主,但在主循环之前有什么导致处理器重置,而如果我有一个printf只在主循环内部或主循环之前和循环内部它工作正常.像这样的东西:

#include <stdio.h>

/* stream definitions for UART input/output */
FILE uart_output = FDEV_SETUP_STREAM(uart_drv_send_byte, NULL, _FDEV_SETUP_WRITE);
FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_drv_read_byte, _FDEV_SETUP_READ);

int main() {
    /* Definition of stdout and stdin */
    stdout = &uart_output;
    stdin = &uart_input;

    /* Configures Timer1 for generating a compare interrupt each 1ms (1kHz) */
    timer_init()

    /* UART initialization */
    uart_drv_start(UBRRH_VALUE, UBRRL_VALUE, USE_2X, &PORTB, 2);

    /* Sets the sleep …
Run Code Online (Sandbox Code Playgroud)

c embedded avr stdio avr-gcc

3
推荐指数
1
解决办法
2355
查看次数

avrdude:错误:不支持缓冲内存访问

我正在尝试通过Arduino 1.0.5-r2上传这个固件 sck_beta_v0_8_6。我选择了董事会。该设备是Smart Citizen Kit Urban Shield v.1.1。上传失败并显示以下错误消息:LilyPad Arduino USB

Found programmer: Id = "BÛR"; type = 
   Software Version = . ; Hardware Version = .
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

avr arduino firmware arduino-uno

3
推荐指数
1
解决办法
9058
查看次数

为什么嵌入式C++编译器不支持异常?

我正在为嵌入式系统编写一个库,我碰到了很容易找到的STL标准库.

但我收到的最糟糕的消息是编译器无异常支持.Atmel参考手册显示了这一点

为什么不支持嵌入式环境中的异常?

很简单,不可能使用很多用C++编写的库.C++与异常紧密相关,就像使用new运算符一样!

c++ embedded stl avr

3
推荐指数
2
解决办法
1553
查看次数

如何避免使用"extern"在C中的多个文件之间共享实例?

我在c中制作了一个计时器库来启动计时器,停止它......等等.我使用这个lib为不同的事件制作许多计时器.对于每个事件,我应该创建一个新的计时器实例.我使用一个带有串行通信库,一个用于键盘库.现在重点是timer_interrupt_handler(New_timer* timer)必须通过微控制器的timer1中断程序为每个实例调用一个函数,该程序保留在主文件中.为此,计时器的实例必须是外部类型.有没有办法避免在这种情况下使用extern.

timer_tick.h文件

typedef enum state{STOPPED=0, RUNNING, TIMEOUT} Timer_state;

typedef struct {
        unsigned char volatile state;
        unsigned int volatile ticks;
        unsigned int volatile timeout_ticks;
    }New_timer;
Run Code Online (Sandbox Code Playgroud)

timer_tick.c文件

#include "timer_tick.h"

void start_a_timer(New_timer* timer)
{
    timer->state = RUNNING;
    timer->ticks = 0;
}

void stop_a_timer(New_timer* timer)
{
    timer->state = STOPPED;
}

void timer_interrupt_handler(New_timer* timer)
{
    if(timer->state==RUNNING)
    {
        if(timer->ticks < timer->timeout_ticks)
            timer->ticks++;
        else
            timer->state = TIMEOUT;
    }
}
Run Code Online (Sandbox Code Playgroud)

main.c中

// timer1 interrupt routine
void timerIsr()
{
    timer_interrupt_handler(&timer1);
    timer_interrupt_handler(&timer2);
    timer_interrupt_handler(&timer3);
    timer_interrupt_handler(&timer4);
    timer_interrupt_handler(&timer5);
}
Run Code Online (Sandbox Code Playgroud)

c embedded avr

3
推荐指数
1
解决办法
305
查看次数

AVR Assembly BRNE 延迟循环如何工作?

一个在线延时循环发电机给了我0.5秒的运行时间为频率为16MHz运行该芯片延迟循环。

我心中的问题是:

  1. 如果寄存器变为负数,分支是否继续分支?
  2. 一开始加载的值究竟是如何计算的?

        ldi  r18, 41
        ldi  r19, 150
        ldi  r20, 128
    L1: dec  r20
        brne L1
        dec  r19
        brne L1
        dec  r18
        brne L1
    
    Run Code Online (Sandbox Code Playgroud)

assembly loops avr delay

3
推荐指数
1
解决办法
1万
查看次数

C++浮点数和字节数组的问题

我正在研究arduino(基于AVR平台),我有一个接收浮点数并将其写入EEPROM的方法.我必须将float转换为字节数组以与EEPROM交互.我有两个功能如下:

void WriteFloatToEEPROM(int address, float value) {
    union {
        byte byteVal[4];
        float floatVal;
    } data;

    data.floatVal = value;

    for (int i = 0; i < 4; i++) {
        EEPROM.update(address + i, data.byteVal[i]);
    }   
}

float ReadFloatFromEEPROM(int address) {
    union {
        byte byteVal[4];
        float floatVal;
    } data;

    for (int i = 0; i < 4; i++) {
        uint8_t readValue = EEPROM.read(address + i);

        data.byteVal[i] = readValue;        
    }

    return data.floatVal;
}
Run Code Online (Sandbox Code Playgroud)

当我打印出结果时,我得到以下几个例子:

Read value at address 50 for float read 0
Read …
Run Code Online (Sandbox Code Playgroud)

c++ avr unions

3
推荐指数
1
解决办法
515
查看次数