搜索
bottom↓
回复: 3

请教马老师,2个中断存在依赖性,如何较好的控制?

[复制链接]

出0入0汤圆

发表于 2007-3-21 05:02:10 | 显示全部楼层 |阅读模式
马老师,您好。



在双机通讯中,由A向B持续不断发送数据(这些数据是正弦波形函数的列表值),B接受后,存储在一个FIFO中,另外一个中断函数T/C0_overflow中,取这个FIFO存储器的值(也就是正弦波形函数的列表值)来改变OCR0B,生成PWM,经过滤波后,从而达到在B方输出正弦波的目的。



我的困难是:我用Usart_Rx中断来接受数据,用Timer0_ovf中断来修改OCR0B,如何控制这两个中断?

我希望这两个中断互不干扰,各做各的。但是从实现角度来看,互不干扰是不可能的,使能了溢出中断就一定会影响到数据接收的中断;而且溢出中断程序中所需要的OCR0B的数值是由接受数据中断的程序提供的。



后来我想我用polling来代替中断的方法接收数据,这样就不存在矛盾了,但是程序运行有问题,溢出中断中读取OCR0B的值不能按我想的那样,输出的正弦波不够平滑,并且频率是以前的十分之一。



不知道您可以给我提供一些建议吗?



谢谢。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2007-3-21 21:24:41 | 显示全部楼层
我已经不太明白你到底想做什么。



关于AVR本身功能模块的应用我可以给你些建议,至于产品的功能的具体实现,已经超出了本讨论组的范围。



如同你买了一台PC,PC本身没有问题,你在上面自己编写的程序有问题的话,微软公司也不知道如何帮你解决。

出0入0汤圆

 楼主| 发表于 2007-3-22 01:24:49 | 显示全部楼层
也许是我的表达能力有问题吧,请见谅。



通过示波器观测发现问题出在接受数据的速度太慢,而溢出中断更新OCR0B的值太快,于是通过调整波特率就可以解决了。



但是我是用查询的方法来接受数据,如果改用中断,还是有问题。



附加代码如下:

//reception



#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <util/delay.h>

#include "son.h"

#include "fifo.h"



#ifndef F_CPU

#define F_CPU 8000000UL

#endif



//RTS CTS 流量控制

#define RTS_inactive        PORTD &= ~(1<<PD3)   //level low

#define RTS_active          PORTD |=  (1<<PD3)  //level high

#define CTS_inactive        !(PIND &(1<<2))   //level low  

#define CTS_active          PIND &(1<<2)  //level high  



/* declaration of variables */

volatile uint8_t counter_repetition;

uint8_t testFifo_buf[64]; // FIFO的大小是64bytes

fifo_t testFifo = {testFifo_buf, sizeof testFifo_buf-1, 0, 0}, *myFifo  = &testFifo; /* create a testFifo and a pointer to it */

volatile uint8_t i_push;

uint8_t buff[sizeof testFifo_buf];  



/* functions */

// Init Usart

void Init_Usart(unsigned int baudrate)

{

    UBRR0H = (unsigned char)(baudrate>>8);

    UBRR0L = (unsigned char)baudrate;

       

    UCSR0B = 0x00; //disable while setting baud rate

   

    UCSR0A = (1<<U2X0);



    // Enable receiver

    //UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);

    UCSR0B = (1<<RXEN0)|(1<<TXEN0);



    // Async mode, 8bits data, 1bits stop

    UCSR0C = (1<<UCSZ00)|(1<<UCSZ01) ;  

}



// Init Port

void Init_Port_Son(void)

{       

    // Port D init

    //PORTD.0 ->    IN          RxD

    //PORTD.1 ->    OUT          TxD

    //PORTD.2 ->    IN          CTS

    //PORTD.3 ->    OUT     RTS  high level means enable RTS

    //PORTD.5 ->    OUT         PWM audio output from timer compare

     

    PORTD = 0b11010011;

    DDRD  = 0b11101010;

}



