首页专栏详情
打赏
新唐cortex-m0之RS485通讯
易百纳技术社区 在学了在学了! 2020-10-10 13:00:00

如果大家用的新唐的板子的话,而又要用485通讯功能,一定会去参考自带的UART_DEMO示例程序。新唐的实例程序分为两种类型,一种就是寄存器版本的,一种叫做API版本的。如果用API写程序的同仁们,一定会非常欣慰,因为这个示例程序就是485的,只要改改就行了,而用寄存器版本写程序的一定非常苦恼(笔者就是一直用寄存器版本的写程序),因为它就是一个普通的UART通讯功能,很多人会想着看看API的版本的,慢慢翻译成寄存器版本的,但是两者有些区别,经过这两天的深入,我已经把API版本改成了寄存器版本,改的是面目全非,因为我的初始化代码几乎和API的版本的一样,但是它能运行出结果,而我不行,这如何不叫人纠结呢?

在新唐的两个版本中,有这样两个区别,大家需要注意的:

  1. API版本中,用的UART时钟是内部的22MHZ的晶振,大家一定看到了算晶振的波特率的函数,所以没有深入看,只知道可以得出自己想要的晶振就可以了(一般用9600的波特率),而寄存器版本中用的还是外部的12MHZ晶振
  2. 第二个不同的地方也是我纠结了3个星期终于发现了,也是我的问题所在的,就是API版本中,配置了管脚为RTS0功能,而寄存器版本中没有,所以即使后面初始化和API非常相似,也出不来结果,这是一个很重要的原因!(RTS0功能就是自动方向控制,是485中用来控制收发的) 解决了这两个问题,485通讯来说,基本就可以平坦大道了,但是这样说也许很空虚,下面附上485的电路图和485初始化的寄存器版本的代码,希望对大家有帮助,只是新唐Cortex-M0的代码,如果不是这个芯片的可以看看步骤,应该也没有什么太大问题。

如下图就是RS85通讯的电路图:

