Tag: avr

许多客户端打印后,Arduino(Uno)以太网客户端连接失败

我正在使用带有以太网盾的Arduino Uno。 发送许多HTTP请求后, client.println(…) ,连接时客户端开始失败。 失败的时间似乎是随机的,并且循环的序列读数可以在~1000到~7000之间的任何地方变化。 该错误与以太网发送缓冲区溢出无关(遵循此建议 ) 这是失败的代码: #include #include // Network constants byte mac[] = {0x00, 0x23, 0xdf, 0x82, 0xd4, 0x01}; byte ip[] = {/*REDACTED*/}; byte server[] = {/*REDACTED*/}; int port = /*REDACTED*/; Client client(server, port); // State int sequence; void setup(){ Ethernet.begin(mac, ip); Serial.begin(9600); sequence = 0; delay(1000); } void loop(){ httpPut(“/topic/:test/publish?sessionId=SESenanhygrp”); […]

在位数组中有效地找到’1’的位置

我正在连接一个测试一组电线的程序,用于开路或短路。 该程序在AVR上运行,将测试向量(步行’1’)驱动到导线上并接收结果。 它将此结果向量与已存储在SD卡或外部EEPROM中的预期数据进行比较。 这是一个例子,假设我们有一组8条线,所有这些线都是直通的,即它们没有连接点。 因此,如果我们驱动0b00000010,我们应该收到0b00000010。 假设我们收到0b11000010。 这意味着线7,8和线2之间存在短路。我可以通过0b00000010 ^ 0b11000010 = 0b11000000检测我感兴趣的位。 这告诉我显然线7和8有故障,但我如何在一个大的位arrays中有效地找到这些’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) 只是为了进一步说明如何检测开路。 预期数据:0b00000010,接收数据:0b00000000(导线未拉高)。 […]

初始化变量并同时指定存储地址:是否可能?

例如,在Atmel处理器的codevision编译器中,可以指定全局变量的存储地址 int a @0x100; // will place the variable at the address 0x100 in RAM 当然,根据标准C,变量可以在声明时初始化 int a=42; 但是,我没有发现任何可能同时做到这两点。 int a @0x100 = 42或int a = 42 @0x100; 不起作用,它们会导致编译器错误。 你可能会问为什么这么做很重要,因为人们可以这样做 int a @0x100; int main() { a = 42; //… } 但是,如果我在EEPROM中有变量,我需要初始化它们,因为这是自动生成带有值的eeprom文件的唯一方法。 我不能在以后分配这些值,因为在这种情况下,它实际上会在程序的每个开始时将值写入eeprom。

为什么这个编译器障碍不强制执行排序?

我正在查看Atmel网站上的文档,我遇到了这个例子 ,他们解释了重新排序的一些问题。 这是示例代码: #define cli() __asm volatile( “cli” ::: “memory” ) #define sei() __asm volatile( “sei” ::: “memory” ) unsigned int ivar; void test2( unsigned int val ) { val = 65535U / val; cli(); ivar = val; sei(); } 在这个例子中,他们正在实现一个类似于关键区域的机制。 cli指令禁用中断,sei指令启用它们。 通常,我会保存中断状态并恢复到该状态,但我离题了…… 他们注意到的问题是,在启用优化的情况下,第一行上的除法实际上会在cli指令之后移动到。 当您尝试尽可能在最短的时间内进入关键区域时,这可能会导致一些问题。 为什么如果cli()MACRO扩展为内联asm明显破坏内存,这怎么可能呢? 编译器如何在此语句之前或之后自由移动? 另外,我修改了代码以在__asm volatile(“” ::: “memory”);forms的每个语句之前包含内存屏障__asm volatile(“” ::: “memory”); 它似乎没有改变任何东西。 […]

在没有双精度类型的C编译器上解析双精度IEEE浮点

