我是从学单片机才开始接触嵌入式,所以我一直都感觉还是从硬件在到上面的驱动,这样的而学习流程让我更加容易懂的一些,但是上班了发现公司没让我那样,一开始就给我一大批的代码,让我一段时间很消沉,不过现在也差不多熬过来了,但是回首这段时间,发现自己阅读那些令人费解的代码的能力有所提升把,但是现在自己还是打算从硬件到驱动好好的学习个彻底,上面启动代码没什么好说的,接着程序已经跳转到了c语言的入口Main函数这里了,接下来就会觉得很熟悉了(我也还是建议和我一样菜鸟的先不看那段启动代码,曾经在学校哪个启动代码让我费了很多的时间,想起来真的好不值,把其他的都会了,在回头看也就差不多了),好了开始正文了。
—————————————————————————————————————————————
硬件平台:TQ2440 (S3C2440A)
开发环境:ADS1.2
时 间:2010-12-12
—————————————————————————————————————————————
1:硬件电路:

可以看见是GPB5-8对应的LED1-4;所以相应的只要对相应的IO口进行操作就没有问题了;
2:2440的IO的配置

这里是2440的IO口的引脚,需要注意的是,除了GPA之外,其他的都有INPUT和OUTPUT功能,这一点我们后面配置自己相关函数的时候会看到。
所以我们只需要把GPB配置为IO口就好了。

