Keil uVision5开发一个基于LPC17XX系列芯片的工程文件

1 如何使用keil5建立一个工程文件

本篇文章所讲内容基于LPC1759芯片展开(公司用LPC比较多,M0、M3都用,对于LPC系列芯片,开发流程大同小异,如果以后用到STM32再总结跟大伙分享),比较完整地展现一个软件项目的开发,内容比较基础,希望对一些刚入门的同学有些帮助。(PS:我也是菜鸟,从事应用层的开发已经两年多,但是最近才着手负责一个较完整的小项目,期间的一些小感悟、小收获非常乐意拿出来跟大家交流分享,不对的地方还请各位高手赐教哈~使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

打开keil5软件(需要软件安装包的同学私我哈,keil5安装包,以及AK100仿真器驱动都可以提供),创建一个新工程文件,如图1所示。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图1


取文件名称:lpc1759example,如图2所示。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图2

进入选择MCU界面,如图3所示。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图3

通过Manage Run-Time Environment可把keil5工具提供的针对开发者所选的MCU的软件功能加载到文件中,我一般就按照图4所示选择。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图4

说几点,本文创建的工程文件为前后台模式,不采用任何实时操作系统,如果你对keil5工具自带的RTX感兴趣,可以进一步研究,目前我们公司开发用的都是UCOS。另外不太建议直接从Manage Run-Time Environment中加载比如GPIO、UART等等硬件相关的代码,一般针对某款MCU开发时,大多数情况下都可以从网上获得相关的开发例程,如各个硬件初始化、简单应用代码等。所以,建议采用开发例程的代码。

如图5所示,一个初步的工程文件搭建好了,接下来的工作主要就是配置工程文件、加载自己编写的代码丰富工程文件功能。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图5

如图6所示,在"Target1"位置右击,点击“Manage Project Items”,进入图7所示界面,可以增加、删除“Project Targets”"Groups",或者修改名称。还有重要一步,就是配置目标选项。

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图6

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图7

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件点击该按钮,进入配置目标选项。

图8、图9跟所选芯片相关,图8就是选择的MCU,图9的ROM、RAM大小自动跟图8所选芯片匹配,采用默认即可。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图8

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图9

 

图10注意勾选“Create Hex File”,否则编译完程序在output里找不到hex文件,图11、图12、图13、图14、图15采用默认配置即可。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图10

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图11

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图12

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图13

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件
图14


使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图15

图16需要注意的是,你所用的仿真器选择,在这之前一定要安装好仿真器的驱动,否则在图16里找不到你要配置的仿真器,目前我都是用AK100仿真器,对应的就是“TKScope Debug for ARM”,然后点击右边的“Settings”按钮。如图17所示,进行“硬件选择”配置,如图18所示,进行“程序烧写”配置,其他选项可以不用改动,感兴趣的话再细究。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图16

 

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图17

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图18

 

2 开始编写代码

在编写代码前,要根据项目的功能要求,确定使用哪些硬件,根据硬件使用情况,决定主频、外设频率大小。

(这个时候,手头上肯定要准备好芯片用户手册和相关开发例程)。关于主频该取多大,一是考虑芯片最大支持多少,肯定不能超过芯片的要求,二是如果外设使用的不太多也不复杂,建议主频不要太大,太大功耗大,太小对于SPI等读写速率有影响,对于lpc1759,主频定为48MHz(外部晶振频率为12MHz)或主频定为44236800Hz(外部晶振频率为11059200Hz),统一外设频率定为二分之一的主频,至于SPI的CLK到底多大,可以通过SPI相关寄存器分频设置。主频、外设频率设定等系统初始化(一般main函数的首行代码),在“system_LPC17xx.c”文件里修改,内容比较少也比较简单,遇到一些寄存器的设置,可以查用户手册。

如图19所示,新建一个文件,按照图20所示保存。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图19



使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图20


 

把main.c文件加载到工程里的UserCode下,如图21所示。接下来开始编写main函数框架,一个简单的框架如图22所示。之后的工作就是根据项目要求,一点一点添加功能,应用层或底层驱动都会涉及到。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图21



使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

图22

3 使用一个硬件,要编写哪些代码?

这一小节,通过UART的例子,跟大家详解一下。牵扯到硬件,对于菜鸟而言,有例程会大大降低开发难度,也容易避免掉进不知名的坑里。用到硬件,首先要初始化,参考例程加上查询芯片用户手册,根据自己的应用要求,写好应该不难。

void UART_Ini(uint8_t PortNum, UARTMODE set,uint32_t baudrate)
{
  uint16_t ulFdiv;
 
  //参数过滤保护
  if((set.datab<5) ||(set.datab>8))  return;
  if( (set.stopb==0)||(set.stopb>2) ) return;
   if( set.parity>4 ) return;
 
  if(PortNum == 0)                                                     //UART0
  {
    LPC_PINCON->PINSEL0 |= (0x01 << 4)|(0x01 << 6);
    LPC_SC->PCONP  |= 0x08;                                            //打开串口0功能   
    LPC_UART0->LCR  = 0x80;                                            //允许设置波特率
    ulFdiv = (Fpclk /16) / baudrate;                                   //设置波特率 Fpclk为外设频率
    LPC_UART0->DLM  = ulFdiv / 256;
    LPC_UART0->DLL  = ulFdiv % 256;
    LPC_UART0->LCR  = 0x00;                                            //锁定波特率
    LPC_UART0->FCR  = 0x87;                                            //使能FIFO 设置8个字节触发点
   LPC_UART0->LCR  |= (set.datab-5);                                //数据位设置

    if(set.stopb ==2 )                                                           //2位停止位
   {   
      LPC_UART0->LCR |= 0x04;
    }
   if(set.parity !=0 )                                                            //有校验位
   {
    LPC_UART0->LCR |= 0x08;
    LPC_UART0->LCR |=((set.parity-1)<<4);                     //奇偶校验设置
   }
    NVIC_EnableIRQ(UART0_IRQn);
    NVIC_SetPriority(UART0_IRQn, 4);
    LPC_UART0->IER  = 0x01;                                           //使能接收中断   
  }

在硬件初始化函数里调用情况如图23所示。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件
图23


 

 

一般使用UART收发数据,都是采用中断方式,所以还要写相应的中断服务函数。在上面创建的工程文件中,UART0的中断服务函数名有默认的,为UART0_IRQHandler,在Starup_LPC17xx.s中可以找到,采用默认函数名称即可。中断函数如下:

void UART0_IRQHandler (void)
{
  uint8_t  i;
 Start: 
  if((LPC_UART0->IIR  & 0x0F ) == 0x02 )                               //发送中断                             
  {
    if (GETBIT(ui_FlgUART[UART0],6))                                       //在发送状态中
    {
     for (i=0; i<8; i++)
     {
       if(uc_UartPtrTx[UART0] >= uc_UartTxLen[UART0])              //发送完数据
       {
         CLRBIT(ui_FlgUART[UART0],6);
         uc_UartPtrTx[UART0] = 0;   
         uc_UartPtrRx[UART0] = 0;
         LPC_UART0->IER  = 0x01;                                           //使能接收中断   
         goto End;
       }
         LPC_UART0->THR = uc_UartTxbuf[UART0][uc_UartPtrTx[UART0]];
         uc_UartPtrTx[UART0] ++ ;  
     }  
       goto Start;
   }  
    else
    {
     LPC_UART0->IER  = 0x01;                                          //使能接收中断
    }   
  }
 
  if((LPC_UART0->IIR & 0x0F ) == 0x04 ||(LPC_UART0->IIR & 0x0F ) == 0x0C)   //接收数据
 {
  if(!GETBIT(ui_FlgUART[UART0],6))                                                                    //不在发送状态
  {
   s_Tmr10ms.ui_UartRxTimeOut[UART0] = 5;
    for(i=0; i<8; i++)
      {
      if( (LPC_UART0->LSR & 0x01)==0 )                                            //FIFO空
      {
     uint8_t  uc_Buf;
       uc_Buf = LPC_UART0->RBR;    
       break;
      }
        uc_UartRxbuf[UART0][uc_UartPtrRx[UART0]] = LPC_UART0->RBR;     //接收数据
       uc_UartPtrRx[UART0] ++ ;
       uc_UartRxLen[UART0] = uc_UartPtrRx[UART0]; 
      }
      goto Start;
  }
  else
  {
   LPC_UART0->IER  = 0x02;                                                                   //使能发送中断
  }
  
 }
 End:;
}

 

 在接收数据中断里,通过 s_Tmr10ms.ui_UartRxTimeOut字节超时定时器,来判断数据收没收全,时间到了,数据接收标志置起(在10ms定时器里做)。对于一些有固定帧头帧尾格式的数据报文,在接收里可做详细判断,不必采用字节超时方法。在main函数的主循环中,接收数据处理代码如图24所示。ui_FlgUART[UARTNum]的bit1位即为接收数据标志。

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件
图24

 

接收完数据做了相关处理后,要发送回复数据,代码构成如图25所示。


使用keil5工具开发一个基于LPC17XX系列芯片的工程文件
图25


 

 

void SetRTS(eUARTNum UARTNum)
{
  ui_FlgUART[UARTNum] |= 0x0020;      //setbit 5
  uc_UartPtrTx[UARTNum] = 0;
}
如果是通过硬件RTS控制数据发送的话,SetRTS里还要增加相关的硬件控制,我这里就是置起发送标志,另外清除了一下发送数据长度。

 

void StartTD485(eUARTNum UARTNum)      //发送启动函数
{
 
  uc_UartPtrTx[UARTNum] = 0;
 memset(uc_UartRxbuf[UARTNum],0,sizeof(uc_UartRxbuf[UARTNum]));
 SETBIT(ui_FlgUART[UARTNum],6); 
  CLRBIT(ui_FlgUART[UARTNum],5);
 
 if(UARTNum==UART0)
 {
   LPC_UART0->THR = uc_UartTxbuf[UART0][uc_UartPtrTx[UART0]];
   uc_UartPtrTx[UART0] ++ ;
   if(uc_UartPtrTx[UART0] >= uc_UartTxLen[UART0])                //发送完数据
    {
       CLRBIT(ui_FlgUART[UART0],6);
       uc_UartPtrTx[UART0] = 0;   
       uc_UartPtrRx[UART0] = 0;
      LPC_UART0->IER  = 0x01;                                          //使能接收中断    
      return;
    }
    if( uc_UartPtrTx[UART0]!=0)
   { 
      LPC_UART0->IER  = 0x02;                         //使能发送中断还有未发送完的数据进入发送中断接着发送
   }          
  }

 }

使用UART收发数据,基本就涉及到以上方面。

 

最后附一张,我做的一个小项目的工程文件结构图26。建议大家,应用层代码、不同硬件的底层代码放在不同的文件目录里,方面维护,增加或删除文件都比较方便,养成好习惯哦~

使用keil5工具开发一个基于LPC17XX系列芯片的工程文件
图26

代码功能完成好了,接下来就是结合硬件仿真调试了,期间可能会出现各种各样的问题,多跟硬件工程师沟通,很重要哦~使用keil5工具开发一个基于LPC17XX系列芯片的工程文件

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妈妈爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值