我正在使用8位AVR芯片。 64位double没有数据类型(double只映射到32位float)。 但是,我将通过串口接收64位双打,并且需要通过串行输出64位双打。 如何在不进行转换的情况下将64位双精度转换为32位浮点数并再次返回? 32位和64位的格式都遵循IEEE 754.当然,我假设转换为32位浮点时精度会下降。 为了从64位转换为32位浮点数,我正在尝试这样做: // Script originally from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1281990303 float convert(uint8_t *in) { union { float real; uint8_t base[4]; } u; uint16_t expd = ((in[7] & 127) <> 4); uint16_t expf = expd ? (expd – 1024) + 128 : 0; u.base[3] = (in[7] & 128) + (expf >> 1); u.base[2] = […]

更快的16位乘法算法,适用于8位MCU

我正在寻找一种算法来乘以两个比下面更好的整数。 你有一个好主意吗? (MCU – AT Tiny 84/85或类似 – 此代码运行的地方没有mul / div运算符) uint16_t umul16_(uint16_t a, uint16_t b) { uint16_t res=0; while (b) { if ( (b & 1) ) res+=a; b>>=1; a+=a; } return res; } 当使用avr-gcc编译器为AT Tiny 85/84编译时,该算法几乎与avr-gcc生成的算法__mulhi3相同。 avr-gcc算法: 00000106 : 106: 00 24 eor r0, r0 108: 55 27 eor r21, r21 10a: 04 […]

为什么我只收到第一个地址字节? (I2C协议)

期望奴隶确认并返回数据,但事实并非如此。 这是我的协议 。 这是我的数据表 数据表提到“从器件将通过首先发送带有MSB的字节来应答。字节0和字节1包含预测值。所有字节都由主器件确认。” 编辑: 源库 另外,仅供我参加Arduino Fio,但我没有inheritanceArduino库。 #include #include #include #include #include #define LED PB5 #define I2C_READ 0x5A char buffer[1]; //char data[9]; uint16_t val = 0; uint8_t status = 0; void getVal() { if(i2c_start(I2C_READ)) { uart_puts(“Start “); val = ((uint8_t)i2c_read_ack())<<8; val |= i2c_read_ack(); status = ((uint8_t)i2c_read_nack()); i2c_stop(); } else { uart_puts("Error"); i2c_stop(); } […]

#define C中的元组

我希望能够定义一个表示其他宏所需参数的元组。 我认为展示我想要的最好方法是展示一个例子: #include #define LED_PORT PORTB #define LED_DDR DDRB #define LED_PIN PB7 #define LED LED_PORT, LED_DDR, LED_PIN #define OUTPUT(port, ddr, pin) ddr |= 1 << pin void main(void) { OUTPUT(LED); } 我想将OUTPUT(LED)扩展为: LED_DDR |= 1 << LED_PIN 我得到的问题是扩展的顺序,并导致以下错误: 宏“OUTPUT”需要3个参数,但只有1个参数 这适用于具有定制硬件的AVR项目,其中我已经定义了LED和其他具有相应LED_PORT LED_DDR和LED_PIN 。 然后我想要定义更多的宏,这些宏可以使用这个LED并使用适当的参数来映射到最简洁的方式。 这是否可以使用标准的C预处理器?

如何在avr中存储十进制格式的数字

我想尝试使用ATMega8中的键盘输入小数值,直到现在我只能输入整数值代码如下 switch (keyCode) { case (0xee): keyPressed=”1″; b=1; a=a*10+b; break; case (0xed): keyPressed=”4″; b=4; a=a*10+b; break; case (0xeb): k keyPressed=”7″; b=7; a=a*10+b; break; case (0xde): keyPressed=”2″; b=2; a=a*10+b; break; case (0xdd): keyPressed=”5″; b=5; a=a*10+b; break; case (0xdb): keyPressed=”8″; b=8; a=a*10+b; break; case (0xd7): keyPressed=”0″; b=0; a=a*10+b; break; case (0xbe): keyPressed=”3″; b=3; a=a*10+b; break; case (0xbd): […]

嵌入式处理器的快速斜边算法?

是否有一个聪明/有效的算法来确定角度的斜边(即sqrt(a² + b²) ),在没有硬件乘法的嵌入式处理器上使用定点数学运算?