MKL25Z芯片采用cotex-M0+的内核,片上外设有定时器,GPIO,DMA,PWM等,该芯片的资源和其他cotex内核的芯片大同小异。
但是笔者的学校上课用的都是这样一款单片机,所以打算把每一次的实验都记录在博客园上。从最简单的GPIO开始吧!实现一个点灯操
作。好了废话不多说了,直接进入正题,笔者用一个开关实现led灯状态的切换,按下红灯亮,蓝灯灭,释放蓝灯亮,红灯灭。笔者打算
以后有时间了准备,做一个按键的长按和短按。
首先定义一个位带操作,因为cotex-m0+没有位带操作的地址,因此定义一个结构体实现像cotex-m3那样的位带操作能给编程带来很大的方
遍。
1 #ifndef __SYS_H__ 2 #define __SYS_H__ 3 4 #include <MKL25Z4.H> 5 #include "stdint.h" 6 7 #define mask(x) (1UL << (x)) 8 #define size(arr) (sizeof(arr)/arr[0]) 9 10 11 //IO operation 12 typedef struct 13 { 14 uint16_t bit0 : 1; 15 uint16_t bit1 : 1; 16 uint16_t bit2 : 1; 17 uint16_t bit3 : 1; 18 uint16_t bit4 : 1; 19 uint16_t bit5 : 1; 20 uint16_t bit6 : 1; 21 uint16_t bit7 : 1; 22 uint16_t bit8 : 1; 23 uint16_t bit9 : 1; 24 uint16_t bit10 : 1; 25 uint16_t bit11 : 1; 26 uint16_t bit12 : 1; 27 uint16_t bit13 : 1; 28 uint16_t bit14 : 1; 29 uint16_t bit15 : 1; 30 31 uint16_t bit16 : 1; 32 uint16_t bit17 : 1; 33 uint16_t bit18 : 1; 34 uint16_t bit19 : 1; 35 uint16_t bit20 : 1; 36 uint16_t bit21 : 1; 37 uint16_t bit22 : 1; 38 uint16_t bit23 : 1; 39 uint16_t bit24 : 1; 40 uint16_t bit25 : 1; 41 uint16_t bit26 : 1; 42 uint16_t bit27 : 1; 43 uint16_t bit28 : 1; 44 uint16_t bit29 : 1; 45 uint16_t bit30 : 1; 46 uint16_t bit31 : 1; 47 } Bits32_TypeDef; 48 49 50 #define PAin(n) ( ( GPIOA->PDIR&(1 << (n)) )>>n ) 51 #define PBin(n) ( ( GPIOB->PDIR&(1 << (n)) )>>n ) 52 #define PCin(n) ( ( GPIOC->PDIR&(1 << (n)) )>>n ) 53 #define PDin(n) ( ( GPIOD->PDIR&(1 << (n)) )>>n ) 54 #define PEin(n) ( ( GPIOE->PDIR&(1 << (n)) )>>n ) 55 #define PFin(n) ( ( GPIOF->PDIR&(1 << (n)) )>>n ) 56 57 #define PAout(n) ( ((Bits32_TypeDef *)(&(GPIOA->PDOR)))->bit##n ) 58 #define PBout(n) ( ((Bits32_TypeDef *)(&(GPIOB->PDOR)))->bit##n ) 59 #define PCout(n) ( ((Bits32_TypeDef *)(&(GPIOC->PDOR)))->bit##n ) 60 #define PDout(n) ( ((Bits32_TypeDef *)(&(GPIOD->PDOR)))->bit##n ) 61 #define PEout(n) ( ((Bits32_TypeDef *)(&(GPIOE->PDOR)))->bit##n ) 62 #define PFout(n) ( ((Bits32_TypeDef *)(&(GPIOF->PDOR)))->bit##n ) 63 64 #define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ 65 #define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ 66 #define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ 67 #define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ 68 #define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ 69 #define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ 70 #define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ 71 #define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ 72 #define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ 73 #define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ 74 #define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ 75 #define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ 76 #define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ 77 #define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ 78 #define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ 79 #define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ 80 #define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ 81 82 83 #endif
接下来定义延时函数,由于一个指令占四个时钟周期,而单片机的时钟频率是48MHz,所以我们有以下的延时代码:
1 #ifndef __DELAY_H 2 #define __DELAY_H 3 4 #include "stdint.h" 5 6 void delay_1ms(void); 7 void delay_1us(void); 8 void delay_ms(uint16_t ms); 9 void delay_us(uint16_t us); 10 11 #endif
1 #include "delay.h" 2 3 4 5 void delay_1us(void){ 6 7 int i=12; 8 while(i--); 9 } 10 11 void delay_us(uint16_t us){ 12 13 for(int i=0;i<us;++i){ 14 delay_1us(); 15 } 16 17 } 18 19 void delay_1ms(void){ 20 21 delay_us(1000); 22 23 } 24 25 void delay_ms(uint16_t ms){ 26 27 for(int i=0;i<ms;++i){ 28 delay_1ms(); 29 } 30 }
然后根据程序的流程,定义led函数和main主函数:
1 #ifndef __LED_H 2 #define __LED_H 3 #include "sys.h" 4 5 #define LED1 (PAout(1)) 6 #define LED2 (PAout(2)) 7 #define SWITCH (PAin(5)) 8 9 #define led_pos_1 (1) 10 #define led_pos_2 (2) 11 #define switch_pos_1 (5) 12 void LedInit(void); 13 14 15 #endif
1 #include "led.h" 2 3 void LedInit(void){ 4 5 SIM->SCGC5|=(1<<9); //OPEN CLOCK GPIOA 6 7 PORTA->PCR[led_pos_1] |=(1<<8); //MAKE PINS GPIO 8 PORTA->PCR[led_pos_2] |=(1<<8); //MAKE PINS GPIO 9 PORTA->PCR[switch_pos_1] |=(1<<8); //MAKE PINS GPIO 10 11 PTA->PDDR|=(1<<1)|(1<<2); //LED PINS IS OUTPUT 12 PTA->PDDR &=~(1<<5); //SW PINS IS INPUT 13 14 LED1=1; //LED1 IS OFF 15 LED2=0; //LED2 IS ON 16 }
1 #include "sys.h" 2 #include "delay.h" 3 #include "led.h" 4 5 6 int main(void) 7 { 8 LedInit(); 9 while(1) 10 { 11 if(SWITCH==0){ 12 LED1=0; //LED1 IS OFF 13 LED2=1; //LED2 IS ON 14 15 }else{ 16 17 LED1=1; //LED1 IS OFF 18 LED2=0; //LED2 IS ON 19 } 20 } 21 22 }