裸机程序开发之LED程序

以下代码段实现了一个简单的LED显示程序,程序比较简单,共53行。

1       #include "def.h"

2       #include "option.h"

3       #include "2440addr.h"

4       #include "2440lib.h"

5       #include "2440slib.h"

6

7       void dely(U32 tt)

8       {

9          U32 i;

10        for(;tt>0;tt--)

11        {

12          for(i=0;i<10000;i++){}

13        }

14     }

15

16     int Main(int argc, char **argv)

17     {

18              int i;

19              U8 key;

20              U32 mpll_val=0;

21              int data;

22

23              mpll_val = (92<<12)|(1<<4)|(1);

24

25              //init FCLK=400M, so change MPLL first

26              ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

27              ChangeClockDivider(key, 12);

28

29              //ChangeClockDivider(1,1);    // 1:2:4    FCLK:HCLK:PCLK

30         // rCLKDIVN=0x4;    //  1:4:4

31         //ChangeMPllValue(82,2,1);     //FCLK=135.0Mhz

32              //ChangeMPllValue(82,1,1);     //FCLK=180.0Mhz

33         //ChangeMPllValue(161,3,1);    //FCLK=202.8Mhz

34           //ChangeMPllValue(117,1,1);    //FCLK=250.0Mhz

35         //ChangeMPllValue(122,1,1);    //FCLK=260.0Mhz

36         //ChangeMPllValue(125,1,1);    //FCLK=266.0Mhz

37         //ChangeMPllValue(127,1,1);    //FCLK=270.0Mhz

38

39         MMU_DisableICache();

40         MMU_DisableDCache();

41

42         rGPBCON = 0x155555;

43

44          data = 0x06;

45          while(1)

46          {

47                   rGPBDAT = (data<<5);

48                   dely(120);

49                   data =~data;

50              }

51

52   return 0;

53     }

以下将对代码进行详细说明

Line26 ChangeMPllValue的函数原型为:

void ChangeMPllValue(int mdiv,int pdiv,int sdiv)

{

rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;

}

图3-1.时钟信号生成器模块图

MPLLCON为PLL控制寄存器。PLL全称为PHASE LOCKED LOOP。在S3C2440A中PLL分为两种:MPLL和UPLL。MPLL进一步处理可以拆分成多个时钟信号(FCLK,HCLK,PCLK),可以给ARM920T核、外设提供时钟信号,UPLL为USB专用。

FCLK用于ARM920T核心,正常情况下FCLK=MPLL。

HCLK用于AHB总线,用于ARM920T核心,内存控制器,内部控制器,LCD控制器,DMA和USB主机模块。

PCLK用于APS总线,使用到的外设有看门狗,IIS总线,I2C总线,PWM定时器,MMC接口,ADC,UART,GPIO,RTC和SPI。

图3-2.上电复位流程(外部时钟信号源为晶振)

在图3-2中可看出时钟信号在系统上电复位过程中的行为。上电后的几毫秒内晶振开始起振。在OSC(XTIpll)时钟稳定后释放nRESET,PLL开始根据默认的PLL配置进行操作。但是,众所周知,PLL上电复位后会不稳定,因此在软件重新配置PLLCON之前,将Fin直接发送到FCLK而不是Mpll(PLL输出)。 即使用户不想在复位后更改PLLCON寄存器的默认值,用户也应通过软件将相同的值写入PLLCON寄存器。只有在软件为PLL配置了新的频率信号值之后,PLL才会执行锁定操作。然后使用新的频率重新启动。锁定时间结束后,可以立即将FCLK配置为PLL输出(Mpll)。

图3-3. PLL (Phase-Locked Loop)模块图

时钟发生器内的MPLL控制电路,可将输出信号与参考输入信号(频率和相位)进行同步。在本应用中,它包括以下基本模块,如3-3图所示:电压受控振荡器(VCO)产生与输入直流电压成比例的输出频率,分频器P进行分频动作,将输入频率(Fin)除以p,分频器M将VCO输出频率除以m,输入到相位频率检测器(PFD),分频器S将VCO输出频率除以“s”,即Mpll(输出MPLL模块的频率),相位差检测器,电荷泵和环路滤波器。输出时钟频率Mpll通过以下公式与参考输入时钟频率Fin相关:

Mpll = (2*m * Fin) / (p * 2^s)

