本帖最后由 初代饭影 于 2015-1-9 21:34 编辑
说起大家玩板子,一开始应该都是那「永恒的流水灯」吧。我也捣鼓了捣鼓,发个帖作学习记录吧~
上代码,C语言功力不够感觉代码写得有点乱。。帖子标题只是个噱头哈(笑)。有建议的话请多多提出啊
- #include "MKL25z4.h"
- #define OFF 0
- #define ON 1
- #define TOGGLE 2
- #define RED 0
- #define GREEN 1
- #define BLUE 2
- /*--------------------定义宏函数---------------------------*/
- #define BSET(bit, Register) ( Register |= (1 << bit )) //寄存器某位置1
- #define BCLR(bit, Register) ( Register &= ~ (1 << bit )) //寄存器某位清0
- /* 定义LED信息结构体数组 */
- struct LedInfoStruct
- {
- uint8_t ClockLine; //led引脚所在端口对应的时钟线
- uint8_t Pin; //led的引脚
- PORT_Type * PortX; //led对应的PORT
- FGPIO_Type * FptX; //led在GPIO模式下对应的FPT
- }led[3] = {10, 18, PORTB, FPTB, 10, 19, PORTB, FPTB, 12, 1, PORTD, FPTD};
- /**----------------------------------------------------------------------------
- * 函数名称: Delay
- * 函数返回: 无
- * 参数说明: n(略)
- * 功能概要: 用作简单的延时
- *----------------------------------------------------------------------------
- */
- void Delay(uint32_t n)
- {
- uint32_t i;
- for (i = 0; i < n; i++);
- }
- /**----------------------------------------------------------------------------
- * 函数名称: Led_GPIOInit
- * 函数返回: 无
- * 参数说明: led_ID(要初始化的LED号,RED,BLUE,GREEN)
- * 功能概要: 将传入的LED的引脚设为GPIO模式并配置为输出
- *----------------------------------------------------------------------------
- */
- void Led_GPIOInit(uint8_t led_ID)
- {
- /* 开启相应的时钟线 */
- BSET(led[led_ID].ClockLine, SIM->SCGC5);
-
- /* 配置引脚控制寄存器 */
- BSET(8, led[led_ID].PortX->PCR[led[led_ID].Pin]); //设置为GPIO模式
-
- /* 配置相关参数 */
- BSET(led[led_ID].Pin, led[led_ID].FptX->PDDR); //数据方向寄存器
- BSET(led[led_ID].Pin, led[led_ID].FptX->PDOR); //数据输出寄存器
- }
- /**----------------------------------------------------------------------------
- * 函数名称: Led_SetStatus
- * 函数返回: 无
- * 参数说明: led_ID(要初始化的LED号,RED,BLUE,GREEN)
- status(要设定的LED的状态,ON,OFF,TOGGLE)
- * 功能概要: 设置LED的状态(亮,灭,状态反转)
- *----------------------------------------------------------------------------
- */
- void Led_SetStatus(uint8_t led_ID, uint8_t status)
- {
- if (status == ON)
- {
- BSET(led[led_ID].Pin, led[led_ID].FptX->PCOR); //输出清0寄存器
- }
- else if (status == TOGGLE)
- {
- BSET(led[led_ID].Pin, led[led_ID].FptX->PTOR); //输出反转寄存器
- }
- else
- {
- BSET(led[led_ID].Pin, led[led_ID].FptX->PSOR); //输出置1寄存器
- }
- }
- int main(void)
- {
- /* 初始化LED引脚 */
- Led_GPIOInit( BLUE );
- Led_GPIOInit( RED );
- Led_GPIOInit( GREEN );
-
- /* 开灯 o(>_<)o ~~*/
- Led_SetStatus( BLUE, ON );
- Led_SetStatus( RED, OFF );
- Led_SetStatus( GREEN, ON );
-
- while(1)
- {
- /* LED状态取反 */
- Led_SetStatus( BLUE, TOGGLE );
- Delay(5000000);
-
- Led_SetStatus( RED, TOGGLE );
- Delay(500000);
-
- Led_SetStatus( GREEN, TOGGLE );
- Delay(5000000);
- }
- }
复制代码
上面的Led_GPIOInit函数其实跟下面是一样的,只是个人受不了那么多判断语句和基本重复的设置,而且LED灯的数量也不多,于是定义了一个结构体数组把每个LED对应的引脚啊什么端口信息啊扔进去,如果要配置的时候只需从数组中取出就行啦~
/*--------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------*/
/*------------------------------------- suyong哥库登场---------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------*/
上面是操作寄存器的做法,了解了一下如何操作底层寄存器还是行的,但如果要做一个大一点的项目就蛋疼啦,自己写的我都觉得好乱。接下来就用上suyong哥给我们写好的库,看看效果如何
- #include "app_inc.h"
- #include
- #include
- #include
- /**----------------------------------------------------------------------------
- * 函数名称: Delay
- * 函数返回: 无
- * 参数说明: n(略)
- * 功能概要: 用作简单的延时
- *----------------------------------------------------------------------------
- */
- void Delay(uint32_t n)
- {
- uint32_t i;
- for (i = 0; i < n; i++);
- }
- int main(void)
- {
- /* 使能时钟线等 */
- init_board();
-
- /* 设置LED引脚在GPIO模式下的方向 */
- GPIO_SetPinDir(BSP_GPIO_LED_RED_PORT, BSP_GPIO_LED_RED_PIN, true);
- GPIO_SetPinDir(BSP_GPIO_LED_GREEN_PORT, BSP_GPIO_LED_GREEN_PIN, true);
- GPIO_SetPinDir(BSP_GPIO_LED_BLUE_PORT, BSP_GPIO_LED_BLUE_PIN, true);
-
- /* 关闭LED */
- GPIO_SetPinLogic(BSP_GPIO_LED_RED_PORT, BSP_GPIO_LED_RED_PIN, true);
- GPIO_SetPinLogic(BSP_GPIO_LED_GREEN_PORT, BSP_GPIO_LED_GREEN_PIN, true);
- GPIO_SetPinLogic(BSP_GPIO_LED_BLUE_PORT, BSP_GPIO_LED_BLUE_PIN, true);
-
- while (1)
- {
- GPIO_TogglePinLogic(BSP_GPIO_LED_BLUE_PORT, BSP_GPIO_LED_BLUE_PIN);
- Delay(5000000);
-
- GPIO_TogglePinLogic(BSP_GPIO_LED_RED_PORT, BSP_GPIO_LED_RED_PIN);
- Delay(5000000);
-
- GPIO_TogglePinLogic(BSP_GPIO_LED_GREEN_PORT, BSP_GPIO_LED_GREEN_PIN);
- Delay(5000000);
- }
- }
复制代码
用上库,果然清爽多了吧。suyong哥的库写的很好啊,我也会进去底层看看,学习一下他是如何操作寄存器的。真心佩服他。大家也用suyong哥的库吧,效果事半功倍啊米娜桑推荐指数五颗星!
最后我们来看看在板子跑起来的效果,两个程序的现象都是一样的哈
接下来几天有很多门考试,学习的事就慢慢来吧。
0
|
|
|
|
延时的话,还可以参考一下systick_ticker的样例工程,里面有直接使用硬件的Systick模块进行延时的API。
关于初始化GPIO的操作,更安全的做法是,先设定输出值,然后再设定方向为输出,防止在设定输出和设定正确的初始电平器件出现意外。
|
|
|
|
|
原来如此!我看到几个程序都是先配置输出的值再配置输出方向的,个人还不理解为什么不按照逻辑那样先配置方向再配置输出的值呢!原来在这么细微的地方也要很注意才行啊!谢谢suyong哥,以后也要多多指教呢!
|
|
|
|
|
今天在捣鼓程序的时候,发现一个关于打开时钟的小问题,在使能时钟后把三个LED引脚设置为GPIO模式,评估板上三盏灯分别对应PORTB和PORTD时钟,本预想是没打开PORTD的时钟,最多只不过是三盏灯亮两盏,结果却是全部灯都不亮,把那句注释去掉,全部灯都亮了,还是有点想不明白
- #include "MKL25Z4.h"
- #include "gpio.h"
- int main(void)
- {
- /* 开时钟线 */
- SIM->SCGC5 |= (1 << 10);
- // SIM->SCGC5 |= (1 << 12);
-
- /* 初始化FGPIO引脚 */
- FGPIO_Init(PORTB, FPTB, 18, FGPIO_Mode_Out);
- FGPIO_Init(PORTB, FPTB, 19, FGPIO_Mode_Out);
- FGPIO_Init(PORTD, FPTD, 1, FGPIO_Mode_Out);
-
- FGPIO_ResetBit(FPTB, 18);
- FGPIO_ResetBit(FPTB, 19);
- FGPIO_ResetBit(FPTD, 1);
-
- while(1);
- }
复制代码
|
|
|
|
|