我无法让旋转编码器与AVR微控制器一起正常工作.编码器是机械ALPS编码器,我使用的是Atmega168.
澄清
我曾尝试使用外部中断来收听引脚,但看起来它太慢了.当引脚A变为高电平时,中断程序开始,然后检查引脚B是否为高电平.我们的想法是,如果引脚B变高,引脚A变高,那么它就会逆时针旋转.如果引脚B为低电平,则它按顺时针方向旋转.但似乎AVR检查引脚B需要太长时间,所以它总是读得很高.
我还尝试创建一个程序,只需阻塞直到引脚B或引脚A发生变化.但可能是旋转编码器时噪音太大,因为这也不起作用.我的最后一次尝试是有一个计时器,它将最后8个值存储在缓冲区中,并检查它是否从低到高.这也不起作用.
我已经尝试过对编码器进行范围设计,它似乎在第一个Pin的2到4ms之间使用,直到另一个Pin发生变化.
(如果你的懒惰看到TL的底部; DR)
您好,我打算建立一个处理物理计算的新(原型)项目.基本上,我有电线.这些电线都需要同时读取其电压.每根导线读数之间的差异超过几百微秒就会完全搞砸了.Arduino需要大约114微秒.因此,在延迟会影响读数的准确性之前,我能阅读的最多的是2或3条线.
所以我的计划是让一个Arduino成为一系列ATTinys的"主人".arduino相当狭窄的空间,但它与一个巨大的游乐场相比.ATTiny13A具有1k的闪存ROM(程序空间),64字节的RAM和64字节(非耐用和慢速)EEPROM.(我选择这个价格和尺寸)
我系统中的ATTinys不会做太多.基本上,他们所要做的就是等待来自Master的信号,然后读取1或2线的电压并将其存储在RAM中(如果它变得狭窄,则可能存储在EEPROM中).然后使用1根电线将数据发送给Master.(没有更多空间!).
到目前为止,我所要做的就是实现简单的电压读取代码(使用内置ADC).但这个沟通有点让我担心.您是否认为通信协议(仅使用1线!)甚至可以在这样的约束中实现?
TL; DR:在不到1k的程序空间和64字节的RAM(以及64字节的EEPROM)中,您认为可以实现1线通信协议吗?我是否需要放入装配以使其适合?
我知道目前我的Arduino程序链接到Wiring库超过8k,所以我有点担心.
我正在研究C中的微控制器DDS项目,并且在确定如何计算线性插值以平滑输出值方面遇到了一些麻烦.现在的程序
使用24位累加器的前8位作为8位输出值数组的索引.我需要提出一个函数,它将占用累加器的中间和低位字节,并在数组中的"previous"和"next"值之间生成一个值.这对于快速硬件来说足够简单,但由于我使用的是微控制器,我真的需要避免做任何浮点运算或划分!
有了这些限制,我不确定如何从我的两个8位输入数字和累加器的低2个字节获得8位插值,这表示两个输入值之间的"距离".提前感谢任何建议!
澄清
DDS =直接数字合成
在DDS中,使用相位累加器从查找表生成波形.相位累加器通常包含整数分量和分数分量.整数组件用作查找表的索引.在简单的DDS实现中,忽略小数部分,但是对于更高质量的输出,小数分量用于在相邻查找表值之间进行内插(通常只是线性内插).对于上述问题,我们正在研究如何在给定分数f,其中的两个查找表值之间有效地执行此线性插值0 <= f < 1.
我正在使用Eclipse kepler进行AVR开发.我拥有的代码是C(开源),我已经调整它以便它完美运行.我的目标是ATmega2560,采用arduino mega2560的形式.使用arduino板严格用于硬件方便; 我们正在开发硬件作为定制板,其中包含大多数核心arduino mega2560组件.
我需要在这个项目中使用几个库,它们只能用作arduino库,即电子纸屏幕库(来自seeedstudio)和Nordic的BLE nRF8001.
如果我在eclipse中使用插件创建一个新的arduino项目,我可以完美地构建和运行arduino库的测试.
当我尝试将两个代码库合并在一起时,我似乎无法调用添加的arduino库中的函数 - 如果我调用它们,编译器会抛出链接错误.
Building target: Virgin2ManualArdInsert.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,Virgin2ManualArdInsert.map -mmcu=atmega2560 -o "Virgin2ManualArdInsert.elf" ./avr/adc.o ./avr/eeprom.o ./avr/lcd_and_input.o ./avr/main.o ./avr/strings.o ./avr/unimplemented.o ./avr/usart.o ./aes.o ./baseconv.o ./bignum256.o ./ecdsa.o ./endian.o ./fft.o ./fix16.o ./hash.o ./hmac_sha512.o ./messages.pb.o ./p2sh_addr_gen.o ./pb_decode.o ./pb_encode.o ./pbkdf2.o ./prandom.o ./ripemd160.o ./sha256.o ./statistics.o ./stream_comm.o ./test_helpers.o ./transaction.o ./wallet.o ./xex.o
./avr/main.o: In function `main':
main.c:(.text.startup.main+0xc): undefined reference to `writeEink'
collect2: error: ld returned 1 exit status
makefile:53: recipe for target 'Virgin2ManualArdInsert.elf' failed
make: *** [Virgin2ManualArdInsert.elf] Error 1 …Run Code Online (Sandbox Code Playgroud) 我正在使用Yosemite OS X在Mac上工作,我正在尝试用C编译一个程序,然后我可以上传到我的Arduino.我正在学习一个教程.
我试过并重新安装avr-gcc,但我得到了相同的输出.我尝试crtatmega328p.o在我的系统上搜索该文件,但它无处可寻,目录也是如此.
$ avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o Program.o Program.c
$ avr-gcc -mmcu=atmega328p Program.o -o Program
/usr/local/lib/gcc/avr/5.2.0/../../../../avr/bin/ld: cannot find crtatmega328p.o: No such file or directory
/usr/local/lib/gcc/avr/5.2.0/../../../../avr/bin/ld: cannot find -latmega328p
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud) 我正在尝试在没有FPU的CPU上实现对double和的支持float以及相应的基本算法。
我知道这一切都有可能AVR ATmega controllers。ATmega也没有FPU。因此出现了一个问题:它是如何工作的?是否有任何文献建议或带有解释和实例的链接?
在最好的情况下,我将为以下代码提供支持:
double twice ( double x )
{
return x*x;
}
Run Code Online (Sandbox Code Playgroud)
提前谢谢,亚历克斯
在程序中,我使用定时器中断循环通过LED,如果有人按下开关,它应该停止第一个中断并触发第二个应该根据按下的开关点亮LED.在这里,我有点困惑,正在调用哪个中断.我为Pin Change Interrupt提到了一些书,并为设置PCMSK2写了几行.我得到的输出是"最初所有的LED都在循环,当按下一个开关...... LED的循环停止并重新开始(这意味着程序正在读取输入,只是没有触发第二次中断).它不会停止或者暂停并且不会点亮随后的领导." 有人可以帮忙吗?
#include <avr/io.h>
#include <avr/interrupt.h>
#define PINK_MASK \
((1<<PINK0)|(1<<PINK1)|(1<<PINK2)|(1<<PINK3)|(1<<PINK4)|(1<<PINK5)|(1<<PINK6)|(1<<PINK7))
volatile unsigned int intrs, i=1;
void enable_ports(void);
void delay(void);
extern void __vector_23 (void) __attribute__ ((interrupt));
extern void __vector_25 (void) __attribute__ ((signal));
void enable_ports()
{
DDRB = 0xff; //PORTB as output for leds
PORTB = 0xff;
DDRK = 0x00; //PORTK as input from switches
PORTK |= PINK_MASK;
PCMSK2 = PINK_MASK; //ENABLE PCMSK2, Setting interrupts
PCICR = 0x04;
PCIFR = 0x04;
TCCR0B = 0x03; //Setting TIMER
TIMSK0 = 0x01; …Run Code Online (Sandbox Code Playgroud) 我目前正在为 AVR 微控制器上的 USB 设备创建固件。由于 USB 时序非常严格,因此我不能允许非 USB 中断阻塞超过几个指令周期。因此,我的 USART RXC(接收到的字符)中断如下所示:
\n\nvoid usart_rxc_wrapped() __attribute__ ((interrupt));\nvoid usart_rxc_wrapped(){\n uint8_t c=UDR;\n if(!ringBufferFull(&rx)){\n ringBufferWrite(&rx, c);\n }\n // Reenable nterrupt\n UCSRB|=1<<RXCIE;\n}\n\n// This cannot be ISR_NOBLOCK, since the interrupt would go\n// into infinite loop, since we wouldn\'t get up to reading\n// UDR register. Instead, we use assembly to do the job\n// manually and then jump to the real handler.\nISR(USART_RXC_vect, ISR_NAKED){\n // Disable this interrupt by clearing its Interrupt Enable flag.\n __asm__ volatile("cbi %0, %1"::\n "I"(_SFR_IO_ADDR(UCSRB)),"I"(RXCIE));\n …Run Code Online (Sandbox Code Playgroud) 提前道歉,因为我对这个主题还不太了解,并且仍在学习编译器的内部工作原理。
我目前正在研究在嵌入式系统中使用 D 的可能性,并发现一篇文章提到 AVR 后端如何合并到上游 LLVM 项目中,以便开发人员可以致力于为他们的语言创建 AVR 支持。D 有 LDC 编译器,它使用 LLVM 后端。不过,这篇文章还提到了 avr-gcc 的使用,这让我对在哪个阶段使用哪些工具从 D 源代码到 AVR 二进制文件有点困惑。我假设 LDC 将源代码转换为 LLVM IR,然后转换为二进制,所以我不确定 avr-gcc 的用途。
有人可以更详细地向我解释这一点吗?
解决方案:
\n事实证明它与 USART 没有任何关系。问题出在 Makefile 中。我重复使用了长期以来一直用于 atmega328p 和 atmega2560 的 Makefile。但是在将 elf 转换为 hex 文件时,此 Makefile 不包含 .rodata 部分。我想这部分从来没有用于“旧的”atmega 部件。在十六进制文件中包含 .rodata 部分后,一切都按 atmega4809 的预期工作。
\nMakefile 之前的部分:
\n$(OUT).hex: $(OUT).elf\n rm -f $(OUT).hex $(OUT).eep.hex\n $(OBJCOPY) -j .text -j .data -O ihex $(OUT).elf $(OUT).hex\n $(SIZE) $(OUT).hex\nRun Code Online (Sandbox Code Playgroud)\n之后的 Makefile 部分:
\n$(OUT).hex: $(OUT).elf\n rm -f $(OUT).hex $(OUT).eep.hex\n $(OBJCOPY) -j .text -j .data -j .rodata -O ihex $(OUT).elf $(OUT).hex\n $(SIZE) $(OUT).hex\nRun Code Online (Sandbox Code Playgroud)\n原问题:
\n以下代码的结果是:
\n\n$(OUT).hex: $(OUT).elf\n rm -f …Run Code Online (Sandbox Code Playgroud)