// Timer0 Init

void Init_Timer0_Son(void)

{

    //Fast PWM mode, TOP=0xFF,   

    TCCR0A=(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);



    //CLKI/O  8MHz

    TCCR0B=(1<<CS00);

         

    //enable TOIE0

    //TIMSK0=(1<<TOIE0);  

}



// Init Total

void Init_Total_Son(void)

{

        CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable



        Init_Port_Son();

        //Init_Usart(103); //9600bits/s baudrate for 8MHz, 太慢

        Init_Usart(1); //0.5Mbits/s baudrate for 8Mhz

        Init_Timer0_Son();

}



// recept funtion

char Usart_Rx(void)

{

        while (!(UCSR0A & (1<<RXC0)));

        return UDR0;

}



/* interruption */

// Timer0 overflow

ISR(TIMER0_OVF_vect)

{       

        counter_repetition++;

        if(counter_repetition == 4) //重复四次,Fpwm=31KHz

        {

                OCR0B = pullFifo(myFifo);//取FIFO的值到OCR0B

                counter_repetition =0;

        }

}



// interruption of reception

/* 这种方法不可以

ISR(USART_RX_vect)

{

        //if(!(isFifoFull(myFifo)))

        //        pushFifo(myFifo,UDR0);       

        //TIMSK0 = (1<<TOIE0);

        if(!(isFifoFull(myFifo)))

                {

                        RTS_active; //il faut remettre cette condition

                        pushFifo(myFifo,UDR0);

                        TIMSK0 = (1<<TOIE0); // just useful for the first time

                }

        else

                RTS_inactive;

}

*/



/* Programme Main */

int main(void)

{       

        counter_repetition = 0;



        Init_Total_Son();

        resetFifo(myFifo);

        sei();



        while(CTS_inactive);

        RTS_active;



        while(1)

        {

                if(!(isFifoFull(myFifo))) //如果FIFO没满

                {

                        RTS_active;  

                        pushFifo(myFifo,Usart_Rx());//存入数据到FIFO

                        TIMSK0 = (1<<TOIE0); // just useful for the first time

                }

                else

                RTS_inactive;

        }

        return 0;

}



FIFO的程序不是我写的,不能公布,不好意思。



//Butterfly : 发送方

#include <avr/io.h>

#include <avr/pgmspace.h>

#include <avr/interrupt.h>

#include "Butterfly_sendson.h"



#ifndef F_CPU

#define F_CPU 8000000UL

#endif



//RTS CTS

#define RTS_inactive        PORTB &= ~(1<<PB7)   //level low

#define RTS_active          PORTB |=  (1<<PB7)  //level high

#define CTS_inactive        !(PINB &(1<<6))   //level low  

#define CTS_active          PINB &(1<<6)  //level high  



/* declaration of variables */

/************************** Sin Table **********************

* Samples table : one period sampled on 128 samples and   *

* quantized on 7 bit                                      *

* formule: f(x) = 64 + 63 * sin(2πx/128) x∈[0…127]     *                              

***********************************************************/



const uint8_t table1_SinParam[128] PROGMEM = {

64, 67, 70, 73, 76, 79, 82, 85,

88, 91, 94, 96, 99, 102,104,106,

109,111,113,115,116,118,120,121,

122,123,124,125,126,126,127,127,

127,127,127,126,126,125,124,123,

122,121,120,118,116,115,113,111,

109,106,104,102,99, 96, 94, 91,

88, 85, 82, 79, 76, 73, 70, 67,

64, 61, 58, 55, 52, 49, 46, 43,

40, 37, 34, 32, 29, 26, 24, 22,

19, 17, 15, 13, 12, 10, 8,  7,

6,  5,  4,  3,  2,  2,  1,  1,

1,  1,  1,  2,  2,  3,  4,  5,

6,  7,  8,  10, 12, 13, 15, 17,

19, 22, 24, 26, 29, 32, 34, 37,

40, 43, 46, 49, 52, 55, 58, 61};



