我正在连接一个测试一组电线的程序,用于开路或短路.该程序在AVR上运行,将测试向量(步进'1')驱动到导线上并接收结果.它将该结果向量与已存储在SD卡或外部EEPROM中的预期数据进行比较.
这是一个例子,假设我们有一组8条线,所有这些线都是直通的,即它们没有连接点.因此,如果我们驱动0b00000010,我们应该收到0b00000010.
假设我们收到0b11000010.这意味着线7,8和线2之间存在短路.我可以通过0b00000010 ^ 0b11000010 = 0b11000000检测我感兴趣的位.这告诉我显然线7和8有故障,但我如何在大位阵列中有效地找到这些'1'的位置.使用位掩码只需8线即可轻松完成此操作,但我正在开发的系统必须能够处理多达300线(位).在我开始使用如下的宏并测试300*300位数组中的每个位之前,我想问一下是否有更优雅的解决方案.
#define BITMASK(b) (1 << ((b) % 8))
#define BITSLOT(b) ((b / 8))
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITCLEAR(a,b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
#define BITTEST(a,b) ((a)[BITSLOT(b)] & BITMASK(b))
#define BITNSLOTS(nb) ((nb + 8 - 1) / 8)
Run Code Online (Sandbox Code Playgroud)
只是为了进一步说明如何检测开路.预期数据:0b00000010,接收数据:0b00000000(导线未拉高).0b00000010 ^ 0b00000000 = 0b0b00000010 - 导线2打开.
注意:我知道测试300线不是AVR Mega 1281内部的微小RAM可以处理的东西,这就是为什么我将它分成组,即测试50线,比较,显示结果然后前进.
首先是一些背景.在微小的数据中,数据可以存储在寄存器,sram,eeprom或程序空间中.寄存器和sram是易失性存储,而eeprom和程序空间则不是.(即:未通电时数据停留.)
在c中编程时(使用avr-gcc库),典型代码可能如下所示:
#define F_CPU 8000000UL
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//This data is put in the eeprom
const uint8_t dat_eeprom EEMEM= 0xab;
//This data is put in the program space
const uint8_t dat_pgm_space PROGMEM= 0xcd;
//This data is stored in the sram
uint8_t dat_sram = 0xef;
int main(){
while(1){
;;
}
}
Run Code Online (Sandbox Code Playgroud)
编译:
avr-gcc -g -mmcu=attiny44 -o test.elf test.c
Run Code Online (Sandbox Code Playgroud)
并从.elf中提取intel .hex:
avr-objcopy -j .text -j .data -O ihex test.elf test.hex
Run Code Online (Sandbox Code Playgroud)
我们得到以下test.hex:
:1000000011C023C022C021C020C01FC01EC01DC0FF
:100010001CC01BC01AC019C018C017C016C015C01C
:1000200014C0CD0011241FBECFE5D1E0DEBFCDBF8F
:1000300010E0A0E6B0E0EAE5F0E002C005900D9225
:10004000A236B107D9F702D006C0DACFCF93DF933B
:0A005000CDB7DEB7FFCFF894FFCF65 …Run Code Online (Sandbox Code Playgroud) 首先,我想说我是崇高文本编辑器的新手,我喜欢它.我没有使用JSON的经验,但它看起来并不困难.
我正在尝试编写一个构建系统,它将调用一个bash脚本,将一个makefile移动到我正在工作的目录中并调用makefile,它将使用avr-gcc编译我的c代码然后使用它将其闪存到连接的微控制器上AVRDUDE.
我意识到sublime text 2只能有一个"cmd"对象,所以我尝试从终端模拟器调用一行中的所有东西,它完全符合我的预期.电话是:
checkAVRmakefile.sh $PWD; make PROJECTNAME+=hello install
Run Code Online (Sandbox Code Playgroud)
我的脚本位于我的$ PATH环境变量的目录中,我将它传递给我正在使用的目录,因此它在那里检查makefile,如果它不存在,则从我保留所有目录的目录中复制它我的makefile.然后我调用make并将其命名为I,并调用该项目并安装闪存avr微控制器.
我用崇高做的是这样的:
{
"shell":true,
"cmd":[ "checkAVRmakefile.sh", "$file_path", ";" ,"make","PROJECTNAME+=$file_base_name","install"],
}
Run Code Online (Sandbox Code Playgroud)
这只运行bash脚本,它将makefile放在目录中但不运行make.
有谁看到我哪里出错了?
任何帮助表示赞赏.我也在崇高的论坛上问过类似的问题,但没有人回答.我也在Ubuntu上使用ST2.
我目前正在尝试设置工具链,以便可以从 CLion 构建 AVR 项目。
我的出发点是这个,特别是 Blink 示例。问题在于,它与现有的用于 AVR 示例的 CMake 一起,都适用于基于 Linux 的系统。
我试过的是安装 WinAVR 来获取可执行文件。我修改了 CMakeList.txt,因此程序名称包含以下内容:
set(AVRCPP "C:/WinAVR-20100110/bin/avr-g++")
set(AVRC "C:/WinAVR-20100110/bin/avr-gcc")
set(AVRSTRIP "C:/WinAVR-20100110/bin/avr-strip")
set(OBJCOPY "C:/WinAVR-20100110/bin/avr-objcopy")
set(OBJDUMP "C:/WinAVR-20100110/bin/avr-objdump")
set(AVRSIZE "C:/WinAVR-20100110/bin/avr-size")
set(AVRDUDE "C:/WinAVR-20100110/bin/avrdude")
set(AVRAS "C:/WinAVR-20100110/bin/avr-as")
Run Code Online (Sandbox Code Playgroud)
在使用 Cygwin 环境时,CMake 可以毫无问题地找到我的编译器,但是当我尝试构建项目时,avr-gcc 正在以 Linux 格式传递参数。
C:/WinAVR-20100110/bin/avr-gcc.exe -o CMakeFiles/cmTryCompileExec420260872.dir/testCCompiler.c.obj -c /cygdrive/c/Users/Daniel/.clion10/system/cmake/generated/2eb381d5/2eb381d5/__default__/CMakeFiles/CMakeTmp/testCCompiler.c
avr-gcc.exe: /cygdrive/c/Users/Daniel/.clion10/system/cmake/generated/2eb381d5/2eb381d5/__default__/CMakeFiles/CMakeTmp/testCCompiler.c: No such file or directory
Run Code Online (Sandbox Code Playgroud)
有没有办法让 CMake 以它可以使用的格式传递 avr-gcc 参数?
作为参考,这是完整的输出:
Error:The C compiler "C:/WinAVR-20100110/bin/avr-gcc" is not able to compile a simple test program.
It fails with the following output: …Run Code Online (Sandbox Code Playgroud) Atmega162我正在写和之间的通信PC。
在我的PCBI 上有接口RS485(从 转换RS422而来MAX485),它通过ADAM-4520收发器进入COM port。
我一直在终端中测试我的程序,这对我来说似乎很奇怪,发送字符MCU工作正常,但接收到的字符PC被更改了(我无法弄清楚这种转换的任何方案)。
例如,这些 ASCII 字符的解释方式如下:
0 => 0
1 => 64
2 => 32
3 => 32
4 => 16
5 => 65
6 => 16
7 => 16
8 => 8
'1' => 204
'2' => 102
'3' => 70
'4' => 51
'5' => 141
'6' => 35
'7' => 51
'8' => 6
'9' …Run Code Online (Sandbox Code Playgroud) 我在 Linux 上使用 Eclipse CDT Mars 4.5.0 20150621-1200 来进行涉及 AVR 微控制器的固件项目。Eclipse 给我错误,如“无法解析类型‘uint8_t’”。
我正确添加/usr/lib/avr/include到项目属性 -> C/C++ 常规 -> 路径和符号 -> 包含。
当我尝试在 Eclipse 中打开声明时,uint8_t我得到以下结果:
这表明 Eclipse 检测到了 2 个声明,但无法确定哪一个是正确的。这对我来说很奇怪,因为/usr/include在“路径和符号”->“包含”下没有特色。
如何解决这种疼痛?谢谢!
你好堆栈溢出的人.我的问题是一个看似永远不会执行的中断服务程序(ISR)!以下是我设置的一些信息:我正在闪烁avr attiny85.到目前为止,我只使用main.c和两个模块设置项目的基础:timer和hardwareInit.在定时器模块中,我有一个timer0_init函数,我用它来设置Timer0以使CTC模式在1 ms内溢出.这是功能:
void timer0_init( void )
{
cli();
TCCR0B |= 3; //clock select is divided by 64.
TCCR0A |= 2; //sets mode to CTC
OCR0A = 0x7C; //sets TOP to 124 so the timer will overflow every 1 ms.
TIMSK |= 2; //Enable overflow interrupt
sei(); //enable global interrupts
}
Run Code Online (Sandbox Code Playgroud)
设置定时器后,每次计数器溢出时我都会添加一个ISR来增加滴答,这样我就可以跟踪已经过了多长时间等等.
ISR(TIMER0_OVF_vect)
{
cli();
//ticks ++;
PORTB |= ( 1 << PORTB0 );
sei();
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我注释掉了滴滴答用器因为它没有工作,并用PORTB |= ( 1 << PORTB0 );简单的LED打开就取而代之,所以如果中断被执行,我会通过证明LED亮起来知道.
不幸的是,我无法让它打开,看不到我错过的东西.(为了证明我1.将LED设置在右侧引脚上,并且2.正在操作正确寄存器中的正确位,我将此声明PORTB |= ( 1 …
AVR C编译器是否让程序记住SRAM中函数开始将其数据(变量,数组)存储在数据堆栈中索引寄存器之一的地址,以便通过公式获得局部变量的绝对地址:
absoluteAdr = functionDataStartAdr + localShiftOfVariable.
Run Code Online (Sandbox Code Playgroud)
当由其长度声明的变量或堆栈指针在函数的结尾/开始处增加时,它们是否会增加数据堆栈点,因为它的所有变量长度。
我想知道是否可以编写std::atomic<>供 AVR \xc2\xb5C 使用的内容。__atomic_xxx()不幸的是,avr-gcc 中没有实现内置函数。
据我了解,uint8_tAVR 上的基本加载/存储是原子的,但例如operator++()不是因为它意味着 rmw 循环。因此,对于这些操作,必须禁用中断,因为这是该硬件上唯一的并发形式。对于更大的类型,uint8_t甚至operator=(T)需要防止中断。
另一方面,必须对模板的数据成员应用内存屏障:例如,该数据成员具有必须使用的std::atomic<>名称来完成机器上的实际加载/存储。valueasm volatile("" : "+m" (value));
这足以实施吗std::atomic<>?
由于此实现是无锁的,因此它应该可用于该硬件上的 ISR。
\n如果要实现这一点,std::atomic<>这将导致ISR内的机器代码效率低下,因为不必要的中断禁用和/或内存屏障会阻止优化。
std::atomic<>好吧,这可以通过扩展不安全操作的接口来规避。
另一方面:std::atomic_ref<>在 ISR 之外实施和使用它是否更可行?
我面临的问题是 Attiny167 和 Attiny87 尽管在数据表上说它们是替代品,但实际上并非如此。该程序是用AVR汇编语言编写的。
Attiny87 的向量表使用 RJMP,而 Attiny167 使用 JMP。这意味着我的程序中需要两个单独的向量表实例,但我认为这是不可能的。有没有办法编写代码,以便程序可以检查签名字节以检查哪个硬件设备打开,然后使用适当的“jmp”指令?谢谢。
到目前为止,我已经尝试使用所需的 jmp 指令编写程序的两个单独实例,但是我需要一种方法让程序自动执行此操作,而不必手动检查。