【.Net Micro Framework PortingKit – 09】串口驱动

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

虽然在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");

         }

}

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

相关文章
【.Net Micro Framework PortingKit – 09】串口驱动
虽然在PC机中,串口渐行渐远,但是在嵌入式领域,串口仍可以说是如日中天,因为它造价低廉、并且编程也比较方便,在没有显示屏或输入设备的系统上,串口更是不可或缺,和超级终端一道,共同解决了信息显示和输入问题。
560 0
【.Net Micro Framework PortingKit - 08】GPIO驱动
要点亮LED灯或获得输入IO的状态应该是比较容易的,打开端口时钟,然后读写相关的GPIO寄存器就可以了,但是要实现一个输入中断,就要费些周折了
496 0
.Net Micro Framework研究—串口操作
试验平台:Digi MF开发板,Digi提供的示例中包含了串口的示例程序
583 0
|
Windows
在Corex-M3开发板上移植.Net Micro Framework系列文章
.NET Micro Framework 将 .NET 的可靠性和效率与 Visual Studio&reg; 的高生产率结合起来,以针对价格较低、资源受限的小型设备开发应用程序,可帮助人们使用熟悉的 Visual Studio 工具来构建托管的嵌入式应用程序。
652 0
【.Net Micro Framework PortingKit – 13】LCD驱动开发
LCD的驱动开发还是比较繁琐一些的,因为LCD的驱动代码分散在三个目录中(题外话,我觉得针对.Net Micro Framework来说,最难的驱动是网卡驱动(特别是wifi驱动)、其次是USB驱动,和它们相比,LCD驱动就是小菜了)
764 0
.Net Micro Framework研究—Digi开发板初探
写的比较基础全面,由于我们北航的研发团队先研究了Digi的开发板,所以直到今天Digi开发板才到我的手上,我的《Micro Framework研究》系列文章以后也会陆续推出
740 0
|
前端开发
【.Net Micro Framework PortingKit - 06】设置芯片时钟
上两篇《修改启动代码&重写向量表》《SRAM初始化&设置NVIC中断表偏移》文章中,我们设置了中断向量表,初始化了RAM,并重设了向量表的地址,本篇文章是相对重要的一篇,我们将设置芯片时钟
578 0
【.Net Micro Framework PortingKit – 12】SysTick驱动开发
SysTick驱动有三个功用,一是我们上面所说的多任务和多线程支持;二是获得系统当前Tick,以此实现延时等待
639 0
【.Net Micro Framework PortingKit(补) – 1】USB驱动开发
USB接口支持8个端点,数据传输支持三种模式:DMA、双缓冲、单缓冲,简单期间,我仅实现了单缓冲模式。首先,我们需要声明USB寄存器相对应的结构体,以期方便操作相关的寄存器。
634 0
.Net Micro Framework研究—带I2C总线的模拟器
I2C以前没有怎么接触过,所以做它的模拟功能,只能靠着感觉走,有不妥之处,还望方家指正。做出了spi相关的模拟功能,做I2C相对也就不难了,只不过用户操作I2C总线读写数据的时候要稍微麻烦一点。
658 0