|
![](static/image/common/ico_lz.png)
楼主 |
发表于 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编辑过 |
|