在嵌入式系统(基于AVR控制器)和iPhone之间实现无线通信的最佳方法是什么?我认为只有两种选择:WiFi或BlueTooth.范围不是真正的问题,因为两个设备应该保持在同一个房间.
我不知道,如果有任何有用的WiFi板可以连接到基于AVR的微控制器系统(或任何小型微控制器),任何提示都将受到高度欢迎.
我想更好的解决方案是BlueTooth,但也存在问题:哪个BlueTooth板最适合连接到AVR系统,是否可以使用iPhone BlueTooth堆栈通过BlueTooth与AVR设备进行(串行)通信.
我希望有人已经意识到这样一个系统并且可以提供一些有用的提示......
我正在为 AVR 芯片编写 C 代码。该代码在等待串行端口、ADC 和定时器的中断服务例程上很繁重。ISR 写入缓冲区,当主循环到达它们时会检查这些缓冲区。
我设计了缓冲区,以便 ISR 可以在主循环读取它们时更新它们。我想验证这是否有效。我有单元测试来验证基本操作,但我不清楚如何测试如果在主循环读取缓冲区时触发中断会发生什么。
我的单元测试非常基础——功能中的一些代码main()。我在我的 Linux 机器上运行测试。
在程序中,我使用定时器中断循环通过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) 在学习C代码时尝试一下,我想测试一下.它按预期工作,但抛出警告
警告1来自不兼容指针类型的分配[默认启用]
代码很简单.我在这里所做的就是在atmega2560上切换PIN B7.我有一个LED挂钩,我可以看到它闪烁,所以我知道它按预期工作.
任何人都可以解释为什么我看到这个错误,即使它按预期执行?代码如下:
#include <avr/io.h>
#include <util/delay.h>
void main(void) {
int *ptr;
ptr = &PORTB; // This line throws the warning
DDRB = (1 << 7);
while(1) {
*ptr = (1 << 7);
_delay_ms(1000);
*ptr = (0 << 7);
_delay_ms(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
PORTB是一个8位寄存器,每个引脚有一位用于控制该引脚是高电平还是低电平.
现在,我很高兴它有效.但这些警告让我烦恼.
我想为AVR制作启动加载程序代码,它可以通过无线方式更新固件.
现在我可以使用一些固定数据写入应用程序区域.我有一个要更新的新固件的hex文件.如何将该hex文件转换为原始数据,以便我可以使用该原始数据更新应用程序?
我已经搜索了几天没有任何运气。
堆内存碎片是在微控制器/Arduino 中大量使用 malloc() 和 free() 的结果。
如果使用它们是不可避免的,我如何不时对堆进行碎片整理以确保下一个 malloc() 调用将找到要分配的连续内存?
我的问题是我将如何在 avr - c 中制作文件,然后将它们编译到 avr mkii isp。
我只是简单地创建 ac 文件,将我的 avr - c 代码放入其中,然后在终端中键入命令将其导出到 isp 还是有更复杂的过程?
PS,当涉及到 Arch linux 时,我是一个完整的新手
我原以为 8 位 AVR 平台不需要任何对齐。但是,我在LLVM commit 中发现了以下评论:
以前的数据布局在处理原子时引起了问题。
例如,加载小于 16 位对齐的 16 位值是非法的。
这会更改数据布局,以便所有类型至少以它们自己的宽度对齐。
不幸的是,这个提交的原作者也不确定这是否正确:
自从我最初从 SourceForge 导入旧的 SVN 存储库以来,大部分对齐内容都没有受到影响。我没有处理过太多,所以我的知识很差。
最安全的假设是,如果某件事看起来是故意的,那可能不是;P
(8 位)AVR 上的对齐故事究竟是什么?
我想检查 AVR-GCC 编译器如何编译乘法?
输入 c 代码:
unsigned char square(unsigned char num) {
return num * num;
}
Run Code Online (Sandbox Code Playgroud)
输出汇编代码:
square(unsigned char):
mul r24,r24
mov r24,r0
clr r1
ret
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么要添加该语句clr r1?表面上,假设参数存储在 r24 中并且返回值在 r24 中可用,则可以删除此语句并仍然获得所需的结果。
直接 Godbolt 链接:https ://godbolt.org/z/PsPS_N
我还在这里看到了相关的更一般性讨论。
最近我试图将我的代码打包到带有 1kB 闪存的小型 ATTiny13 中。在优化过程中,我发现了一些奇怪的东西。让我们以示例代码为例:
#include <avr/interrupt.h>
int main() {
TCNT0 = TCNT0 * F_CPU / 58000;
}
Run Code Online (Sandbox Code Playgroud)
它当然没有意义,但有趣的是输出大小 - 它产生248 bytes。
代码快速说明:F_CPU是由-DF_CPU=...switch for定义的常量avr-gcc,TCNT0是 8 位寄存器(在 ATTiny13 上)。在实际程序中,我将方程结果分配给uint16_t,但仍然观察到相同的行为。
如果表达式的一部分被括在括号中:
TCNT0 = TCNT0 * (F_CPU / 58000);
Run Code Online (Sandbox Code Playgroud)
输出文件大小为70 字节。巨大的差异,但这些操作的结果是相同的(对吧?)。
我查看了生成的汇编代码,尽管我不太了解 ASM,但我看到无括号版本添加了一些标签,例如:
00000078 <__divmodsi4>:
78: 05 2e mov r0, r21
7a: 97 fb bst r25, 7
7c: 16 f4 brtc .+4 ; 0x82 <__divmodsi4+0xa>
7e: 00 94 …Run Code Online (Sandbox Code Playgroud)