我通过外部中断在软件uart上有这个代码。任何人都可以检查这是什么问题?它可以在位爆炸引脚上传输但不传输所需的值。这是代码。
/*
* MidtermSUART.c
*
* Created: 3/31/2014 5:11:08 AM
* Author: johnmark
*/
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
#define TRXDDR DDRD
#define TRXPORT PORTD
#define TRXPIN PIND
#define TX_PIN PIND3 //Transmit data pin
#define RX_PIN PIND2 //Receive data pin
#define SET_TX_PIN() ( TRXPORT |= ( 1 << TX_PIN ) )
#define CLEAR_TX_PIN() ( TRXPORT &= ~( 1 << TX_PIN ) )
#define GET_RX_PIN() ( TRXPIN & ( 1 << RX_PIN ) )
#define ENABLE_EXTERNAL0_INTERRUPT() ( EIMSK |= ( 1<< INT0 ) )
#define DISABLE_EXTERNAL0_INTERRUPT() ( EIMSK = ( 0<< INT0 ) )
volatile unsigned char pinchange = 0xFF;
volatile char received = 0;
volatile char transmit = 0;
volatile int i = 0;
volatile int j = 0;
volatile int confirm = 0;
//Initialize Software Uart
void SUART_Init()
{
TRXDDR |= ( 1 << TX_PIN ); // TX_PIN is output.
SET_TX_PIN( ); // Set the TX line to idle state.
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 bit for 1 pre-scaler:
TCCR1B |= (1 << CS10);
TCNT1 = 0;
// set compare match register to desired timer count:
OCR1A = round(16000000/(9600));
OCR1B = round(16000000/(9600));
//ENABLE_EXTERNAL0_INTERRUPT();
EIMSK = (1<<INT0);
}
//Receiving Section
ISR(INT0_vect)
{
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A); //Enable Output Compare A Match Interrupt
//DISABLE_EXTERNAL0_INTERRUPT();
EIMSK = 0;
//PCICR = (0 << PCIE0); //Pin Change Interrupt Enable 0
TCNT1 = 0;
}
//receive
ISR(TIMER1_COMPA_vect)
{
if (i >= 1) {
received |= ((PIND&0x04)>>2)<<(i-1);
}
i++;
if (i == 10)
{
i = 0;
//ENABLE_EXTERNAL0_INTERRUPT();
EIMSK = (1<<INT0);
TIMSK1 = (0 << OCIE1A);
TCNT1 = 0;
confirm = 1;
}
}
//transmit
ISR(TIMER1_COMPB_vect)
{
if (j == 0)
{
PORTD = (0<<PIND3);
}
if ((j > 0)&&(j < 9))
{
PORTD = ((transmit>>(j-1))&0x01)<<PIND3;
}
j++;
if (j == 10)
{
PORTD = (1<<PIND3);
TIMSK1 = (0 << OCIE1B);
j = 0;
TCNT1 = 0;
}
}
void SWUART_send(char m)
{
transmit = m;
TIMSK1 |= (1 << OCIE1B);
TCNT1 = 0;
}
int main (void)
{
SUART_Init();
sei(); // enable global interrupts
while(1)
{
//TODO:: Please write your application code
if (confirm == 1)
{
//UART_send(x);
SWUART_send(received);
received = 0;
confirm = 0;
}
}
}
答案 0 :(得分:1)
if (j == 0)
{
PORTD = (0<<PIND3);
}
if ((j > 0)&&(j < 9))
{
PORTD = ((transmit>>(j-1))&0x01)<<PIND3;
}
这段代码有问题...... 可能不是唯一的问题,但通常在您设置端口位时使用AVR编码。你这样做。
PORTD |= (1<<PIND3); // set PORTD bit 3
PORTD &= ~(1<<PIND3); // clears PORTD bit 3
尝试这样的事情。
if (j == 0)
{
// start bit
PORTD &= ~(1<<PIND3);
}
else if ((j > 0)&&(j < 9))
{
// shift data out
if( (transmit>>(j-1)) &0x01)
PORTD |= (1<<PIND3);
else
PORTD &= (1<<PIND3);
}
j++;
if (j == 10)
{
// stop bit
PORTD |= (1<<PIND3);
// timer off
TIMSK1 = (0 << OCIE1B);
j = 0;
TCNT1 = 0;
}