TA的每日心情 | 奋斗 2020-5-27 15:41 |
---|
签到天数: 868 天 连续签到: 1 天 [LV.10]以坛为家III
|
本帖最后由 wambob 于 2017-1-2 18:43 编辑
ASF库里有3个IOPORT例程,为了进一步学习IOPORT,打开了第二个例子,细看之下,发现控制管脚的函数不相同。第二个例子里直接控制端口的一个管脚。
比如:
例一中的函数- ioport_set_port_dir(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK, //设置LED端口、位、方向为输出
- IOPORT_DIR_OUTPUT);
复制代码 例二中的函数- ioport_set_pin_dir(EXAMPLE_LED, IOPORT_DIR_OUTPUT);
复制代码 两个函数都可以控制端口的一个管脚,区别是,例一中的函数不仅可以控制一个管脚,还可以控制一组。PIO在数据手册中的说明是并行I/O口。相关寄存器是32位的:
实际上引出的只有一部分:
那么第三个例程给的是什么知识呢,打开例程3,发现使用的函数和例程二一样,只不过在函数参数中使用了函数返回值作为实参。- ioport_set_pin_level(EXAMPLE_LED,
- ioport_get_pin_level(EXAMPLE_BUTTON));
复制代码 我想驱动16位的LCD,结果发现一个问题。回顾例一中的控制端口的函数:- /* Set LED IOPORTs high */
- ioport_set_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK,
- IOPORT_PIN_LEVEL_HIGH);
复制代码 这个真能控制LED脚输出高电平吗?
为什么这么说?
先看看这个函数的3个参数:
1.#define EXAMPLE_LED_PORT (0) 且#define IOPORT_PIOA 0 这个表示端口A,没问题
2.#define EXAMPLE_LED_MASK ((1 << 16))
这句表示PA端口的第17个管脚,PA16 也没问题。
3.这个参数是个枚举常量- enum ioport_value {
- IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */
- IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */
- };
复制代码 看上去似乎没有问题。先不讲真确答案。先验证下:去掉原先的端口翻转函数- ioport_toggle_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK); //翻转LED端口
复制代码 while循环里换成如下语句测试- ioport_set_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK, //设置LED端口、位、电平高
- IOPORT_PIN_LEVEL_LOW);
- delay_ms(500);
- ioport_set_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK, //设置LED端口、位、电平高
- IOPORT_PIN_LEVEL_HIGH);
- delay_ms(500);
复制代码 目的是使端口A的PA16 输出占空比50%,周期1s的方波驱动LED闪烁,结果编译后下载到板上,LED只亮,并不闪烁。这就有问题了?
来追根逐源下此函数原型:- static inline void ioport_set_port_level(ioport_port_t port,
- ioport_port_mask_t mask, ioport_port_mask_t level)
- {
- arch_ioport_set_port_level(port, mask, level);
- }
复制代码 调用了一个封装的函数,继续:- __always_inline static void arch_ioport_set_port_level(ioport_port_t port,
- ioport_port_mask_t mask, ioport_port_mask_t level)
- {
- Pio *base = arch_ioport_port_to_base(port);
- base->PIO_SODR = mask & level;
- base->PIO_CODR = mask & ~level;
- }
复制代码 端口解析后赋给了一个Pio类型的指针。
下面这两条语句当level的值为1时无论如何也不能把第一位除外的mask位置1,当level值为0时也不能把第一位除外的mask位置0;
而主程序中传过的参数是枚举常量0和1。
这个函数如果要正常工作,置1时两个参数mask和level相同。清0时相反。
修改主程序whilex循环验证代码:- /* Toggle LED IOPORTs with half a second interval */
- ioport_set_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK,
- EXAMPLE_LED_MASK);
- delay_ms(500);
- ioport_set_port_level(EXAMPLE_LED_PORT, EXAMPLE_LED_MASK,
- ~EXAMPLE_LED_MASK);
- delay_ms(500);
复制代码 编译后下载代码,观察板子,LED闪烁了。
|
评分
-
查看全部评分
|