下面是代码部分:

    #define UARTClkSource_in22MHZ   (CLKSEL1 = ((CLKSEL1 & (~UART_CLK)) | UART_22M))
    #define UART0_Clock_EN    APBCLK |= UART0_CLKEN   // Enable UART0 clock

    void UART_Init(void)

    {

        /* Step 1. GPIO initial */ 

        P3_MFP &= ~(P31_TXD0 | P30_RXD0);   

        P3_MFP |= (TXD0 | RXD0);            //P3.0 --> UART0 RX

                                //P3.1 --> UART0 TX

        P0_MFP &= ~(P03_AD3_RTS0 | P02_AD2_CTS0);

        P0_MFP |= (RTS0 | CTS0);            //P0.3---->RTS0自动方向控制

                                        //这里就是配置的地方,笔者就是这里错了,导致了3个星期没有出来,       

        /* Step 2. Enable and Select UART clock source  */

        UART0_Clock_EN;         //UART Clock Enable, APBCLK[16]:1

      //UARTClkSource_ex12MHZ;  //UART Clock is ext12MHz, CLKSEL1[25,24]: 00

        UARTClkSource_in22MHZ;  //使用内部22MHZ晶振

        CLKDIV &= ~(15<<8);     //UART Clock DIV Number = 0;

        /* Step 3. Select Operation mode */

        IPRSTC2 |= UART0_RST;   //Reset UART0

        IPRSTC2 &= ~UART0_RST;  //Reset end

        UA0_FCR |= TX_RST;      //Tx FIFO Reset

        UA0_FCR |= RX_RST;      //Rx FIFO Reset

        UA0_FCR |= RFITL_1;     //设置为1个字节触发中断

        UA0_LCR &= (~SPE);

        UA0_LCR &= (~EPE);

        UA0_LCR &= (~PBE);      //Parity Bit Disable  校验禁止

        UA0_LCR &= ~WLS;

        UA0_LCR |= WL_8BIT;     //8 bits Data Length  8位长度

        UA0_LCR &= NSB_ONE;     //1 stop bit          1位停止位

        /* Step 4. Set BaudRate to 115200*/

        //UA0_BAUD |= DIV_X_EN;   //Mode2:DIV_X_EN = 1

        //UA0_BAUD |= DIV_X_ONE;  //Mode2:DIV_X_ONE =1

      //上面是使用12M晶振的波特率设置
      //下面的是使用22M晶振波特率的设置

        UA0_BAUD &= (~(1<<29));     //    UA0_BAUD |= (1<< 29);   //Mode2:DIV_X_EN = 1

        UA0_BAUD &= (~(1<< 28));            //    UA0_BAUD |= (1<< 28);  //Mode2:DIV_X_ONE =1

        /* For XTAL = 12 MHz */

        //UA0_BAUD |= ((12000000 / 9600) -2);   //Set BaudRate to 115200;  UART_CLK/(A+2) = 
                                                    //115200, UART_CLK=12MHz
        /*FOr 12MHz*/
        UA0_BAUD |= ( 22118400UL / 9600/16  -2);

         /* For XTAL = 11.0592 MHz */

        //UA0_BAUD |= ((11059200 / 115200) -2); //Set BaudRate to 115200;  

                                                 //UART_CLK/(A+2) = 115200, UART_CLK=12MHz

    }

    void initRS485(void) {  UA0_FUN_SEL = RS485_EN;      //设置为485功能  UA0_FCR |= (RX_DIS);      //禁止接收器接受
     UA0_RS485_CSR |= RS485_NMM;    //设置为485普通操作模式  UA0_RS485_CSR |= RS485_AUD;    //设置为控制自动方向模式

     /* 开启UART0中断 */  UA0_IER |= RDA_IEN;       //开启可接受数据中断和  UA0_IER |= RLS_IEN;       //接收器上中断状态使能,是一个错误中断,见M0手册
     NVIC_ISER |= UART0_INT; // NVIC_IPR3 |= UART0_PRI0;      //设置优先级为3(最小优先级) }

     void initRS485(void)

     {

        UA0_FUN_SEL = RS485_EN;                 //设置为485功能

        UA0_FCR |= (RX_DIS);                    //禁止接收器接受

        UA0_RS485_CSR |= RS485_NMM;             //设置为485普通操作模式

        UA0_RS485_CSR |= RS485_AUD;             //设置为控制自动方向模式

    //  UA0_IER |= AUTO_RTS_EN;

    //  UA0_FCR  |= RTS_TRI_4;

    //  UA0_MCR |= (LEV_RTS_H);                 //设置RTS为1,使能485驱动器

        /* 开启UART0中断 */

        UA0_IER |= RDA_IEN;                     //开启可接受数据中断和

        UA0_IER |= RLS_IEN;                     //接收器上中断状态使能

        NVIC_ISER |= UART0_INT;

    //  NVIC_IPR3 |= UART0_PRI0;                //设置优先级为3(最小优先级)

     }

原文链接:https://blog.csdn.net/memoryjs/article/details/6795803?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159728998019725211962540%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=159728998019725211962540&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v1~rank_blog_v1-11-6795803.pc_v1_rank_blog_v1&utm_term=%E6%96%B0%E5%94%90&spm=1018.2118.3001.4187

2720
收藏
点赞
打赏
给作者打赏,鼓励他抓紧创作吧~
人在车底,非常的菜。
评论
0个
内容存在敏感词
相关专栏
打赏作者
易百纳技术社区
在学了在学了!
您的支持将鼓励我继续创作!
打赏金额:
¥1 易百纳技术社区
¥5 易百纳技术社区
¥10 易百纳技术社区
¥50 易百纳技术社区
¥100 易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区 微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

审核成功

发布时间设置
发布时间:

审核失败

失败原因
备注
Loading...
易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区
易百纳技术社区
在专栏模块发布专栏,可获得其他E友的打赏
易百纳技术社区
回答悬赏问答,被题主采纳后即可获得悬赏金
易百纳技术社区
在上传资料时,有价值的资料可设置为付费资源
易百纳技术社区
达到一定金额,收益即可提现~
收益也可用来充值ebc,下载资料、兑换礼品更容易
易百纳技术社区
活动规则
  • 1.周任务为周期性任务,每周周一00:00刷新,上周完成的任务不会累计到本周,本周需要从头开始任务,当前任务完成后才可以完成下一个任务
  • 2.发布的专栏与资料需要与平台的板块有相关性,禁止注水,专栏/资料任务以审核通过的篇数为准
  • 3.任务完成后,现金奖励直接打款到微信账户;EBC/收益将自动发放到个人账户,可前往“我的钱包”查看;其他奖励请联系客服兑换
  • 4.每周最后三个任务将会有以下奖品掉落:社区热卖开发板、小米音响、视频年度会员、京东卡、华为手机等等
易百纳技术社区
升级提醒
易百纳技术社区

恭喜您由入门

社区送出礼品一份

请填写您的收件地址,礼品将在3个工作日寄出

易百纳技术社区