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

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

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

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

  1. struct CortexM3_Usart  
  2.  
  3. {  
  4.  
  5.   static const UINT32  c_MAX_BAUDRATE = 45000000;  
  6.  
  7.   static const UINT32  c_MIN_BAUDRATE = 1200;  
  8.  
  9.       
  10.  
  11.   static const UINT32 c_Base1 = 0x40013800;  
  12.  
  13.   static const UINT32 c_Base2 = 0x40004400;  
  14.  
  15.   static const UINT32 c_Base3 = 0x40004800;    
  16.  
  17.    
  18.  
  19.   /****/ volatile UINT16 SR;  
  20.  
  21.   static const    UINT16 SR_TXE=((UINT16)0x0080);  
  22.  
  23.   static const    UINT16 SR_TC=((UINT16)0x0040);  
  24.  
  25.   static const    UINT16 SR_RXNE=((UINT16)0x0020);  
  26.  
  27.     
  28.  
  29.   UINT16  RESERVED0;  
  30.  
  31.   /****/ volatile UINT16 DR;  
  32.  
  33.   UINT16  RESERVED1;  
  34.  
  35.   /****/ volatile UINT16 BRR;  
  36.  
  37.   UINT16 RESERVED2;  
  38.  
  39.   /****/ volatile UINT16 CR1;  
  40.  
  41.   static const    UINT16 CR1_UE_Set = ((UINT16)0x2000);   //USART Enable Mask  
  42.  
  43.   static const    UINT16 CR1_UE_Reset = ((UINT16)0xDFFF); //USART Disable Mask    
  44.  
  45.   static const    UINT16 CR1_Parity_No = ((UINT16)0x0000);  
  46.  
  47.   static const    UINT16 CR1_Parity_Even = ((UINT16)0x0400);  
  48.  
  49.   static const    UINT16 CR1_Parity_Odd = ((UINT16)0x0600);  
  50.  
  51.   static const    UINT16 CR1_DataBit_8 = ((UINT16)0x0000);  
  52.  
  53.   static const    UINT16 CR1_DataBit_9 = ((UINT16)0x1000);  
  54.  
  55.   static const    UINT16 CR1_Mode_Rx = ((UINT16)0x0004);  
  56.  
  57.   static const    UINT16 CR1_Mode_Tx = ((UINT16)0x0008);  
  58.  
  59.   static const    UINT16 CR1_CLEAR_Mask =  ((UINT16)0xE9F3);  
  60.  
  61.   static const    UINT16 CR1_PEIE = ((UINT16)0x0100);  
  62.  
  63.   static const    UINT16 CR1_TXEIE = ((UINT16)0x0080);  
  64.  
  65.   static const    UINT16 CR1_TCIE = ((UINT16)0x0040);  
  66.  
  67.   static const    UINT16 CR1_RXNEIE = ((UINT16)0x0020);     
  68.  
  69.      
  70.  
  71.   UINT16 RESERVED3;  
  72.  
  73.   /****/ volatile UINT16 CR2;  
  74.  
  75.   static const    UINT16 CR2_StopBits_1 = ((UINT16)0x0000);    
  76.  
  77.   static const    UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);   
  78.  
  79.   static const    UINT16 CR2_StopBits_2 = ((UINT16)0x2000);    
  80.  
  81.   static const    UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);   
  82.  
  83.   static const    UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF);  /* USART CR2 STOP Bits Mask */  
  84.  
  85.     
  86.  
  87.   UINT16 RESERVED4;  
  88.  
  89.   /****/ volatile UINT16 CR3;  
  90.  
  91.   static const    UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);    
  92.  
  93.   static const    UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);    
  94.  
  95.   static const    UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);    
  96.  
  97.   static const    UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);    
  98.  
  99.   static const    UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);    
  100.  
  101.    
  102.  
  103.   UINT16  RESERVED5;  
  104.  
  105.   /****/ volatile UINT16 GTPR;  
  106.  
  107.   UINT16  RESERVED6;  
  108.  
  109. };  
  110.  

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

串口的初始化要做如下初始化工作(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;

 

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

  1. void CortexM3_USART_Driver::ISR( void* param )  
  2.  
  3. {  
  4.  
  5.     UINT32  comPort = (UINT32)param;  
  6.  
  7.     CortexM3_Usart &Usart=CortexM3::Usart(comPort);   
  8.  
  9.     char c;  
  10.  
  11.     UINT32 Status;    
  12.  
  13.    
  14.  
  15.     Status = Usart.SR;  
  16.  
  17.     if(Status & CortexM3_Usart::SR_RXNE)  
  18.  
  19.     {  
  20.  
  21.         c = Usart.DR;  
  22.  
  23.         USART_AddCharToRxBuffer( comPort, c );  
  24.  
  25.         Events_Set( SYSTEM_EVENT_FLAG_COM_IN );  
  26.  
  27.     }  
  28.  
  29.            
  30.  
  31.     if(Status & CortexM3_Usart::SR_TC)  
  32.  
  33.     {  
  34.  
  35.         if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))  
  36.  
  37.         {  
  38.  
  39.             return;  
  40.  
  41.         }  
  42.  
  43.         if(USART_RemoveCharFromTxBuffer( comPort, c ))  
  44.  
  45.         {  
  46.  
  47.             WriteCharToTxBuffer( comPort, c );    
  48.  
  49.         }  
  50.  
  51.         else 
  52.  
  53.         {  
  54.  
  55.             // disable further Tx interrupts since we are level triggered  
  56.  
  57.             TxBufferEmptyInterruptEnable( comPort, FALSE );  
  58.  
  59.         }  
  60.  
  61.         Events_Set( SYSTEM_EVENT_FLAG_COM_OUT );  
  62.  
  63.     }  
  64.  
  65. }  
  66.  

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

  1. void ApplicationEntryPoint()  
  2.  
  3. {        
  4.  
  5.     while(TRUE)       
  6.  
  7.     {        
  8.  
  9.            if(Events_WaitForEvents(SYSTEM_EVENT_FLAG_COM_IN,100))  
  10.  
  11.            {  
  12.  
  13.                Events_Clear(SYSTEM_EVENT_FLAG_COM_IN);                      
  14.  
  15.                   char bytData[512];  
  16.  
  17.                      int Size=USART_BytesInBuffer(0,TRUE);  
  18.  
  19.                      USART_Read(0,bytData,Size);  
  20.  
  21.                      for(int i=0;i<Size;i++)  
  22.  
  23.                  debug_printf("%c",bytData[i]);                
  24.  
  25.            }  
  26.  
  27.            debug_printf("Hello Micro Framework!!!\r\n");  
  28.  
  29.          }  
  30.  
  31. }  
  32.  

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

 

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