我有一个二进制文件,我使用avr-objcopy进行了反汇编.中断向量表如下所示:
00000000 :
; VECTOR TABLE
0: 13 c0 rjmp .+38 ; 0x28, RESET
2: b8 c1 rjmp .+880 ; 0x374, INT0
4: fd cf rjmp .-6 ; 0x0
6: fc cf rjmp .-8 ; 0x0
8: fb cf rjmp .-10 ; 0x0
a: fa cf rjmp .-12 ; 0x0
c: f9 cf rjmp .-14 ; 0x0
e: f8 cf rjmp .-16 ; 0x0
10: f7 cf rjmp .-18 ; 0x0
12: c7 c1 rjmp .+910 ; 0x3a2, TIMER1 OVF … (我不是母语,在术语方面可能不正确.抱歉.)
我通过无线电在AVR微控制器之间传输数据供个人使用,并希望客户能够证明传输数据的真实性,因为它来自一个授权客户端.这意味着我不要求不可否认性,并且能够预先定义共享密钥.我已经对不同的方法做了一些研究,发现我需要一些帮助来选择一个最符合我要求的方法.
请理解我不需要最高安全性.我只是想阻止潜在的脚本儿童邻居在几个小时内闯入.如果打入平均消费装备需要几个星期的时间,我会没事的.
我传输的消息尺寸相当小(不超过30个字节,只有几个字节的有效负载),频率不超过30条消息/分钟.
一个用例是运动检测器通过空中向处理单元发送消息,然后处理单元通过空中向灯开关发送另一个消息.请不要专注于运输.这个问题仅针对数据真实性.
我在具有非常有限的闪存和RAM的20 MHz AVR微控制器上运行客户端/服务器软件(在C中).所以我正在寻找一种具有小代码大小和RAM利用率的解决方案,同时仍然提供高数据速率.
我使用MD5实现(C)进行了一些性能测试,从20字节数据创建哈希值,发现它可能太慢了.我知道MD5实现本身并不能解决这个问题.我做的测试只是为了评估散列性能.
感谢您的评论
microcontroller cryptography avr authenticity cryptographic-hash-function
我正在尝试使用Atmel Atudio 6.但我不确定如何将.h文件添加到我的项目中.这是允许的吗?如果是这样,我该如何添加它们?
我很难让PID反馈和定位同时运行.
我计算RPM的想法是:
我可以计算RPM但是我只能在计算之后调用我的PID控制器(不管我想等多久才能获得良好的分辨率.)这会导致代码非常混乱.是否有更简单的方法或我缺少的东西?
关于我的应用的信息: 我正在使用直流电机/双磁编码器编程到Atmel ATmega328P,每转约600个脉冲(齿轮箱后).我想调用GoToTarget(#)并让电机在更新PID参数时转到该位置.此外,它必须双向进行.
需要注意的一些有趣的事情,我尚未完全理解。我的UART初始化为9600波特。我已经通过逻辑分析仪查看了线路上的TX,并且我发送的字节具有最小的延迟。预期为每字节36µs。
现在,如果我使用不同的波特率(例如115,200)初始化该UART,则发送的每个字节之间的延迟将大大增加。它跳至每字节125µs。
这引起了一个问题,因为我必须在某个时候提高波特率,但是响应时间有限。
延迟是否应该在字节之间减少,因为它应该以相同的频率发送更多的比特?
此阻塞方法用于写入UART。
static inline void uart2_putchar(uint8_t data)
{
// Disable interrupts to get exclusive access to ring_buffer_out.
cli();
if (ring_buffer_is_empty(&ring_buffer_out2)) {
// First data in buffer, enable data ready interrupt
UCSR2B |= (1 << UDRIE2);
}
// Put data in buffer
ring_buffer_put(&ring_buffer_out2, data);
// Re-enable interrupts
sei();
}
Run Code Online (Sandbox Code Playgroud)
这是基于中断触发的。
ISR(USART2_UDRE_vect)
{
// if there is data in the ring buffer, fetch it and send it
if (!ring_buffer_is_empty(&ring_buffer_out2)) {
UDR2 = ring_buffer_get(&ring_buffer_out2);
}
else {
// …Run Code Online (Sandbox Code Playgroud) 我现在正在教我的朋友如何编程AVR微控制器.我们编写了这个小程序,它发送简单的莫尔斯式代码.
问题是,在用AVR-GCC和WinAVR对其进行加工后,a.out文件几乎为30KB,十六进制文件为11KB,因此它不适合attiny2313闪存.
WinAVR CMD: avr-gcc -mmcu=attiny2313 -Os -g main.c
AVR-objcopy命令: avr-objcopy -O ihex a.out a.hex
这是代码:
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
void light_led(int ms)
{
PORTD |= (1 << 4);
_delay_ms(ms);
PORTD &= ~(1 << 4);
_delay_ms(1000);
}
void send_char(int c)
{
int i;
for(i = 1; i < 8+1; i++)
{
if(c & i) light_led(1000);
else light_led(500);
}
}
int main(void)
{
DDRD |= (1 << 4);
//char text[] = {'t', 'e', 's', 't'};
int i;
for(i …Run Code Online (Sandbox Code Playgroud) 昨晚我和朋友遇到了一个我们试图理解的异常,但不能.当我们使用AVR组件玩ATTiny2313时,今天我在ATMega328P上复制了Arduino的完全相同的体验.
我注意到他的代码中有一个错误,他将LED设置为高(后来为低)PINB,6.我告诉他使用PORTB,6和(由于某些其他原因)根本不起作用.整个代码现在已经消失了,所以我在Ardunio C++中复制了它并得到了意想不到的结果,正确分配时一切正常,但如果分配不正确,LED会以一半的速率闪烁.这似乎是一个阶段性的问题.
在我进入代码之前,我知道你不能分配输出PIN,问题是我们尝试(错误)并试图了解它是如何工作的.
void setup(){
DDRB=0xFF;
}
void loop(){
PORTB |= 1<<5; // turns on the LED
delay(500);
PORTB &= ~(1<<5); // turns off the LED
delay(500);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是正确的,led每500ms切换一次
void setup(){
DDRB=0xFF;
}
void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
PINB &= ~(1<<5); // turns off the LED
delay(500);
}
Run Code Online (Sandbox Code Playgroud)
现在上面的代码确实偶尔会起作用.它不是每隔500毫秒打开和关闭,而是每秒打开和关闭!
我已经检查了芯片的电路图(实际上是ATMEga128-因为我这里有PDF的硬拷贝),pp66,图30,通用数字I/O.
电路指示PINx是只读的,但你显然可以设置它,虽然它似乎需要每三个设置.
有趣的是,如果你只设置PINx(如下面的代码:)
void loop(){
PINB |= 1<<5; // turns on the LED
delay(500);
}
Run Code Online (Sandbox Code Playgroud)
LED TOGGLES!每500ms.尝试清除OUTPUT不起作用,只设置它.
同样,我知道这不是OUTPUT的设置方式,我只是想了解它为什么会这样做.
我有以下程序......
"编写一个程序,以一定的延迟连续切换PORTB的所有位.使用Timer0,正常模式,没有预分频器选项."
#include….
void T0Delay()
int main ()
DDRB= 0xFF;
while (1) {
PORTB=0x55;
T0Delay();
PORTB=0xAA;
T0Delay();
}
void T0Delay ()
{
TCNT0=0x20;
TCCR0=0x01;
while ((TIFR&01)==0);
TCCR0=0;
TIFR=0x01;
}
Run Code Online (Sandbox Code Playgroud)
在"TODelay()"函数中,"while((TIFR&01)== 0)"的功能是什么?为什么这个循环设置TCCR0 = 0和TIFR = 0x01?有人可以解释这段代码吗?
我只是失去了几天,从字面上看,大约25个小时的工作,因为我试图调试我的代码而不是我不知道的简单.
事实证明,在C++中减少单字节数组的元素,在AVR上,ATmega328 8位微控制器(Arduino)不是原子操作,需要原子访问保护(即关闭中断).为什么是这样???此外,在Atmel AVR微控制器上确保原子访问变量的所有C技术是什么?
这是我所做的一个愚蠢的版本:
//global vars:
const uint8_t NUM_INPUT_PORTS = 3;
volatile uint8_t numElementsInBuf[NUM_INPUT_PORTS];
ISR(PCINT0_vect) //external pin change interrupt service routine on input port 0
{
//do stuff here
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
numElementsInBuf[i]++;
}
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
numElementsInBuf[i]--; //<--THIS CAUSES ERRORS!!!!! THE COUNTER GETS CORRUPTED.
}
}
Run Code Online (Sandbox Code Playgroud)
这是循环的版本,没关系:
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
noInterrupts(); //globally disable interrupts
numElementsInBuf[i]--; //now it's ok...30 hrs of …Run Code Online (Sandbox Code Playgroud) AVR MCU(Arduino)会记住nointerrupts()部分中发生的所有中断吗?
void f1() {
noInterrupts();
// critical, time-sensitive code here
interrupts();
}
//now jump to queued interrupts if any
Run Code Online (Sandbox Code Playgroud)
它会在之后执行interrupts()吗?
我问这个是因为在阅读了数据表之后,我觉得所有的中断都有它们的标志,所以这可能没问题.但我不是那么经验丰富,我可能会遗漏一些东西,因为其他教程总是模糊地说"不要在那里停留太长时间,因为当时根本不会发生中断".
为什么?
我有一个循环缓冲区,我从I2C中放入一些数据包(只要发生I2C中断,它们就被放置).我也偶尔在主循环中读取这个缓冲区,在不可预测的时间允许覆盖.
另外,我在相反的方向上使用相同的缓冲类(但是不同的实例)(I2C然后触发中断和读取).
我的问题是:我想在非中断读/写期间关闭中断,所以我可以确定我不会遇到I2C触发并覆盖当前从正常主循环读取的项目的情况.
我现在有种处理与前和读取后标志的情况,因此中断首先检查的项目是免费的,但我不是这种方法有信心,我想,使其与工作noInterrupts()和interrupts()阅读主循环中.
谢谢.
avr ×10
arduino ×4
c ×4
assembly ×2
avr-gcc ×2
embedded ×2
atmega ×1
atmel ×1
atomic ×1
authenticity ×1
avr-studio5 ×1
c++ ×1
cryptographic-hash-function ×1
cryptography ×1
disassembly ×1
interrupt ×1
motordriver ×1
serial-port ×1
uart ×1
winavr ×1