所以如图我们需要的是输出,故,GPBCON=(0x01<<10);这样就把GPB5配置wie输出了,同理配置其他的管脚。
3: 相关代码的实现
1: #define GPBCON (*(volatile unsigned long *)0x56000010)
2: #define GPBDAT (*(volatile unsigned long *)0x56000014)
3: #define GPB5_out (1<<(5*2))
4: #define GPB6_out (1<<(6*2))
5: #define GPB7_out (1<<(7*2))
6: #define GPB8_out (1<<(8*2))
7: void wait(unsigned long dly)
8: {
9: for(; dly > 0; dly--);
10: }
11: /*这个LED_Test1函数是直接copy韦东山的那本书里的代码,感觉这个简单就不用写,之所以写这个是为了验证后面自己的写法*/
12: void LED_Test1(void)
13: {
14: unsigned long i = 0;
15: GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;
16:
17: GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4
18: if(++i == 16)
19: i = 0;
20: wait(30000);
21: }
22: void Main(void)
23: {
24:
25: while(1)
26: {
27: LED_Test1();
28: LED_Test();
29: }
30: }
我因为在公司做驱动,感觉他门里面的代码的写法很不错,所以自己也打算改变一下写法,直接实现一个函数,对那组IO口的那个管脚配置和操作。
1: #define IO_CON_BASE 0x56000000
2: #define IO_DAT_BASE 0x56000004
3: void GPIO_CONF_SET(unsigned int group,unsigned int index,unsigned int type)
4: {
5: unsigned int *p_add=NULL;
6: unsigned int addr = IO_CON_BASE + (group*0x10);
7: unsigned int io_reg = type<<(index<<1);
8: p_add=(unsigned int *)(addr);
9: *p_add=*p_add&~(0x3<<(index<<1));
10: *p_add=*p_add|io_reg;
11: }
12: void GPIO_OUT_PUT(unsigned int group,unsigned int index,unsigned int outval)
13: {
14: unsigned int *p_add=NULL;
15: unsigned int addr = IO_DAT_BASE + (group*0x10);
16: unsigned int io_reg = outval< 18: *p_add=*p_add&~(0x1< 20: } 21: void wait(unsigned long dly) 22: { 23: for(; dly > 0; dly--); 24: } 25: void LED_Test(void) 26: { 27: //-------------5.6.7.8 conf OutPut 28: GPIO_CONF_SET(1,5,1); 29: GPIO_CONF_SET(1,6,1); 30: GPIO_CONF_SET(1,7,1); 31: GPIO_CONF_SET(1,8,1); 32: //-------------LED flash 33: GPIO_OUT_PUT(1,5,1); 34: wait(30000); 35: GPIO_OUT_PUT(1,6,1); 36: wait(30000); 37: GPIO_OUT_PUT(1,7,1); 38: wait(30000); 39: GPIO_OUT_PUT(1,8,1); 40: wait(30000); 41: GPIO_OUT_PUT(1,5,0); 42: wait(30000); 43: GPIO_OUT_PUT(1,6,0); 44: wait(30000); 45: GPIO_OUT_PUT(1,7,0); 46: wait(30000); 47: GPIO_OUT_PUT(1,8,0); 48: wait(30000); 49: } 上面我把他改为p_add=*(unsigned int *)(addr);然后 p_add=p_add&~(0x3<<(index<<1));这样程序却跑不起来,不知道为什么,希望高手能解答一下。 觉得这样还不是很完美所以想把他直接定义为宏定义,这样直接拷贝到其他的文件开头就能用了。免得还得去声明和定义函数; 改造之后如下: 1: #define IO_CON_BASE 0x56000000 2: #define IO_DAT_BASE 0x56000004 3: /* 4: GPIO_CFG_SET说明: group--表示是那组IO(注意没有GPA) 5: index--表示这组中的那个引脚 6: type --表示是配置为输入还是输出等其他功能 7: */ 8: #define GPIO_CFG_SET(group,index,type) do{ 9: (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))&=~(0x3< 12: 13: /* 14: GPIO_DAT_SET说明: group--表示是那组IO(注意没有GPA) 15: index--表示这组中的那个引脚 16: val --表示对此引脚写入的数据 17: */ 18: #define GPIO_DAT_SET(group,index,val) do{ 19: (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))&=~(0x1< 22: /* 23: 因为GPA的控制寄存器,每个引脚只只占用一位,所以为了能统一这里,就没有把 24: GPA加进来,而后面的GPB-GPJ的控制寄存器每个引脚对应2位 25: */ 26: enum{GPB=1,GPC,GPD,GPE,GPF,GPG,GPH,GPI,GPJ}; 27: /* 28: 从GPB开始由于用两位表示此引脚的功能所以有四种可能 29: 0代表INPUT,1代表OUTPUT,2代表第三功能,3代表第四功能 30: */ 31: enum{INPUT=0,OUTPUT,THI_FUNC,FOR_FUNC}; 32: /* 33: 定义高低电平 34: */ 35: enum{LOW=0,HIG}; 36: void wait(unsigned long dly) 37: { 38: for(; dly > 0; dly--); 39: } 40: void LED_Test(void) 41: { 42: //-------------5.6.7.8 conf OutPut 43: GPIO_CFG_SET(GPB,5,OUTPUT); 44: GPIO_CFG_SET(GPB,6,OUTPUT); 45: GPIO_CFG_SET(GPB,7,OUTPUT); 46: GPIO_CFG_SET(GPB,8,OUTPUT); 47: //-------------LED flash 48: GPIO_DAT_SET(GPB,5,HIG); 49: wait(30000); 50: GPIO_DAT_SET(GPB,6,HIG); 51: wait(30000); 52: GPIO_DAT_SET(GPB,7,HIG); 53: wait(30000); 54: GPIO_DAT_SET(GPB,8,HIG); 55: wait(30000); 56: GPIO_DAT_SET(GPB,5,LOW); 57: wait(30000); 58: GPIO_DAT_SET(GPB,6,LOW); 59: wait(30000); 60: GPIO_DAT_SET(GPB,7,LOW); 61: wait(30000); 62: GPIO_DAT_SET(GPB,8,LOW); 63: wait(30000); 64: }
上一篇:wince下sources\sources.cmn\Makefile.def的相关作用
下一篇:TQQ2440第一节:启动代码
推荐阅读最新更新时间:2026-03-21 10:35
- LM2904DMR2G 函数发生器运算放大器的典型应用
- DEMO9RS08KA2: DEMO9RS08KA2 Demonstration Board
- MCP73871EV,MCP73871 锂离子电池充电器评估板
- STEVAL-IHM039V1,采用 STM32F415 微控制器的双电机控制演示板
- LTC1606CG 演示板、16 位、250ksps ADC
- RT8086B 3.5A、1.2MHz、同步降压转换器的典型应用
- TS4999EIJT 典型应用 免滤波器立体声 2.8 W D 类音频功率放大器,可选择 3D 音效
- LTM4615,采用 15mm-15mm 封装的完整双路和三路输出负载点模块稳压器
- LTC2415-1IGN 24 位 ADC 的典型应用电路使用电阻器阵列在励磁放大器中提供精确匹配
- 使用 Analog Devices 的 LTC1450LIN 的参考设计

51单片机8按键流水灯程序
C51单片机高效入门_第2版
非常经典的关于LLC的杨波博士论文
1CIS223-04TG3M






京公网安备 11010802033920号