Atmel Software Framework学习笔记 — 端口控制
Atmel Software Framework学习笔记 — IO端口控制上一贴讲了系统时钟配置,这一贴将会给大家讲解IO端口控制软件包。
按照 系统时钟 配置贴内步奏建立一个ASF工程,打开ASF Wizard管理器,向项目中添加 驱动包。
本例子包含的程序模块如下
(本例子设置系统时钟为DFLL32MHz时钟,不会的童鞋请看前一贴系统时钟)
本帖主要讲几个常用的函数,其他的函数需要有兴趣的童鞋自己查看IOPORT的API手册了。
例1:LED闪烁(PE0外接了LED,控制LED的状态。)
这个例子主要讲如何创建一个端口,并使用软件包的函数来控制端口输出。
使用一个PIN之前,我们要先创建这个PIN的定义,打开config文件夹下的conf_board.h,在此建立端口定义(其他文件内也可以,主要是营造一个良好的编程风格,大家根据自己的风格来)
IOPORT_CREATE_PIN(PORT,PIN bp)这个其实是一个宏,其原型如下
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
这个宏什么意思,有兴趣的可以研究下,很简单,我不说了。
创建好PIN后,如何使用它呢?
按照AVR Mega系列的步奏,当然是先设置端口的方向,是输出还是输入?是否内部上拉等等。Xmega也不例外。一般常用来设置PIN的函数为
ioport_configure_pin(pin,flags)
参数pin是我们前面创建的PIN宏,flags设置这个PIN的初始化状态(输入输出,是否上拉,边沿感知等等)我们把LED01设置为输出,初始电平为高电平:
Init.c文件board_init函数
将端口输出高电平:
ioport_set_pin_high(LED01);
ioport_set_pin_level(LED01,true);
这2个函数都可以将PIN设置为高电平,任选一个自己喜欢的。
将端口输出低电平:
ioport_set_pin_low(LED01);
ioport_set_pin_level(LED01,false);
同样任选其一。
将端口取反输出:
ioport_toggle_pin(LED01);
ioport_toggle_pin_level(LED01);
好吧,最简单的例子,LED 闪烁
#define F_CPU 32000000UL
#include <asf.h>
#include <util/delay.h>
int main (void)
{
// Insert system clock initialization code here (sysclk_init()).
sysclk_init();
board_init();
while(1)
{
ioport_set_pin_high(LED01);
_delay_ms(500);
ioport_set_pin_low(LED01);
_delay_ms(500);
}
}
While循环里面也可以写成:
ioport_toggle_pin(LED01);
_delay_ms(500);
例2:用按钮控制LED状态(PD0接了按钮,控制PE0的LED,按下时亮,松开时灭)
创建PIN
#define BUTTON01 IOPORT_CREATE_PIN(PORTD,PIN0_bp)
设置PIN为输入,内部上拉
ioport_configure_pin(BUTTON01,IOPORT_DIR_INPUT | IOPORT_PULL_UP);
如何获取PIN的状态呢?可以使用如下函数:
ioport_pin_is_high(PIN);//读取PIN状态,高电平返回1,低电平返回0
ioport_pin_is_low(PIN); //读取PIN状态,低电平返回1,高电平返回0
按下按钮后,PIN将检测到低电平,所以我们使用
ioport_pin_is_low(BUTTON01);
最终代码:
#define F_CPU 32000000UL
#include <asf.h>
#include <util/delay.h>
int main (void)
{
// Insert system clock initialization code here (sysclk_init()).
sysclk_init();
board_init();
while(1)
{
if (ioport_pin_is_low(BUTTON01))
{
ioport_set_pin_level(LED01,false);
}
else
{
ioport_set_pin_level(LED01,true);
}
}
}
IOPORT模块里面有很多有用的函数,大家可以自行研究,比如设置一组PIN的输入输出,一个端口的PIN输入输出等等,都非常好,有兴趣的童鞋自行研究,有不理解的地方可以共同讨论。
关于函数里面使用到的宏定义,如IOPORT_PULL_UP、IOPORT_DIR_OUTPUT 等等,请感兴趣的童鞋自己定位到宏定义的文件查看其它可用值。如果不会定位到文件,请看下图:
下一贴——不知道先讲中断还是先讲TC了,看情况吧。 看不懂LZ使用的是什么,但真的觉得很好,好像是使用库的! pangbin4 发表于 2015-1-2 22:09
看不懂LZ使用的是什么,但真的觉得很好,好像是使用库的!
类似,是ATMEL官方写的软件包,这样就可以不需要关心底层的各种寄存器什么的了,跟STM32的库差不多,ATMEL的库用的人不多,主要是好多人不会用,所以才分享这个的,这个就是大家常说的ASF了 zyin123 发表于 2015-1-3 23:27
类似,是ATMEL官方写的软件包,这样就可以不需要关心底层的各种寄存器什么的了,跟STM32的库差不多,ATME ...
支持!希望出更多的教程!方便我等菜鸟学习一下!谢谢 学习了,几号。 用库就不用太了解数据手册中的各种地址和定义了。 mark{:smile:}{:smile:}{:smile:}{:smile:} #define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
看不懂这行种*8+是什么意思,望指点谢谢。 ioport 头文件里有定义的。主题思路是为所有PORT每个Pin分配ID,这个ID就是pin唯一识别码,以后程序引用时就可以忽略pin在哪个port。
具体实现方法就是自port A B C D E…… 开始预定义一个数0 1 2 3 4 。然后比如你有个led连接到portb pin3,那么初始化时就先创造这个led与pin的连接关系----
#define LED IOPORT_CREATE_PIN(PORTB, 3)
关系公式就是下面的宏
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
LED的ID数值= IOPORT_PORTB×8+3=1×8+3=11。以后再提LED,就是提PIN 11。
LED置位清零配置等操作时,底层宏替换反推出led在哪个在哪个port哪个pin。不用再操心。 qqwwzzxx 发表于 2015-3-28 21:02
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
看不懂这行种*8+是什么意思,望指 ...
已经回复你了。你应该还在论坛。 真是挖坟啊,几年了。还是谢谢。 qqwwzzxx 发表于 2017-5-30 17:52
真是挖坟啊,几年了。还是谢谢。
专业挖坟,技术挖坟。相信品牌的力量! 这个一直不知道怎么用。{:sweat:}
页:
[1]