gpt4 book ai didi

c - 使用 MCU-ATMega 1280 进行多中断实时数据记录

转载 作者:行者123 更新时间:2023-11-30 18:01:10 24 4
gpt4 key购买 nike

我的问题是关于实时数据记录和多中断。我正在尝试通过 winAVR 对 MCU-ATMega 1280 进行编程,使其从正交编码器(20um/pitch)读取脉冲并将数据存储到闪存(Microchip SST25VF080B,串行 SPI 协议(protocol))中。编码器完成操作后(大约2分钟),MCU将数据从内存导出到屏幕。我的代码如下。

但是我不知道为什么它不能正确运行。有两种错误:一种错误是某些点突然偏离趋势,另一种错误是尽管编码器运行缓慢但值突然跳跃。跳跃似乎只有在转弯时才会出现。

我认为问题可能仅在于数据存储,因为除了跳跃之外,趋势的发生与我的预期一致。我只是想问我是否像我在程序中所做的那样运行两个 ISR。一个 ISR 运行时是否会被另一个 ISR 干预?根据atmega 1280数据表,似乎当一个ISR发生时,在前一个中断完成其例程后不允许发生其他中断。

    #include <stdlib.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "USART.h" // this header is for viewing the data on the computer
#include "flashmemlib.h" // this header contains the function to read n
//write on the memory

#define MISO PB3
#define MOSI PB2
#define SCK PB1
#define CS PB0
#define HOLD PB6
#define WP PB7
#define sigA PD0 //INT0
#define sigB PD2 //INT2
#define LED PD3


uint8_t HADD,MADD,LADD, HDATA, LDATA,i; //HADD=high address, MADD-medium address, LADD-low address
volatile int buffer[8]; //this buffer will store the encoder pulse
uint32_t address = 0;
uint16_t DATA16B = 0;

int main(void)
{
INITIALIZE(); //initialize the IO pin, timer CTC mode, SPI and USART protocol
for(i=0;i<8;i++)
buffer[i]=0;

sei();

//AAI process- AAI is just one writing mode of the memory
AAIInit(address,0);
while (address < 50) //just a dummy loop which lasts for 5 secs (appox)
{
_delay_ms(100);
address++;
}
AAIDI();//disable AAI process
cli(); //disable global interrupt
EIMSK &= ~(1<<INT0);
TIMSK1 &= ~(1<<OCIE1A);

//code for reading procedure. i thought this part is unnecessary because i am quite //confident that it works correcly
return (0);
}


ISR(INT0_vect) // this interrupt is mainly for counting the number of encoder's pulses
{ // When an interrupt occurs, we only have to check the level of
// of pB to determine the direction
PORTB &= ~(1<<HOLD);
for(i=0;i<8;i++)
buffer[i+1]=buffer[i];

if (PIND & (1<<sigB))
buffer[0]++;
else buffer[0]--;
PORTB |= (1<<HOLD);
}

ISR(TIMER0_COMPA_vect) //after around 1ms, this interrupt is triggered. it is for storing the data into the memory.
{
HDATA =(buffer[7]>>8)&0xFF;
LDATA = buffer[7]&0xFF;
PORTB &= ~(1<<CS);
SEND(AD);
SEND(HDATA);
SEND(LDATA);
PORTB |=(1<<CS);
}

void SEND(volatile uint8_t data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))){} // Wait the end of the transmission
}
uint8_t SREAD(void)
{
uint8_t data;
SPDR = 0xff; // Start the transmission
while (!(SPSR & (1<<SPIF))){} // Wait the end of the transmission
data=SPDR;
return data;
}

最佳答案

在 INT0 的中断服务程序中,您编写:

    for(i=0;i<8;i++)
buffer[i+1]=buffer[i];

意味着当i=7时,您正在数组的预定空间之外写入,并且可能会覆盖另一个变量。所以你必须这样做:

    for(i=0;i<7;i++)
buffer[i+1]=buffer[i];

AVR 将根据 ATmega1280 数据表按照您的描述管理中断。或者,如果您希望允许另一个中断中断 ISR vector ,您需要执行以下操作(示例):

ISR(INT0_vect, ISR_NOBLOCK)
{...
...}

关于c - 使用 MCU-ATMega 1280 进行多中断实时数据记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9972950/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com