volatile uint8_t counter_interrupt;

volatile uint8_t send_son_active;

/* init */

// init usart

void Init_Usart_Butterfly(uint16_t baudrate)

{

    UBRRH = (unsigned char)(baudrate>>8);

    UBRRL = (unsigned char)baudrate;

       

    UCSRB = 0x00; //disable while setting baud rate

   

    // double vitesse

    UCSRA = (1<<U2X);



    // Enable  transmitter and receiver

    UCSRB = (1<<TXEN)|(1<<RXEN);



    // Async mode, 8bits data, 1bits stop  

    UCSRC = (1<<UCSZ0)|(1<<UCSZ1) ;  

}



// Init Port       

void Init_Port_Butterfly(void)

{

        // PE0  RXD  IN

        // PE1  TXD  OUT

        // PE2  XCK/AIN0  IN

        // PE3  AIN1  IN

        // PE4  SCL/USCK BI

        // PE5  SDA/DI  BI

        // PE6  DO  BI

        // PE7  RST_FLASH OUT

        PORTE = 0b11111111;

        DDRE  = 0b10000010;

    // PB0  /SS   OUT desactiver

        // PB1  SCK   OUT

        // PB2  MISO  IN

        // PB3  MOSI  OUT

        // PB4  OC0      

        // PB5  OC1A

        // PB6  OC1B  CTS IN read RTS of TUX

        // PB7  OC2   RTS OUT

        PORTB = 0b00100000;

        DDRB  = 0b10010000;

}



// init total

void Init_Total_Butterfly(void)

{

        CLKPR = (1<<CLKPCE);        // set Clock Prescaler Change Enable



        Init_Port_Butterfly();

        //Init_Usart_Butterfly(103); //9600bits/s baudrate for 8Mhz

        Init_Usart_Butterfly(1); //250Kbits/s baudrate for 8Mhz



        EIMSK = (1<<PCIE1);    //Pin change interrupt enable

        PCMSK1 = (1<<PCINT14); //Pin change enable PB6_CTS

}



/* send a character function  */

void Put_Char(char c)

{

        while (!(UCSRA & (1<<UDRE)));   

        UDR = c;

}





/* interrupt */

ISR(PCINT1_vect)

{

        switch (counter_interrupt % 2)

    {

        case 0:

                {

                        counter_interrupt++;

                        send_son_active=1;

                }   break;                  

       

                case 1:

                {

                           counter_interrupt++;

                        send_son_active=0;       

                }   break;

        }

}





/* programme main */

int main (void)

{       

        uint8_t data = 0;

        uint8_t step_width = 8;

        uint8_t position_in_table = 0;

        uint8_t Num_Sample;



        Num_Sample = 128/step_width;

        send_son_active = 0;

        counter_interrupt = 0;



        Init_Total_Butterfly();

        sei();

        RTS_active;



        while(1)

        {

                while(Num_Sample>0)

                {

                        if(send_son_active)

                        {

                                Num_Sample--;

                                position_in_table += step_width;  

                                   if (position_in_table > 127) position_in_table -= 128;  

                                    data = pgm_read_byte(&table1_SinParam[position_in_table]);

                                Put_Char(data);



                                if(Num_Sample == 0)

                                Num_Sample = 128/step_width;                       

                        }

                }               

        }

                                        

        return 0;

}






-----此内容被Lily1979于2007-03-22,01:25:37编辑过

出0入0汤圆

发表于 2007-3-23 00:15:48 | 显示全部楼层
使用两个变量 data_pre,data_new.



Usart_Rx中断接受到的数据,放在data_new中。



每次Timer0_ovf中断,进入中断后,判断data_pre,data_new值是否相同。不同修改OCR0B;并将data_pre = data_new。相同不修改OCR0B。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-23 17:09

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表