m = M (除数M的值)+ 8, p = P (除数P的值) + 2

时钟发生器内的UPLL在各个方面都与MPLL相似。

rMPLLCON展开宏后可知道就是MPLLCON寄存器。

将代码中的值带入上面两个公式,M=92,P=1,S=1,开发板使用的晶振是12MHz,Fin=12MHz:

m=M+8=92+8=100;

p=P+2=1+2=3;

Mpll= (2*m * Fin) / (p * 2^s)=(2*100*12)/((1+2)*2^1)=400MHz。刚好和cpu的主频一致。

接来下我们看代码Line27, ChangeClockDivider(0, 12)对应的原型为:

void ChangeClockDivider(int hdivn_val,int pdivn_val)

{

int hdivn=2, pdivn=0;

// hdivn_val (FCLK:HCLK)ratio hdivn

// 11           1:1       (0)

// 12           1:2       (1)

// 13           1:3       (3)

// 14           1:4       (2)

// pdivn_val (HCLK:PCLK)ratio pdivn

// 11           1:1       (0)

// 12           1:2       (1)

switch(hdivn_val) {

case 11: hdivn=0; break;

case 12: hdivn=1; break;

case 13:

case 16: hdivn=3; break;

case 14:

case 18: hdivn=2; break;

}

switch(pdivn_val) {

case 11: pdivn=0; break;

case 12: pdivn=1; break;

}

rCLKDIVN = (hdivn<<1) | pdivn;

//Uart_Printf("rCLKDIVN:%x]\n", rCLKDIVN);

switch(hdivn_val) {

case 16:            // when 1, HCLK=FCLK/6.

rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8);

break;

case 18: // when 1, HCLK=FCLK/8.

rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9);

break;

}

//Uart_Printf("rCAMDIVN:%x]\n", rCAMDIVN);

if(hdivn!=0)

MMU_SetAsyncBusMode();

else

MMU_SetFastBusMode();

}

上述代码中,经简单计算可知hdivn=2, pdivn=1。

rCLKDIVN对应CLKDIVN(CLOCK DIVIDER CONTROL)寄存器

rCAMDIVN对应CAMDIVN(CAMERA CLOCK DIVIDER)寄存器

根据上表可知,PCLK=HCLK/2, HCLK=FCLK/4。上面代码MPLLCON寄存器设置后,PCLK=MPLL=400MHz, HCLK=100MHz, PCLK=50MHz

ChangeClockDivider函数最后调用了MMU_SetAsyncBusMode,其依据是S3C2440芯片的官方手册要求:

如果HDIVN不为0,则必须将CPU总线模式从快速总线模式更改为异步模式总线模式,请按照以下指令进行操作(S3C2440不支持同步总线模式)。

MMU_SetAsyncBusMode

  mrc  p15,0,r0,c1,c0,0

  orr  r0,r0,#R1_nF:OR:R1_iA

  mcr  p15,0,r0,c1,c0,0

接着我们回到Main函数。MMU_DisableICache和MMU_DisableDCache是对MMU的操作,此处我们忽略,后续章节再做解释。

rGPBCON = 0x155555; rGPBDAT = (data<<5);

rGPBCON对应GPBCON寄存器,用于控制端口B的IO引脚。0x155555对应的2进制为0101010101010101010101,将所有端口B的引脚设置为输出模式。rGPBDAT对应GPBDAT寄存器,是端口B的IO数据寄存器。

LED对应的原理图,LED1~4对应的引脚分别为GPB5,GPB6,GPB7,GPB8。

   

Main函数最后是一个while死循环,不断地改变GPBDAT数据,从而改变LED的亮灭。Dely为延时函数,作用是让人眼能够观察到LED亮灭的变化过程。

至此,程序结束。

