LED闪烁

和当时学习单片机一样,程序跑到c入口了,第一件事情就是点亮LED了,我对LED也做了相应的调整,这几天老婆用着电脑,不还意思抢过来,所以先把代码写好在这里。

#define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPB5_out (1<<(5*2)) #define GPB6_out (1<<(6*2)) #define GPB7_out (1<<(7*2)) #define GPB8_out (1<<(8*2)) void wait(unsigned long dly) { for(; dly > 0; dly--); } /*这个LED_Test1函数是直接copy韦东山的那本书里的代码,感觉这个简单就不用写,之所以写这个是为了验证后面自己的写法*/ void LED_Test1(void) { unsigned long i = 0; GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4 if(++i == 16) i = 0; wait(30000); } void Main(void) { while(1) { LED_Test1(); LED_Test(); } }

我因为在公司做驱动,感觉他门里面的代码的写法很不错,所以自己也打算改变一下写法,直接实现一个函数,对那组IO口的那个管脚配置和操作。

#define IO_CON_BASE 0x56000000 #define IO_DAT_BASE 0x56000004 void GPIO_CONF_SET(unsigned int group,unsigned int index,unsigned int type) { unsigned int *p_add=NULL; unsigned int addr = IO_CON_BASE + (group*0x10); unsigned int io_reg = type<<(index<<1); p_add=(unsigned int *)(addr); *p_add=*p_add&~(0x3<<(index<<1)); *p_add=*p_add|io_reg; } void GPIO_OUT_PUT(unsigned int group,unsigned int index,unsigned int outval) { unsigned int *p_add=NULL; unsigned int addr = IO_DAT_BASE + (group*0x10); unsigned int io_reg = outval<<index; p_add=(volatile unsigned int *)(addr); *p_add=*p_add&~(0x1<<index); *p_add=*p_add|io_reg; } void wait(unsigned long dly) { for(; dly > 0; dly--); } void LED_Test(void) { //-------------5.6.7.8 conf OutPut GPIO_CONF_SET(1,5,1); GPIO_CONF_SET(1,6,1); GPIO_CONF_SET(1,7,1); GPIO_CONF_SET(1,8,1); //-------------LED flash GPIO_OUT_PUT(1,5,1); wait(30000); GPIO_OUT_PUT(1,6,1); wait(30000); GPIO_OUT_PUT(1,7,1); wait(30000); GPIO_OUT_PUT(1,8,1); wait(30000); GPIO_OUT_PUT(1,5,0); wait(30000); GPIO_OUT_PUT(1,6,0); wait(30000); GPIO_OUT_PUT(1,7,0); wait(30000); GPIO_OUT_PUT(1,8,0); wait(30000); }

上面我把他改为p_add=*(unsigned int *)(addr);然后 p_add=p_add&~(0x3<<(index<<1));这样程序却跑不起来,不知道为什么,希望高手能解答一下。

 

觉得这样还不是很完美所以想把他直接定义为宏定义,这样直接拷贝到其他的文件开头就能用了。免得还得去声明和定义函数;

改造之后如下:

 

#define IO_CON_BASE 0x56000000 #define IO_DAT_BASE 0x56000004 /* GPIO_CFG_SET说明: group--表示是那组IO(注意没有GPA) index--表示这组中的那个引脚 type --表示是配置为输入还是输出等其他功能 */ #define GPIO_CFG_SET(group,index,type) do{/ (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))&=~(0x3<<index<<1);/ (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))|=(type<<index<<1);/ }while(0) /* GPIO_DAT_SET说明: group--表示是那组IO(注意没有GPA) index--表示这组中的那个引脚 val --表示对此引脚写入的数据 */ #define GPIO_DAT_SET(group,index,val) do{/ (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))&=~(0x1<<index);/ (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))|=(val<<index);/ }while(0) /* 因为GPA的控制寄存器,每个引脚只只占用一位,所以为了能统一这里,就没有把 GPA加进来,而后面的GPB-GPJ的控制寄存器每个引脚对应2位 */ enum{GPB=1,GPC,GPD,GPE,GPF,GPG,GPH,GPI,GPJ}; /* 从GPB开始由于用两位表示此引脚的功能所以有四种可能 0代表INPUT,1代表OUTPUT,2代表第三功能,3代表第四功能 */ enum{INPUT=0,OUTPUT,THI_FUNC,FOR_FUNC}; /* 定义高低电平 */ enum{LOW=0,HIG}; void wait(unsigned long dly) { for(; dly > 0; dly--); } void LED_Test(void) { //-------------5.6.7.8 conf OutPut GPIO_CFG_SET(GPB,5,OUTPUT); GPIO_CFG_SET(GPB,6,OUTPUT); GPIO_CFG_SET(GPB,7,OUTPUT); GPIO_CFG_SET(GPB,8,OUTPUT); //-------------LED flash GPIO_DAT_SET(GPB,5,HIG); wait(30000); GPIO_DAT_SET(GPB,6,HIG); wait(30000); GPIO_DAT_SET(GPB,7,HIG); wait(30000); GPIO_DAT_SET(GPB,8,HIG); wait(30000); GPIO_DAT_SET(GPB,5,LOW); wait(30000); GPIO_DAT_SET(GPB,6,LOW); wait(30000); GPIO_DAT_SET(GPB,7,LOW); wait(30000); GPIO_DAT_SET(GPB,8,LOW); wait(30000); }

你可能感兴趣的:(LED闪烁)