我有一个项目,其中ATtiny2313V正在控制7x5 LED矩阵以显示滚动文本.为了显示文本,我构建了一个字体,该字体与程序的其余部分一起存储在闪存中.
整个程序,包括整个字体,占用1106个字节.但是当我把它加载到芯片中时,它似乎没有运行; 相反,它只是点亮了几个LED,就是这样.
但是,当我删除大部分字体,并仅使用字母A到J进行编译时,程序的大小为878字节,运行正常.
这是因为AVR闪存的某种溢出?
ATtiny2313V的数据表显示它有2KB的闪存!1106字节怎么样太多了?
更新:为了清楚起见,我使用的工具链是AVR Studio(编译代码)然后AVRDude将其上传到微控制器.据我所知,AVR Studio使用avr-gcc版本来编译代码.
我正在开发一种可以测试大量电线(最多360个)的嵌入式系统 - 本质上是一个连续性检查系统.系统通过在测试向量中计时并从另一端读取输出来工作.然后将输出与存储结果(将在SD卡上)进行比较,该结果告诉输出应该是什么.测试向量只是一个步行,所以不需要将它们存储在任何地方.这个过程有点像:
我的硬件包含一个大型移位寄存器,用于输入AVR微控制器.对于每个测试向量(也可能是360位),我需要读取360位.因此,对于360线,数据总量将是360*360 = 16kB左右.我已经知道我不能在一个通做到这一点(即读取整个数据,然后进行比较),所以它必须通过测试向量测试向量.
由于没有固有类型可以容纳如此大的数字,我打算使用长度为360位的位数组.现在,我的问题是,我应该如何将这个位数组存储在txt文件中?
一种方法是存储原始值,即在每行存储我从移位寄存器读入的原始二进制数据.因此,对于8线,它将是0b10011010.但是对于高达360线的线路来说这可能会变得很难看 - 每条线路都包含360个字节.
另一种方法是存储十六进制值 - 这只是8位的两个字符(上面的9A)和360位的大约90个字符.这会,但是,需要我在文本阅读 - 逐行 - 并转换位阵列中表示的十六进制值,不知何故.
那么这个问题的最佳解决方案是什么?我需要解决方案完全"确定性" - 我不能调用malloc等.从我读过的内容来看,它们在嵌入式系统中有点禁忌.
摘要
我需要存储无法用任何传统变量类型表示的大值.目前我打算将这些值存储在一个bitarray中.将这些值存储在SD卡上的文本文件中的最佳方法是什么?
我正在为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以上.
我发现AVR uCs的C++编译器不支持new和delete运算符,但也有一个快速修复:
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())?
我正在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) 我正在尝试通过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)
我究竟做错了什么?
我正在为嵌入式系统编写一个库,我碰到了很容易找到的STL标准库.
但我收到的最糟糕的消息是编译器无异常支持.Atmel参考手册显示了这一点
为什么不支持嵌入式环境中的异常?
很简单,不可能使用很多用C++编写的库.C++与异常紧密相关,就像使用new运算符一样!
我在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) 一个在线延时循环发电机给了我0.5秒的运行时间为频率为16MHz运行该芯片延迟循环。
我心中的问题是:
一开始加载的值究竟是如何计算的?
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)我正在研究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)