zoukankan      html  css  js  c++  java
  • 【.Net Micro Framework PortingKit – 09】串口驱动

    虽然在PC机中,串口渐行渐远,但是在嵌入式领域,串口仍可以说是如日中天,因为它造价低廉、并且编程也比较方便,在没有显示屏或输入设备的系统上,串口更是不可或缺,和超级终端一道,共同解决了信息显示和输入问题。

    经过这几天的努力,在Cortex-M3平台上的.Net Micro FrameworkNativeSample移植工作就要一个段落了,目前已实现启动代码、SRAM、时钟(RCC)、中断(NVIC)、SysTickGPIO、串口、NandFlash(FMSC)等相关功能,这些代码可以说是使TinyClr正常工作的最小集合,有了这些工作做铺垫,下一步就可以移植TinyClr了,如果我们采用的Cortex-M3开发板有2M以上的RAM,那么我们的工作到这一步也许是已经完成90%上了,但是由于资源有限,下一步调试必须为Flash版本,所以未知的工作将很多,并且调试也将变得困难,不管怎么我们的.Net Micro Framework PortingKit之旅还将继续,不过,说心里话,由零开始完成这些工作,虽然艰苦,但是收获颇丰,对ARM开发(尤其是Cortex-M3)的理解更是上了一个层次。

    好了,下面我们要说一下串口驱动的开发。

    GPIO开发一样,我们仍需在CortexM3.h中编写串口相关的寄存器代码。

    struct CortexM3_Usart

    {

     static const UINT32 c_MAX_BAUDRATE = 45000000;

     static const UINT32  c_MIN_BAUDRATE = 1200;

       

     static const UINT32 c_Base1 = 0x40013800;

     static const UINT32 c_Base2 = 0x40004400;

     static const UINT32 c_Base3 = 0x40004800; 

     

     /****/ volatile UINT16 SR;

     static const    UINT16 SR_TXE=((UINT16)0x0080);

     static const    UINT16 SR_TC=((UINT16)0x0040);

     static const    UINT16 SR_RXNE=((UINT16)0x0020);

     

     UINT16 RESERVED0;

     /****/ volatile UINT16 DR;

     UINT16 RESERVED1;

     /****/ volatile UINT16 BRR;

     UINT16 RESERVED2;

     /****/ volatile UINT16 CR1;

     static const    UINT16 CR1_UE_Set = ((UINT16)0x2000);   //USART Enable Mask

     static const    UINT16 CR1_UE_Reset = ((UINT16)0xDFFF); //USART Disable Mask 

     static const    UINT16 CR1_Parity_No = ((UINT16)0x0000);

     static const    UINT16 CR1_Parity_Even = ((UINT16)0x0400);

     static const    UINT16 CR1_Parity_Odd = ((UINT16)0x0600);

     static const    UINT16 CR1_DataBit_8 = ((UINT16)0x0000);

     static const    UINT16 CR1_DataBit_9 = ((UINT16)0x1000);

     static const    UINT16 CR1_Mode_Rx = ((UINT16)0x0004);

     static const    UINT16 CR1_Mode_Tx = ((UINT16)0x0008);

     static const    UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);

     static const    UINT16 CR1_PEIE = ((UINT16)0x0100);

     static const    UINT16 CR1_TXEIE = ((UINT16)0x0080);

     static const    UINT16 CR1_TCIE = ((UINT16)0x0040);

     static const    UINT16 CR1_RXNEIE = ((UINT16)0x0020);  

      

     UINT16 RESERVED3;

     /****/ volatile UINT16 CR2;

     static const    UINT16 CR2_StopBits_1 = ((UINT16)0x0000); 

     static const    UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);

     static const    UINT16 CR2_StopBits_2 = ((UINT16)0x2000); 

     static const    UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);

     static const    UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF); /* USART CR2 STOP Bits Mask */

     

     UINT16 RESERVED4;

     /****/ volatile UINT16 CR3;

     static const    UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000); 

     static const    UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100); 

     static const    UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200); 

     static const    UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300); 

     static const    UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF); 

     

     UINT16 RESERVED5;

     /****/ volatile UINT16 GTPR;

     UINT16 RESERVED6;

    };

    有了上述代码,我们便可以方便的操作串口寄存器了。

    串口的初始化要做如下初始化工作(STM3210E开发板有三个串口,我们以串口1为例来讲述):

    1、 开启串口时钟

        UsartId = CortexM3_NVIC::c_IRQ_Index_USART1;

             RCC.APB2ENR |= CortexM3_RCC::APB2_GPIOA | CortexM3_RCC::APB2_USART1;

    2、 激活中断

        if(!CPU_INTC_ActivateInterruptEx( UsartId, (UINT32)(void *)USART1_IRQHandler)) return FALSE;   

    3、 设置串口参数,如波特率、奇偶校验、数据位、停止位等

    4、 GPIO重定义

    CPU_GPIO_DisablePin(GPIO_Driver::PA9,RESISTOR_DISABLED,FALSE,GPIO_ALT_MODE_1);

    CPU_GPIO_DisablePin(GPIO_Driver::PA10,RESISTOR_DISABLED,TRUE,GPIO_ALT_MODE_2);

    5、 串口使能

    Usart.CR1 |= CortexM3_Usart::CR1_UE_Set;

    在中断函数中完成数据的发送和接收:

    void CortexM3_USART_Driver::ISR( void* param )

    {

        UINT32 comPort = (UINT32)param;

        CortexM3_Usart &Usart=CortexM3::Usart(comPort);

        char c;

        UINT32 Status; 

        Status = Usart.SR;

        if(Status & CortexM3_Usart::SR_RXNE)

        {

            c = Usart.DR;

            USART_AddCharToRxBuffer( comPort, c );

            Events_Set( SYSTEM_EVENT_FLAG_COM_IN );

        }

            

        if(Status & CortexM3_Usart::SR_TC)

        {

            if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))

            {

                return;

            }

            if(USART_RemoveCharFromTxBuffer( comPort, c ))

            {

                WriteCharToTxBuffer( comPort, c ); 

            }

            else

            {

                // disable further Tx interrupts since we are level triggered

                TxBufferEmptyInterruptEnable( comPort, FALSE );

            }

            Events_Set( SYSTEM_EVENT_FLAG_COM_OUT );

        }

    }

    核心代码也就是上述介绍的相关内容,下面我们在NativeSample中写一个串口测试代码:

    void ApplicationEntryPoint()

    {     

        while(TRUE)    

        {     

              if(Events_WaitForEvents(SYSTEM_EVENT_FLAG_COM_IN,100))

              {

                   Events_Clear(SYSTEM_EVENT_FLAG_COM_IN);                   

                     char bytData[512];

                        int Size=USART_BytesInBuffer(0,TRUE);

                        USART_Read(0,bytData,Size);

                        for(int i=0;i<Size;i++)

                     debug_printf("%c",bytData[i]);             

              }

              debug_printf("Hello Micro Framework!!!\r\n");

             }

    }

    代码编译运行后的结果如下:

  • 相关阅读:
    爬虫1 爬虫介绍, requests模块, 代理(正向代理,反向代理), 爬梨视频, 自动登录网站, HTTP协议复习, 伪静态概念, 301和302状态码区别, http版本0.9 1.1 和2.0的区别
    数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树
    算法 时间复杂度, 空间复杂度, 冒泡排序**, 选择排序, 插入算法, 快速排序**, 希尔算法,计数排序, 二分法查找**
    量化分析 在线量化分析网站
    数据分析3 matplotlib绘图, 折线图(刻度与范围,标题,注释), 曲线图例, 过滤报警信息, 柱状图, 曲线图, 饼图
    [编织消息框架][netty源码分析]6 ChannelPipeline 实现类DefaultChannelPipeline职责与实现
    [编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现
    [编织消息框架][netty源码分析]4 EventLoop 实现类NioEventLoop职责与实现
    编程之路
    [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现
  • 原文地址:https://www.cnblogs.com/yefanqiu/p/1655483.html
Copyright © 2011-2022 走看看