S3C2440驱动开发(二)相关推荐

  1. 基于MTD的NAND驱动开发(二)

    基于MTD的NAND驱动开发(二) 基于MTD的NAND驱动开发(三) http://blog.csdn.net/leibniz_zsu/article/details/4977853 http:// ...

  2. Window XP驱动开发(二) 环境搭建(VS2008+WDK+DDKWzard)及示例源码分析

    郁闷,做了WCE嵌入式驱动这么久还没热身够,又被调到做window xp下的驱动开发.没办法.只能受令了. 现在就开始自己的学习之旅吧. 转载请标明是引用于 http://blog.csdn.net/ ...

  3. i.MX 6ULL 驱动开发 二十九:向 Linux 内核中添加自己编写驱动

    一.概述 Linux 内核编译流程如下: 1.配置 Linux 内核. 2.编译 Linux 内核. 说明:进入 Linux 内核源码,使用 make help 参看相关配置. 二.make menu ...

  4. Window XP驱动开发(二十一) 过滤驱动程序

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖 参考书籍<<Windows驱动开发技术详解>> 过滤驱动程序的开发十分 ...

  5. i.MX 6ULL 驱动开发 二十七:块设备

    参考:[块设备]通用块层 struct bio 详解 | zzm (aliez22.github.io) 一.Linux 中块设备驱动框架 二.块设备基本概念 1.扇区的概念来自硬件,扇区是硬件最小操 ...

  6. Linux SD卡驱动开发(二) —— SD 卡驱动分析HOST篇

    回顾一下前面的知识,MMC 子系统范围三个部分: HOST 部分是针对不同主机的驱动程序,这一部是驱动程序工程师需要根据自己的特点平台来完成的. CORE 部分: 这是整个MMC 的核心存,这部分完成 ...

  7. Windows驱动开发二:Windbg源码调试

    在windbg中源码调试,编译好测试的驱动文件到指定路径打开 windbg-> Open source file 打开 在原代码文件同级目录中有编译打符号文件,Settings->Defa ...

  8. S3C2440驱动开发(四)

    裸机程序开发之蜂鸣器程序 程序实现了控制蜂鸣器输入pwm频率和开关功能.输入数字1开启蜂鸣器,输入数字0关闭蜂鸣器,输入字符+增加蜂鸣器输入pwm频率,输入字符-减少蜂鸣器输入pwm频率.代码如下: ...

  9. S3C2440驱动开发(七)

    Bootloader Bootloader 以其本身的含义来讲就是下载和启动系统,它类似于 PC 中的 BIOS,大部 分芯片厂商所提供的嵌入式系统都提供有这样的程序,而且都比较成熟,大可不必自行编写 ...

最新文章

  1. 2.2元组介绍+字符串操作
  2. 前百度首席科学家吴恩达携手富士康,要用人工智能升级制造业
  3. Ajax方式上传文件报错Uncaught TypeError: Illegal invocation
  4. python3 中递归的最大次数
  5. c++ dll继续使用然后强制删除dll文件_Windows 10系统安全风险,近300个系统执行文件容易遭受劫持攻击...
  6. 【斗医】【11】Web应用开发20天
  7. SharePoint 2013:解决添加域名后每次都需要登录的问题
  8. 信息学奥赛C++语言:for_求和2
  9. powershell自动化操作AD域、Exchange邮箱系列(9)—导出AD内所有计算机到数据库
  10. 在Android中运用RxJava
  11. [置顶] 从工作流引擎设计来看人精神活动的一些问题
  12. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_08-新增页面-前端-Api调用...
  13. Java中上转型对象数组
  14. 分布式本质论:高吞吐、高可用、可扩展 (1)
  15. 基于JSP和SQL的CD销售管理系统
  16. python求职意向怎么写_软件测试求职意向怎么写(附样本)最新精美简历模板
  17. 都2022年了,这11个Java开发工具你还不知道?
  18. 【WPS】折线图数据点上添加标记(三角形、正方形、菱形等)
  19. python is not defined
  20. 树莓派 无线网卡服务器,树莓派(Raspberry Pi)USB无线网卡配置方法

热门文章

  1. 苹果8没有信号显示无服务器,苹果8p没信号无服务怎么回事
  2. 智慧海洋学习 task 1
  3. 背景图延迟加载(lazyload)技术
  4. cocos2d-x 使用tmx地图总结
  5. 哈工大c语言指针实验题,C语言程序设计_哈工大(2):指针与数组.pdf
  6. 向后量子密码学迁移!美国NIST公布12家合作伙伴
  7. C# RichTextBox 滚动条 滚动到最后一行
  8. 2022-2028全球FAKRA射频连接器行业调研及趋势分析报告
  9. 万邦阿里巴巴中国站获得1688商品类目 API 返回值说明
  10. 摸鱼有理:大脑一思考就在积累毒素,必须休息才能清除|Cell子刊