找回密码
 立即注册

QQ登录

只需一步,快速开始

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

PL3201芯片的串口2使用(修复BUG)

[复制链接]
ID:82781 发表于 2015-6-13 15:56 | 显示全部楼层 |阅读模式
原本想着这个小事小弟完全可以搞定,可是小弟却令我有些失望,而且还是51的内核,只不过是他是在原来芯片上扩展的一个而已,操作起来也无非是:
第一歩:设置下定时器的工作模式
第二歩:设置下培增
第三部:定时器初始化
第四部:配置串口方式
第五步:启动定时器发生波特率
但是需要注意的是 他没有倍增器,第二定时器的初值,第三他的控制寄存器,
一下是代码,我测试的,很好用,!
  1. #include<string.h>
  2. #include <PL3201_Addr_Map.h>
  3. #include "pl3201.h"
  4. #include "usart.h"
  5. #include "string.h"
  6. extern void Protocol_analysis (unsigned char *buf,unsigned char len) ;
  7. sbit  PLC_TLED=P0^2;
  8. sbit  PLC_RLED=P0^4; //if it is 0,well be open !        IS A INDCATER!

  9. sbit RUN=P0^3;


  10. uchar  data    PLC_Rxd_pointer;           
  11. uchar  data    PLC_Rxd_tlen;      
  12. uchar  data    PLC_send_pointer;   
  13. uchar  data    PLC_timer;           
  14. uchar  data    PLC_total_len;      
  15. uchar  data    PLC_Rxd_timer;   

  16. uchar  data    WDI;                 

  17. bit    bdata   PLC_Rxd_state;   
  18. bit    bdata   PLC_Rxd_OK;        
  19. bit    bdata   PLC_sending;         
  20. bit  data    PLC_TX_EN=0;       
  21. uchar    xdata PLC_recv_buf[50];   
  22. uchar  xdata   PLC_Tx_Buf[50];  

  23.   
  24. uchar put_buf=0;
  25.   uint8_t start_rec_data;
  26. uint8_t  rec;

  27. unsigned char nk;

  28. void Check_sys_plc(void)
  29. {
  30.   WDI=0x9a;                  
  31.       
  32.        if(!(PLC_Rxd_timer||PLC_sending))        // no sending and receiving
  33.        {
  34.                PLC_rset();
  35.        }

  36.    
  37.        initsys_ref();
  38. }



  39. void Input_Rx_Process(void)
  40. {
  41.        

  42. /*Into the upper layer protocol frame*/
  43. Protocol_analysis (PLC_recv_buf,PLC_recv_buf[0]);
  44. PLC_Rxd_state=0;
  45. }


  46. void  timeint0 ( void ) interrupt 1
  47. {

  48.    RUN=~RUN;
  49.    
  50.    if ( PLC_Rxd_timer>0 )
  51.    {
  52.       PLC_Rxd_timer--;
  53.    }
  54.    else
  55.    {
  56.       PLC_Rxd_timer=0;
  57.       
  58.      PLC_Rxd_state=0;        // resume receive state
  59.    }
  60.    
  61.    if ( PLC_timer>0 )       
  62.            PLC_timer--;

  63. nk++;
  64. if(nk==20){nk=0;PLC_TX_EN=1;}


  65.    TH0=0x63;                                // 置定时器计数 100ms 中断一次 ( 4.8MHz )
  66.    TL0=0xcc;

  67.    if ( WDI == 0x9a )
  68.    {
  69.       WDT_RST=0xa1;                 // 清看门狗
  70.       WDI=0;
  71.    }
  72. }
  73.    uint8_t n,len;
  74.   
  75.    
  76. void  PLC_int ( void ) interrupt 7
  77. {
  78.      uchar  data state;              
  79. uchar data SSC_adr_bak;
  80. SSC_adr_bak=SSC_ADR;       
  81.      SSC_ADR=0x00;                           
  82.      state= SSC_DAT;
  83.    if ( ( state&0x01 ) == 1 )              //载波发送状态
  84.    { // 载波发送

  85.    if ( PLC_send_pointer !=PLC_total_len )
  86.      
  87.     {
  88.        SSC_BUF=PLC_Tx_Buf[PLC_send_pointer];                  //发送下一个字节
  89.        PLC_send_pointer++;
  90.     }
  91.     else
  92.     {  //发送完成
  93.       PLC_sending=0;                        // 清正在发送标志
  94. //      PLC_data=0;
  95.      // PLC_TLED=1;                          // 发送指示灯灭
  96.     }
  97.   }
  98.   else
  99. {

  100. PLC_Rxd_timer=20;              // 最大字节接收延时时间为1S
  101.     if ( ( state&0x04 ) == 0x04 )     //如果接收的是祯头标志
  102.     {
  103. //帧


  104.       if ( PLC_Rxd_state == 0 )      //如果处于等待接收状态
  105.       {
  106.           //接收第一个字节,并准备接收后面的字节
  107.          PLC_recv_buf[0]=SSC_BUF;
  108.          PLC_Rxd_pointer=0;        //lxw2006-3-2 17:07
  109.          PLC_Rxd_state=1;
  110. PLC_Rxd_tlen=PLC_recv_buf[0];

  111.       }
  112.       else // translate to rec
  113.       {             
  114.       PLC_Rxd_state=0;
  115.       SSC_ADR=0X0;       
  116.         SSC_DAT=0X0;
  117.       }
  118.     }

  119.    //数据流
  120.     else
  121.     {
  122.       if ( PLC_Rxd_state == 1 )       // 如果已经接收了祯头,继续接收后续字节
  123.       {
  124.       
  125.         PLC_recv_buf[PLC_Rxd_pointer]=SSC_BUF;
  126.         PLC_Rxd_pointer++;

  127.         if ( PLC_Rxd_pointer==PLC_Rxd_tlen )
  128.         {
  129.            PLC_Rxd_OK=1;
  130.            PLC_Rxd_state=0;
  131.            SSC_ADR=0;       
  132.            SSC_DAT=0;
  133.         }
  134.       }
  135.       else       
  136.       {
  137.       PLC_Rxd_state=0;
  138.       SSC_ADR=0X0;       
  139.         SSC_DAT=0X0;
  140.       }
  141.     }
  142.          
  143.   }
  144.   
  145. SSC_ADR=SSC_adr_bak;
  146. }
  147. /*void set_PLC_3200 ( void )
  148. {
  149. SSC_ADR=0XFF;        
  150. SSC_DAT=0XFF;        // 禁止写保护

  151.         SSC_ADR=0x01;        // 选择3201载波通讯控制寄存器1       
  152.         SSC_DAT=40;        // ZZZ 2007-10-15 前导1bit为40个

  153. SSC_ADR=0x03;        // 选择3201载波通讯控制寄存器3       
  154. SSC_DAT=0xc0;        // 开启载波通讯功能,打开中断,选择接收状态置为3200模式

  155. SSC_ADR=0x04;        // 设置捕获门限
  156. SSC_DAT=LIMIT_3200;

  157. SSC_ADR=0XFF;
  158. SSC_DAT=0XAA;        // 使能写保护  
  159. }  */
  160. void set_PLC_3105 ( void )
  161. {
  162. SSC_ADR=0XFF;        // 2005.11.29 LXW
  163.   SSC_DAT=0XFF;        // 禁止写保护
  164.        
  165.         SSC_ADR=0x01;        // 选择3105载波通讯控制寄存器1       
  166.         SSC_DAT=64;        // ZZZ 2007-10-15 前导1bit为64个

  167.         SSC_ADR=0x03;        // 选择3201载波通讯控制寄存器3       
  168.         SSC_DAT=0xe0;        // 开启载波通讯功能,打开中断,选择接收状态置为3105模式
  169.          
  170.         SSC_ADR=0x04;        // 设置捕获门限
  171.   SSC_DAT=LIMIT_3105;
  172.   
  173.   SSC_ADR=0XFF;
  174.   SSC_DAT=0XAA;        // 使能写保护  
  175. }
  176. void initsys ( void )
  177. {  // 控制看门狗喂狗时间长度                         
  178.   CKCON=0xfF;
  179.   // 8位/16位运算模式选择位设置
  180.   ALU_MOD=0;      // 设置成8位运算模式
  181.   //载波通讯配置
  182. //************   3201的载波寄存器设置  **********//
  183.   set_PLC_3105 ( );        //上电为3105模式
  184.   
  185.   SSC_ADR=0xFF;
  186.   SSC_DAT=0xFF;
  187.   SSC_ADR=0x02;
  188.   SSC_DAT=0x1F;
  189.   SSC_ADR=0xFF;
  190.   SSC_DAT=0x00;
  191.   
  192. //************   3201的载波寄存器设置  **********//
  193.   EIE=0X01;       //  ( A9H 使能INT2中断(EX2=1)
  194.   IT2=1;                  //  ( C8H ) 为边沿触发方式(IT2=1)
  195.   
  196. //串口通讯配置
  197.   //TMOD1 = 0x10 ;                     // 设 T/C1 为1分频模式,ZZZ
  198.   TMOD = 0x21 ;                     // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 1
  199.   SCON=0x50;                           // 工作方式1
  200.   
  201.   PCON=0x80;                           // 波特率加倍
  202.   TH1=BPS2400;
  203.   TL1=BPS2400;                        // 加倍设定波特率 9.6MHz ( 按1分频2400计算)
  204.   TR1=1;                               // 启动定时器1
  205.    

  206.   TMOD1=0x32; //time2方式2
  207.   SCON1=0x50; //
  208.   TH2=0xc2;
  209.   TL2=0xc2;
  210.   TR2 =1;
  211.   




  212.   // 定时器0中断配置
  213.   TH0=0x63;
  214.   TL0=0xcc;   // 定时 50 ms 一个定时中断
  215.   TR0 = 1;               // 启动 T0 定时器
  216.   // 中断级别设置
  217.   IP=0x42;                      // 定时器 T0 中断为高级中断
  218.   EIP=1;                 // 外部中断2 为高级中断
  219.   // 中断允许设置
  220.   IE=0x82;
  221.   





  222.                       // 允许ET0=1定时器 T0 中断;  开放中断
  223.   }


  224. void initsys_ref( void )
  225. {  // 载波设置重置
  226.    uchar  data s1;
  227.    uchar  data GOLD_KSAMI;

  228.    if ( EIE!=1 )
  229.       EIE=0X01;       //  ( A9H 使能INT2中断(EX2=1)
  230.    if ( IT2!=1 )       
  231.       IT2=1;                 //  ( C8H ) 为边沿触发方式(IT2=1)

  232.    SSC_ADR=0x02;
  233.    GOLD_KSAMI=SSC_DAT;
  234.    if ( GOLD_KSAMI!=0x1F )
  235.    {
  236.       SSC_ADR=0xFF;
  237.       SSC_DAT=0xFF;
  238.       SSC_ADR=0x02;
  239.       SSC_DAT=0x1F;
  240.       SSC_ADR=0xFF;
  241.       SSC_DAT=0x00;
  242.    }

  243.    // 串口设置重置
  244.    if ( TMOD1!=0x10 )        //2007-10-15 ZZZ
  245.       TMOD1 = 0x10 ;   //1分频模式
  246.    if ( TMOD!=0x21 )
  247.       TMOD = 0x21 ;   // 设 T/C1 为定时方式2 设置为8位自装载计数器  T/C0 为定时方式 14
  248.    if ( PCON!=0x80 )
  249.       PCON=0X80;      // 波特率加倍

  250.    s1=SCON;
  251.    s1=s1&0xf0;
  252.    if ( s1!=0x50 )
  253.      initsys ();

  254.    if ( TH1!=BPS2400 )
  255.       TH1=BPS2400;
  256.    if ( TR1!=1 )
  257.       TR1=1;          // 启动定时器1
  258.       // 定时器0重置


  259.   /*嘻嘻,*/
  260.        
  261.   TMOD1=0x32; //time2方式2
  262.   SCON1=0x50; //
  263.   TH2=OMG;
  264.   TL2=OMG;
  265.   TR2 =1;

  266.   
  267.    if ( TR0!=1 )
  268.      TR0 = 1;        // 启动 T0 定时器

  269.    // 中断设置重置
  270.    if ( IE!=0x82 )
  271.       IE=0x82;
  272.    if ( IP!=2 )
  273.       IP=2;
  274.    if ( EIP!=1 )
  275.       EIP=1;         // 外部中断2 为高级中断
  276. }


  277. void PLC_rset(void)
  278. {
  279.   uchar s1;

  280. /*if( function_now == 0 )         
  281.         {
  282.            // MEAN 3200 FUNCTION
  283. SSC_ADR=0x03;
  284. s1=SSC_DAT;
  285. if ( ( s1&0xf0 )!=0xc0 )
  286. set_PLC_3200 ();
  287. } */
  288. //else if ( function_now == 0xff )        //3105
  289.    //{
  290. SSC_ADR=0x03;
  291. s1=SSC_DAT;
  292. if ( ( s1&0xf0 )!=0xe0 )
  293. set_PLC_3105 ();
  294.   // }
  295. }
  296.   void init_PLC3201(void)
  297.   {
  298.   
  299.   uchar data i;
  300.    uchar data j;

  301.    for ( i=0; i<5; i++ )        //wait for the stabilization of power
  302.    {
  303.       for ( j=0; j<0xff; j++ );
  304.    }  

  305.    for ( i=0; i<5; i++ )
  306.    {
  307.       for ( j=0; j<0xff; j++ );
  308.    }         
  309.    
  310.    PLC_Rxd_OK=0;
  311.    PLC_sending=0;
  312. //   PLC_Rxd_state=0;
  313.     PLC_Rxd_timer=0x00;

  314.   
  315.   
  316.   }
  317. uint8_t Send_PLC_Data( const uint8_t *Src,uint8_t len)
  318. {

  319. memcpy (PLC_Tx_Buf ,Src, len);
  320.    PLC_total_len=len ;
  321.          PLC_send_pointer=0;                                           
  322.          PLC_sending=1;                   
  323.          SSC_ADR=0x03;
  324.         SSC_DAT= ( SSC_DAT|0x01 );
  325. SSC_BUF= PLC_Tx_Buf[PLC_send_pointer];  
  326.          PLC_timer=30;         // 载波发送过程延时控制1.5秒


  327. while (PLC_sending)
  328.   {
  329.   
  330.   if( 0==PLC_timer) return 0;//超时

  331.   }
  332.     if ( PLC_timer == 0 )        // PLC sending finish
  333.   {
  334.   SSC_ADR=0x03;
  335.   SSC_DAT= (SSC_DAT&0xFE);       // 设置3201为REC状态REDUNDANCY
  336.   PLC_sending=0;

  337.   }
  338. return 1;//成功




  339. }
复制代码



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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