Cortex-M3处理器的GPIO实验自学
扫描二维码
随时随地手机看文章
以前在学校时不知以后会干什么所以什么都学点,感觉什么有用就拿起学学,但是出来以后发现学没有致以用,于是也开始学者老前辈们抱怨当前教育与社会严重脱钩,但是学校也有冠冕堂皇的理由,我们教你的是思想,教你的是学习的方法。也许社会的现实就是这样吧,一遇到事,公说公有理,婆说婆有理,我们又能奈何?幸亏我们还有网络,幸亏我们还没有完全被封口,所以我们还能发发牢骚,好了,时间不早了,牢骚发的差不多了,下面开始写学习总结。
因为项目所需,所以不得不开始研究M3,我用的是NXP公司的LPC1768这个芯片,它是具有三级流水线的哈佛结构,带独立的本地指令和数据总线以及用于外设的稍微低性能的第三条总线,还包含一个支持随机跳转的内部预取指单元。关于LPC1768这个芯片的内部资源这里就不罗列了,这些数据手册上都写的很详细,以后在学习总结中也会慢慢涉及。好了,今天只是初步测试一下它的GPIO功能,所谓的GPIO也就是通用输入/输出口(General Purpose InputOutput),万丈高楼平地起,慢慢来吧。实验的原理图很简单,就是几个LED灯,关于灯的电流及电压参数,这里不作详细介绍,有兴趣的可以到网上或供应商那里要一份数据手册看一下,做技术的不能懒,有些东西该看的还是要看的。
图1 硬件原理图
硬件原理图很简单了,74LVC244是用来驱动LED的,74LVC244内部就是8个三态门,关于它的详细电气参数,请参阅它的数据手册。关于程序也不是太难,有几个地方要说一下。即然是GPIO实验,当然要关注GPIO的配置了,由于大部分引脚都具有一个以上功能,所以首先要配置引脚功能寄存器PINSEL,只有当引脚配置为GPIO功能时,GPIO的方向位才有效,对于其它功能来说,方向是自动的。关于引脚功能寄存器PINSEL功能如下表所示:
PINSEL寄存器每两位控制一个引脚,由于各个引脚的功能不一样,所以PINSEL0~PINSEL9的配置也相应的有所不同,想详细了解这10个寄存器的功能可以参看《user.manual.lpc17xx》,这个手册可以到NXP的网站上去下载。由于这次实验只是用到GPIO功能,所以暂时不用管这个寄存器,用它的默认值就可以了。
另一个寄存器是引脚模式选择寄存器PINMODE,它控制所有端口的工作模式,包括是否配置上拉/下拉电阻和特定的开漏操作模式等。引脚模式选择寄存器PINMODE的功能如下表所示:
当引脚处于逻辑高电平时,中继模式使能上拉电阻,当引脚处于逻辑低电平时,使能下拉电阻,当引脚配置为输入且不是通过外部驱动时,引脚将保持上一个已知状态。PINMODE_0D寄存器控制寄存器的开漏模式,引脚配置为输出且值为0时,开漏模式会正常地将引脚电平拉低。但是如果输出引脚为1,则引脚输出驱动关闭,等同于改变了引脚的方向,实际上是模拟了一个开漏输出。
除了以上两个寄存器要配置,与GPIO端口相关的寄存器还有快速端口值寄存器FIOPIN可以用来读/写端口的值,端口输出置位寄存器FIOSET,当这个寄存器的相应位置1时,相应端口引脚输出1,当然也可以从这个寄存器读取当前引脚输出的值,与它对应的寄存器是FIOCLR,当寄存器FIOCLR相应位置1时,相应引脚输出0,但这个寄存器是只写寄存器,不能读取数据。好了,关于这些寄存器先总结到这,详细的配置还要看LPC1768的用户手册《user.manual.lpc17xx》,当然也可以经常去NXP网站逛逛看看其它的handbook或whitepaper 好了,下面给出实验程序,由于程序太多,只给出部分,剩下的源文件可以到工程文件夹中去找:
/*********************************************************************************
文件名称:mian.c
功 能: 主要调度函数及应用函数
编译环境: MDKV4.12
时 钟: 外部12MHz
日 期: 11/08/16
作 者: 懒猫爱飞
备 注:NULL
---------------------------------------------------------------------------------
修改内容:NULL
修改日期:XXXX年xx月xx日 xx时xx分
修改人员:xxx xxx xxx
**********************************************************************************/
#include"main.h"
volatile unsigned lONg SysTICkCnt; /* 用于系统时钟计数*/
/********************************************************************************
* 函数名称:void SysTick_Handler (void)
* 函数功能: 系统节拍定时器中断函数,每1ms计数一次
* 入口参数: 无
* 出口参数: 无
* 备 注:无
*******************************************************************************/
void SysTick_Handler (void)
{
SysTickCnt++;
}
/********************************************************************************
* 函数名称:void Delay (unsigned long tick)
* 函数功能: 毫秒级延时函数
* 入口参数: unsigned long tick -- 延时时长
* 出口参数: 无
* 备 注:无
*******************************************************************************/
void DelayMs (unsigned long tICk)
{
unsigned long systickcnt;
systickcnt = SysTickCnt;
while ((SysTickCnt - systickcnt) < tick);
}
/********************************************************************************
* 函数名称:void PortInit(void)
* 函数功能: 端口初始化
* 入口参数: 无
* 出口参数: 无
* 备 注:无
*******************************************************************************/
void PortInit(void)
{
GPIO1->FIODIR = 0xB0000000; /*LEDs on PORT1 defined as Output */
GPIO2->FIODIR = 0x0000007C; /* LEDs on PORT2 defined as Output */
Led1Off(); /* 初始化时熄灭所有的灯*/
Led2Off();
Led3Off();
Led4Off();
Led5Off();
Led6Off();
Led7Off();
Led8Off();
}
/********************************************************************************
* 函数名称:int main(void)
* 函数功能: 主函数
* 入口参数: 无
* 出口参数: 无
* 备 注:无
*******************************************************************************/
int main(void)
{
SystEMInit(); /* 系统初始化,函数在system_LPC17xx.c文件夹中定义*/
SysTick_Config(SystemFrequency/1000 - 1); /* 配置时钟中断,每1ms中断一次*/
/* 在core_cm3.h中定义*/
PortInit(); /* 端口初始化*/
while(1)
{
Led1On(); //LED1开
Led4On(); //LED4 开
DelayMs(200);
Led1Off(); //LED1关
Led4Off(); //LED4关
DelayMs(200);
}
}
因为程序是最基础的实验,所以不是太难,程序中延时函数用的是系统节拍定时器,每1m中断一次,系统