[技术讨论]

pic33f 九位 485通信

[复制链接]
524|1
手机看帖
扫描二维码
随时随地手机跟帖
王不留行丶xy|  楼主 | 2021-9-13 16:19 | 显示全部楼层
/*
* 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);  
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

36

帖子

0

粉丝