问答

汇集网友智慧,解决技术难题

21ic问答首页 - PIC33F 9位 485 通信发送时为什么进入接收中断

pic 通信 指令 上位机

PIC33F 9位 485 通信发送时为什么进入接收中断

多次接收没问题,数据都能正确接收,发一次上传参数指令程序运行发送子程序后会改变接收中断中的值导致第二次上位机发送的参数保存位置错位,从而不能上传参数
回答 +关注 16
1975人浏览 1人回答问题 分享 举报
1 个回答
  • /*
    * File:   main.c
    * Author: Vincent
    *
    * Created on 2021年9月8日, 上午10:00
    */
    #include "system.h"
    #include "p33FJ128MC804.h"
    //定义变量
    int RS485_paratemer_tx_end = 0;
    int RS485_paratemer_rx_end = 0;
    int n = 0;
    int word_number = 1;
    unsigned RS485_Buff[13];
    unsigned RS485_Buff_tx[13] ;//{0x150,0x0D,0x43,0x0D,0x05,0x03,0x05,0x03,0x01,0x00,0x00,0x00,0xBE};
    int m = 0;
    int i;
    int RS485_parameter_tx_counter = 13;
    int RS485_patameter_length;
    int buff_sum = 0;
    int judge_word4;
    int cmd_parameter_save;
    int cmd_parameter_transfer;//发参数
    int rx_counter;
    void RS485_parameter_read(void);
    void RS485_parameter_transfer(void);
    void RS485_parameter_write(void);
    void RS485_parameter_dispose(void);
    void Delay_1ms(unsigned int t)//t = 1000大概1s
    {
        unsigned int i,j;
        for(i = 0;i < t;i ++)
            for(j = 0;j < 100;j ++);
    }

    void RS485_RX_Init(void)//配置接收
    {
        TRISAbits.TRISA7 = 0;//485EN 485接收使能引脚
        RPOR5bits.RP11R = 0b00011; //配置RP11为TX引脚
        //RPOR5bits.RP10R = 0b0001010;
        RPINR18bits.U1RXR = 0b0001010;//将接收配置到RP10
        PORTAbits.RA7 = 0;//DE发送使能信号 高电平有效 RE为接收使能信号 低电平有效

        U1MODEbits.STSEL = 0;//一个停止位
        U1MODEbits.PDSEL = 0b11; // 9数据位 无奇偶校验
        _ADDEN = 1;//使能地址检测
        U1MODEbits.ABAUD = 0; // 禁止波特率测量或测量已完成
        U1MODEbits.BRGH = 0; // BRG 在每个位周期内产生 16 个时钟信号 ( 16 倍频波特率时钟,标准模式)
        U1BRG = ((3686400/57600)/16)-1;//80MHz波特率57600(按照计算公式)  
        U1STAbits.UTXISEL0 = 0;
        U1STAbits.URXISEL = 0b00;//当接收到一个字符且该字符从 UxRSR 传输给接收缓冲区,
        //使接收缓冲区有一个或多个字符时,中断标志位置 1。
        IEC0bits.U1TXIE = 1;//使能发送中断
        IEC0bits.U1RXIE = 1;//使能接收中断
        U1MODEbits.UARTEN = 1;//使能UART
    }

    int main()
    {
        RS485_RX_Init();//配置接收
        while(1)
        {
            if(RS485_paratemer_rx_end == 1)//处理参数程序
            {
                RS485_paratemer_rx_end = 0;
                RS485_parameter_dispose();
            }
            if(RS485_paratemer_tx_end == 1)
            {
                RS485_paratemer_tx_end = 0;
                RS485_parameter_tx_counter =13;
                while(_TRMT !=1);
                _UTXEN = 0;//禁止发送器
                PORTAbits.RA7 = 0;//DE发送使能信号 高电平有效 RE为接收使能信号 低电平有效
                n = 0;
                _ADDEN = 1;//使能地址检测
            }



        }
    }
    void RS485_parameter_dispose(void)
    {
        if((RS485_Buff[0]&0b10000000) == 0)
        {
                for(i=0;i<13;i++)
            {
                RS485_Buff_tx[i] = RS485_Buff[i];
            }
        }
        for(i=0;i<RS485_patameter_length;i++)
        {
            buff_sum += RS485_Buff[i];
        }
        if((buff_sum&0xff) == RS485_Buff[RS485_patameter_length])
        {
            buff_sum = 0;
            if((RS485_Buff[0]&0b1111111) == 0x50)
            {
                if((RS485_Buff[0]&0b10000000) == 0)
                {
                    RS485_parameter_write();
                }
                else
                {
                    RS485_parameter_read();
                }
            }  
            else   
            {
                buff_sum = 0;
                _ADDEN = 1;//使能地址检测
            }     
        }
        else   
        {
            buff_sum = 0;
            _ADDEN = 1;//使能地址检测
        }               
    }
    void RS485_parameter_read(void)
    {
        switch (RS485_Buff[2])
        {
                case 0x43:
                {
                    switch (RS485_Buff[3])
                        case 0x0D:
                        {
                            PORTAbits.RA7 = 1;//DE发送使能信号 高电平有效 RE为接收使能信号 低电平有效
                            _UTXEN = 1;//使能发送器
                        }

                        break;
                }
                break;
                default:
                    _ADDEN = 1;//使能地址检测
        }
    }
    void RS485_parameter_write(void)
    {
        switch (RS485_Buff[2])
        {
            case 0x43:
                switch (RS485_Buff[3])
                {        
                    case 0x0D:
                        cmd_parameter_save = 1;//写铁电标志
                        _ADDEN = 1;//使能地址检测
                        break;
                }                  
        default: _ADDEN = 1;//使能地址检测
        }
    }
    void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void)//接收中断
    {
        //if(_UTXEN == 1)
            //goto tiaochu;
        RS485_Buff[m] = U1RXREG;
        switch(word_number)
        {
            case 1:
                    _ADDEN = 0;//禁止地址检测
                    word_number = 2;
                    m++;
                break;
            case 2:
                    rx_counter = RS485_Buff[1] - 1;
                    RS485_patameter_length = RS485_Buff[1] - 1;
                    word_number = 3;
                    m++;
                    rx_counter--;
                break;
            case 3:
                m++;
                rx_counter--;
                if(rx_counter == 0)
                {
                    RS485_paratemer_rx_end = 1;
                    word_number = 1;
                    m = 0;
                }
        }  
        //tiaochu:
        IFS0bits.U1RXIF = 0;
    }
    void __attribute__((__interrupt__, auto_psv)) _U1TXInterrupt(void)//发送中断
    {
        IFS0bits.U1TXIF = 0;
        if(RS485_parameter_tx_counter == 0)
        {
            RS485_paratemer_tx_end = 1;

            word_number = 1;
            m=0;

        }
        else
        {
            U1TXREG = RS485_Buff_tx[n];
            RS485_parameter_tx_counter --;
            n++;
            //while(_TRMT !=1);  
        }
    }


您需要登录后才可以回复 登录 | 注册