找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5238|回复: 0
收起左侧

pic32单片机RS485通信程序

[复制链接]
ID:401765 发表于 2018-9-24 11:11 | 显示全部楼层 |阅读模式
pic32单片机485通信程序分享给大家

0.png

pic32源程序如下:

  1. /********************************************************************************************************
  2. *********************************************************************************************************
  3. *
  4. * File                : RS485.c
  5. * Hardware Environment:        easyPIC pro v2
  6. * Build Environment   : MPLAB V8.66 + PIC32 V2.01
  7. * Microcontroller     : PIC32MX795F512L
  8. * Version             : V1.0
  9. * By                  : JEFF
  10. * DATE                                  : 20150320
  11. *
  12. * Hardware Connection:


  13.   CN5(0~5)-----RB8~RB13, Segment LED Connetion
  14.   CN6(0~7)-----RD0~RD7

  15.   RE/DE------RB15
  16.   RO   ------RF4
  17.   DI   ------RF5
  18. *
  19. *(c) Copyright 2010-2018, Logifind Tech CO.,LTD
  20. *http://www.logifind.com
  21. *All Rights Reserved
  22. *
  23. *********************************************************************************************************
  24. ********************************************************************************************************/
  25. //
  26. // 实验描述:串口助手发送数据,接收16 Byte数据,RS485 发出16Byte数据
  27. //           LED及数码管 显示缓冲区数据.
  28. //
  29. // 头 文 件:C:\Program Files\Microchip\MPLAB C32 Suite\pic32-libs\include\proc
  30. //
  31. // 配 置 位:菜单栏 -> Help -> Topics.. -> PIC32MX Config Setting
  32. //
  33. // 波 特 率:9600  N 8 1
  34. //
  35. // 注意事项:每次必须累积 16Byte 数据,单片机才回传数据
  36. //
  37. //-------------------------------------------------------------------------------

  38. #include <plib.h>                    //调用通用头文件

  39. //-------------------------------------------------------------------------------
  40. // POSCMOD = XT, FNOSC = PRIPLL, FWDTEN = OFF
  41. // PLLIDIV = DIV_2, PLLMUL = MUL_20
  42. // PBDIV = 4 (default)
  43. // Main clock = 4MHz /2 * 20    =  40MHz
  44. // Peripheral clock = 40MHz /4  =  10MHz
  45. // SYSCLK = 40 MHz (4MHz Crystal/FPLLIDIV * FPLLMUL / FPLLODIV)
  46. // PBCLK  = 10 MHz

  47. #pragma config POSCMOD  = XT         //主振荡器  
  48. #pragma config FNOSC    = PRIPLL     //倍频模式
  49. #pragma config FPLLIDIV = DIV_2      //输入分频 1:2
  50. #pragma config FPLLMUL  = MUL_20     //PPL 倍频 1:20
  51. #pragma config FPLLODIV = DIV_1      //输出分频 1:1
  52. #pragma config FPBDIV   = DIV_4      //外设时钟
  53. #pragma config FWDTEN   = OFF        //关闭看门狗
  54. //#pragma config ICESEL   = ICS_PGx1   //调试端口1
  55. #pragma config ICESEL   = ICS_PGx2   //调试端口2

  56. #define SysLED     _LATB5                       //CPU LED
  57. #define SPEKAK     _LATD8                       //蜂呜器
  58. #define RELAY      _LATD8                       //继电器
  59. #define bctl_485   _LATB15                      //485控制端


  60. #define Smg_a    0xFE                           //定义段码
  61. #define Smg_b    0xFD
  62. #define Smg_c    0xFB
  63. #define Smg_d    0xF7
  64. #define Smg_e    0xEF
  65. #define Smg_f    0xDF
  66. #define Smg_g    0xBF
  67. #define Smg_dp   0x7F

  68. #define Bmp0Map          Smg_a & Smg_b & Smg_c & Smg_d & Smg_e & Smg_f
  69. #define Bmp1Map          Smg_b & Smg_c
  70. #define Bmp2Map          Smg_a & Smg_b & Smg_d & Smg_e & Smg_g
  71. #define Bmp3Map          Smg_a & Smg_b & Smg_c & Smg_d & Smg_g
  72. #define Bmp4Map          Smg_b & Smg_c & Smg_f & Smg_g
  73. #define Bmp5Map          Smg_a & Smg_c & Smg_d & Smg_f & Smg_g
  74. #define Bmp6Map          Smg_a & Smg_c & Smg_d & Smg_e & Smg_f & Smg_g
  75. #define Bmp7Map          Smg_a & Smg_b & Smg_c
  76. #define Bmp8Map          Smg_a & Smg_b & Smg_c & Smg_d & Smg_e & Smg_f & Smg_g
  77. #define Bmp9Map          Smg_a & Smg_b & Smg_c & Smg_d & Smg_f & Smg_g
  78. #define BmpAMap          Smg_a & Smg_b & Smg_c & Smg_e & Smg_f & Smg_g
  79. #define BmpBMap          Smg_c & Smg_d & Smg_e & Smg_f & Smg_g
  80. #define BmpCMap          Smg_a & Smg_d & Smg_e & Smg_f
  81. #define BmpDMap          Smg_b & Smg_c & Smg_d & Smg_e & Smg_g
  82. #define BmpEMap          Smg_a & Smg_d & Smg_e & Smg_f & Smg_g
  83. #define BmpFMap          Smg_a & Smg_e & Smg_f & Smg_g




  84. const unsigned char SegCode[] =                //显示段码表
  85. {
  86.         Bmp0Map,Bmp1Map,Bmp2Map,Bmp3Map,Bmp4Map,Bmp5Map,Bmp6Map,Bmp7Map,
  87.         Bmp8Map,Bmp9Map,BmpAMap,BmpBMap,BmpCMap,BmpDMap,BmpEMap,BmpFMap
  88. };

  89. unsigned char DpyNum[6] = {Smg_g,Smg_g,Smg_g,Smg_g,Smg_g,Smg_g}; //显示缓冲区   

  90. unsigned char RxBuffer[16] = {0,0,0,0};        //串口接收缓冲区
  91. unsigned char SysTick = 0;                     //系统时基
  92. unsigned char COM2_RecvCnt  = 0;               //计数清零
  93. unsigned char COM2_RecvFlag = 0;               //接收标志
  94. unsigned char COM2_SendDatCnt = 0;             //发送计数        
  95. unsigned char COM2_SendDatLength = 0;          //发送长度

  96. //-------------------------------------------------------------------------------
  97. //  延时函数
  98. //-------------------------------------------------------------------------------
  99. void Delay_xmS(unsigned int i)               
  100. {
  101.         unsigned int j;
  102.         for(;i>0;i--)
  103.         {
  104.                 Nop();
  105.                 for(j=0;j<255;j++)
  106.                 {
  107.                         Nop();
  108.                         ClearWDT();
  109.                 }
  110.         }       
  111. }

  112. //-------------------------------------------------------------------------------
  113. //  串口2初始化函数
  114. //-------------------------------------------------------------------------------
  115. void UART2_Init(void)
  116. {
  117.         bctl_485 = 0;                    // 接收模式
  118.         U2MODEbits.SIDL  = 0;            // IDLE工作
  119.         U2MODEbits.IREN  = 0;            // 禁止IrDA
  120.         U2MODEbits.UEN   = 0;            // 使能RX TX引脚
  121.         U2MODEbits.WAKE  = 0;            // 禁止唤醒
  122.         U2MODEbits.ABAUD = 0;            // 禁止自动BUD
  123.         U2MODEbits.RXINV = 0;            // 空闲状态为1
  124.         U2MODEbits.BRGH  = 0;            // 16x标准波特率
  125.         U2MODEbits.PDSEL = 0;            // 8位无奇偶校验
  126.         U2MODEbits.STSEL = 0;            // 1个停止位
  127.        
  128.         U2STAbits.ADM_EN   = 0;          // 关自动地址检测
  129.         U2STAbits.UTXISEL1 = 0;          // 发送完所有字符后中断
  130.         U2STAbits.UTXISEL0 = 1;
  131.         U2STAbits.UTXINV   = 0;          // 空闲状态为1
  132.         U2STAbits.URXEN    = 1;          // 接收器使能       
  133.        
  134.         U2STAbits.UTXBRK   = 0;          // 禁止发送间隔位
  135.         U2STAbits.UTXEN    = 1;          // 发送器使能
  136.                                                        
  137.         U2STAbits.URXISEL1 = 0;          // 接收1个字符中断
  138.         U2STAbits.URXISEL0 = 0;
  139.        
  140.         U2BRG = 64;                      // PBCLK 10MHz  N 8 1 9600 BRG = 64;
  141.        
  142.         IPC8bits.U2IP   = 4;             // 主优选级
  143.         IPC8bits.U2IS   = 1;             // 次优选级
  144.        
  145.         IEC1bits.U2RXIE = 1;             // 接收中断
  146.         IEC1bits.U2TXIE = 0;             // 发送中断
  147.        
  148.         U2MODEbits.ON   = 1;             // 串口使能
  149. }

  150. //-------------------------------------------------------------------------------
  151. //  串口2中断函数  注意中断编号
  152. //-------------------------------------------------------------------------------
  153. void __attribute__((vector(32)))__attribute__((interrupt(IPL4)))_UART2Interrupt(void)
  154. {
  155.         if(IFS1bits.U2RXIF == 1)              //接收中断  
  156.         {       
  157.                 RxBuffer[COM2_RecvCnt++] = U2RXREG; //储存
  158.                 if(COM2_RecvCnt == 16)              //接收计数
  159.                 {
  160.                         COM2_RecvCnt = 0;
  161.                         COM2_RecvFlag = 1;
  162.                 }
  163.                 IFS1bits.U2RXIF = 0;
  164.         }

  165.         if(IFS1bits.U2TXIF & IEC1bits.U2TXIE) //发送中断         
  166.         {
  167.                 IFS1bits.U2TXIF = 0;              //清中断标志
  168.                 if(COM2_SendDatCnt != COM2_SendDatLength)  //发送未完成?
  169.                 {
  170.                         U2TXREG = RxBuffer[COM2_SendDatCnt++]; //装载数数据
  171.                 }
  172.                 else                              //发送完成
  173.                 {
  174.                         if(U2STAbits.TRMT == 1)       //移位寄存器空
  175.                         {
  176.                             bctl_485 = 0;             //接收模式
  177.                                 IEC1bits.U2TXIE = 0;      //禁止中断
  178.                         }   
  179.             }
  180.         }
  181. }

  182. //---------------------------------------------------------------------------------
  183. //  TMR1初始化
  184. //---------------------------------------------------------------------------------
  185. void Timer1_Init(void)
  186. {
  187.         T1CON = 0;              // Timer1 清零
  188.        
  189.         IFS0bits.T1IF = 0;      // Timer1 清除标志位
  190.         IEC0bits.T1IE = 1;      // Timer1 中断允许
  191.         IPC1bits.T1IP = 4;      // Timer1 中断优选级
  192.         IPC1bits.T1IS = 1;      // Timer1 次优选级
  193.         TMR1=  0x0000;          // Timer1 给定初值
  194.         PR1 = 0x9C3F;           // Timer1 周期寄存器
  195.        
  196.         T1CONbits.TON = 1;      // Timer1 启动计数
  197. }

  198. //---------------------------------------------------------------------------------
  199. //  数码管驱动
  200. //---------------------------------------------------------------------------------
  201. void SegDisplay(void)
  202. {
  203.         static unsigned char step = 0;
  204.         LATD = (LATD&0xFF00)|DpyNum[step];  //显示缓冲
  205.         switch(step)                        //片选
  206.         {
  207.                 case 0: _LATB8 = 0;_LATB9 = 1;_LATB10 = 1;_LATB11 = 1;_LATB12 = 1;_LATB13 = 1;break;
  208.                 case 1: _LATB8 = 1;_LATB9 = 0;_LATB10 = 1;_LATB11 = 1;_LATB12 = 1;_LATB13 = 1;break;
  209.                 case 2: _LATB8 = 1;_LATB9 = 1;_LATB10 = 0;_LATB11 = 1;_LATB12 = 1;_LATB13 = 1;break;
  210.                 case 3: _LATB8 = 1;_LATB9 = 1;_LATB10 = 1;_LATB11 = 0;_LATB12 = 1;_LATB13 = 1;break;
  211.                 case 4: _LATB8 = 1;_LATB9 = 1;_LATB10 = 1;_LATB11 = 1;_LATB12 = 0;_LATB13 = 1;break;
  212.                 case 5: _LATB8 = 1;_LATB9 = 1;_LATB10 = 1;_LATB11 = 1;_LATB12 = 1;_LATB13 = 0;break;
  213.                 default:break;
  214.         }
  215.         if(step < 5) step ++;         //扫描
  216.         else               step = 0;
  217. }
  218.        
  219. //---------------------------------------------------------------------------------
  220. //  TMR1 中断函数
  221. //---------------------------------------------------------------------------------
  222. void __attribute__ ((vector(4)))__attribute__((interrupt(IPL4)))_T1Interrupt(void)
  223. {       
  224.         IFS0bits.T1IF = 0;
  225.         SegDisplay();                 //数码管扫描
  226.         SysTick = 1;                  //系统 Tick
  227. }

  228. //---------------------------------------------------------------------------------
  229. //  主函数
  230. //---------------------------------------------------------------------------------
  231. int main(void)
  232. {
  233.         unsigned char temp = 0;       //临时变量
  234.         unsigned char Delay = 0;      
  235.        
  236.         AD1PCFG = 0xFFFF;             //引脚为数字I/O
  237.         TRISB  = 0x40DF;              //RB5 RB8-RB13输出
  238.         TRISG  = 0xFFFF;              //G端口输出
  239.         TRISE  = 0x0000;              //E端口输出
  240.         TRISD  = 0xFE00;              //RD0-RD7 RD8 输出
  241.        
  242.         LATD = 0x00FF;                //关闭蜂呜器
  243.         Timer1_Init();                //TMR1初始化
  244.         UART2_Init();                 //UART初始化
  245.        
  246.         INTEnableSystemMultiVectoredInt(); //使能中断多向量表
  247.                
  248.         LATE = 0x00FF;                //点亮 D0 - D7
  249.         Delay_xmS(400);
  250.         LATE = 0x0000;                //关闭 D0 - D7
  251.         Delay_xmS(400);
  252.         LATE = 0x00FF;                //点亮 D0 - D7
  253.         Delay_xmS(400);
  254.         LATE = 0x0000;                //关闭 D0 - D7
  255.         Delay_xmS(200);

  256.         while(1)
  257.         {
  258.                 //----------------------LCD显示-------------------------
  259.                 if(COM2_RecvFlag == 1)
  260.                 {
  261.                         bctl_485 = 1;            //发送模式
  262.                         COM2_RecvFlag = 0;       //清标志
  263.                         COM2_SendDatCnt = 0;     //准备发送
  264.                            COM2_SendDatLength = 16; //数据长度
  265.                         IEC1bits.U2TXIE = 1;     //启动发送
  266.                 }
  267.                 if(SysTick == 1)             //系统显示延时
  268.                 {
  269.                         SysTick = 0;
  270.                         Delay ++;
  271.                 }       
  272.                 if(Delay > 120)              //刷新显示
  273.                 {
  274.                         Delay = 0;
  275.                            DpyNum[0] = SegCode[temp/10];             //LCD 分段      
  276.                         DpyNum[1] = SegCode[temp%10];
  277.                         DpyNum[2] = Smg_g;
  278.                         DpyNum[3] = Smg_g;
  279.                         DpyNum[4] = SegCode[RxBuffer[temp]>>4];   //显示接收数据高4位
  280.                         DpyNum[5] = SegCode[RxBuffer[temp]&0x0F]; //显示接收数据低4位
  281.                        
  282.                         LATE = RxBuffer[temp];                    //LED显示当前数据
  283.                        
  284.                         temp = (temp + 1)&0x0F;                   //循环显示
  285.                         SysLED = !SysLED;                         //CPU LED
  286.                 }
  287.                
  288.                 //------------------------------------------------------
  289.         }
  290. }



  291. //---------------------------------------------------------------------------------
复制代码

所有资料51hei提供下载:
RS485.rar (163.55 KB, 下载次数: 38)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表