#include <iom32v.h>
#include <string.h>
#include <macros.h>
typedef unsigned char u_int8;
typedef unsigned int u_int16;
typedef unsigned long u_int32;
#define UART_PARITY_NONE 0
#define UART_PARITY_ODD 1
#define UART_PARITY_ENEV 2
u_int8 rdata;
vola
tile u_int16 flag=0;
//晶振频率 12M
#define SYSTEM_CLOCK 12000000
//I/O口,位设置为发送模式/值置1,例: sbi(PORTA,0);sbi(DDRA,0);
#define sbi(io,bit) ( io |= (1<<bit) )
//I/O口,位设置为接收模式/值清0,例: cbi(PORTA,0);cbi(DDRA,0);
#define cbi(io,bit) ( io &= ~(1<<bit) )
//I/O口,按位取值,例: PINA0位的值,gbi(PINA,0);
#define gbi(pin ,bit) ( pin & (1<<bit) )
/*485置位,发送状态有效*/
#define EN_SEND delay_nus(20);
sbi(PORTC, 1);
delay_nus(20);
/*485置位,接收状态有效*/
#define EN_RECV delay_nus(20);
cbi(PORTC, 1);
delay_nus(20);
#define EN_RXISR UCSRB |= (1<<RXCIE); // 接收中断使能
#define UN_RXISR UCSRB &= ~(1<<RXCIE); // 接收中断禁止
#define EN_TXISR UCSRB |= (1<<TXCIE); // 发送中断使能
#define UN_TXISR UCSRB &= ~(1<<TXCIE); // 发送中断禁止
void port_init()
{
sbi(DDRD,PD1);
cbi(DDRD,PD0);
}
void delay_nus( unsigned int n ) //N us延时函数 实际延时时长是输入的n值的两倍
{
u_int16 i = 0;
for ( i = 1; i < n; i++ )
{
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
}
}
void uart_init(u_int32 baudrate, u_int8 databits, u_int8 sttopbits, u_int8 parity)
{
u_int8 ucsrc_value = 0;
u_int8 ucsrb_value = 0;
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00; //en rxc /U2X1 = 0,不加倍数率
//set parity
UCSRC = 0x80;
switch(parity)
{
case 0://UART_PARITY_NONE
ucsrc_value |= (0<<4);break;//"dp_None"
case 1://UART_PARITY_ODD
ucsrc_value |= (3<<4);break;//"dp_ODD"
case 2://UART_PARITY_ENEV
ucsrc_value |= (2<<4);break;//"dp_EVEN"
default:
ucsrc_value |= (1<<4);break;//"dp_None"
}
//set databites
switch(databits)
{
case 5:
ucsrc_value |= (0<<1);break;//5
case 6:
ucsrc_value |= (1<<1);break;//6
case 7:
ucsrc_value |= (2<<1);break;//7
case 8:
ucsrc_value |= (3<<1);break;//8
case 9:
ucsrc_value |= (3<<1); //9
ucsrb_value = UCSRB | (1<<2);break;
default:
ucsrc_value |= (3<<1);break;//8
}
//set stopbies
switch(sttopbits)
{
case 1:
ucsrc_value |= (0<<3);break;//"STP1"
case 2:
ucsrc_value |= (1<<3);break;//"STP2"
default:
ucsrc_value |= (0<<3);break;//"STP1"
}
UCSRB|=(1<<RXCIE)|(1<<TXCIE )|(1<<RXEN)|(1<<TXEN);
UCSRC = ucsrc_value|(1<<7);
UCSRB |= ucsrb_value;
//set baudrate
UBRRL = ((SYSTEM_CLOCK / 16 / baudrate) - 1) % 256; //设置波特率低位
UBRRH = ((SYSTEM_CLOCK / 16 / baudrate) - 1) / 256; //设置波特率高位
}
void send_data( u_int8 data )
{
//UN_TXISR
//EN_SEND
UDR = data; //发送数据,数据为变量counter
while ( !(UCSRA & 0x40) ); //等待发送结束
{
UCSRA|=0x40; //清除发送结束标志位
}
//EN_RECV
//EN_TXISR
}
void send_puts(u_int8 *Str)
{ EN_SEND
while (*Str) //字符串未结束则继续发送
{
send_data(*Str++);
}
EN_RECV
}
#pragma interrupt_handler uart_rx_isr:14
void uart_rx_isr( void )
{
UN_RXISR
rdata=UDR;
flag=1;
EN_RXISR
}
void main()
{
port_init();
uart_init(2400, 8, 1, 0);
send_puts("adasfdaff");
delay_nus(100);
SEI();
while(1){
delay_nus(200);
if(flag)
{
EN_SEND;
delay_nus(20);
send_data(rdata);
delay_nus(20);
EN_RECV;
flag = 0;
}
}
}
程序看起来似乎没问题,但你主程序中对flag的处理似乎不太妥当,检测到flag后应立即取出接收到的数据,并清除flag,然后再做发送处理。当然也可以在接受中断函数里直接将接收到的数据发送出去。
建议你在接受中断函数里增加点灯语句,然后再逐步在主程序中点灯,这样便于你快速找到问题根源。。 最佳答案
一周热门 更多>