微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 哪位大侠帮我看看我的程序,为什么从串口助手发送一个字符却接收不到?发送函数显示正常。

哪位大侠帮我看看我的程序,为什么从串口助手发送一个字符却接收不到?发送函数显示正常。

时间:10-02 整理:3721RD 点击:
#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;
volatile 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,然后再做发送处理。当然也可以在接受中断函数里直接将接收到的数据发送出去。
建议你在接受中断函数里增加点灯语句,然后再逐步在主程序中点灯,这样便于你快速找到问题根源。

哦 谢谢 我再试试!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top