基于ARM-contexA9蜂鸣器驱动开发

2023-11-16

上次,我们写了一个LED的驱动程序,这一节,我们只需稍微改动一下就可以实现蜂鸣器的驱动,让我们来看看吧。

     还是跟之前一样,先找电路图,找到电路板上对应的引脚和相关联的寄存器。

     1、看电路图

     (1)蜂鸣器接口位于电路板的底板,看电路图可知道是高电平有效。

 

   (2)相对应的找到核心板的接口。由此可知,我们的蜂鸣器是GPD0_0

 

接下来找数据手册,嵌入式物联网等系统学习企鹅意义气呜呜吧久零就易,找到对应的寄存器,然后配置它就可以了。

  2、查数据手册,找到相关的寄存器,并配置

(1)找到GPD0CON,地址是0x114000A0,我们需要配置GPD0CON(0)为输出状态。也就是写0x1这个值到这个寄存器。

 

 

(2)找到GPD0DAT这个寄存器,用于配置蜂鸣器的高低电平,物理地址是0x114000A4,刚好与上一个差4个字节的偏移

我们只要对这个寄存器写1和写0,那么蜂鸣器就可以叫起来了,哈哈。是不是很简单?

 

3、开始写驱动程序。

 

[plain] view plain copy print?

1. 

#include <linux/init.h>  

2. 

3. 

#include <linux/module.h>  

4. 

5. 

#include <linux/kernel.h>  

6. 

7. 

#include <linux/fs.h>  

8. 

9. 

#include <linux/io.h>  

10. 

11. 

#include <asm/uaccess.h>  

12. 

13. 

#include <asm/irq.h>  

14. 

15. 

#include <asm/io.h>  

16. 

17. 

#define DEV_NAME    "test-dev"  

18. 

19. 

//定义蜂鸣器配置IO的地址   

20. 

21. 

#define GPD0CON  0x114000A0  

22. 

23. 

volatile unsigned long *bell_config = NULL ;   

24. 

25. 

volatile unsigned long *bell_dat = NULL ;   

26. 

27. 

int bell_open(struct inode *inode, struct file *filp)  

28. 

29. 

{  

30. 

31. 

    printk("bell_open\n");  

32. 

33. 

    //清寄存器   

34. 

35. 

    *bell_config &= ~(0xf);  

36. 

37. 

    //设置io为输出   

38. 

39. 

    *bell_config |= (0x1);  

40. 

41. 

    return 0;  

42. 

43. 

}  

44. 

45. 

  

46. 

47. 

int bell_close(struct inode *inode, struct file *filp)  

48. 

49. 

{  

50. 

51. 

    printk("bell_close\n");  

52. 

53. 

    //关闭蜂鸣器   

54. 

55. 

    *bell_dat &= ~0x1 ;  

56. 

57. 

    return 0;  

58. 

59. 

}  

60. 

61. 

  

62. 

63. 

long bell_ioctl(struct file *filp, unsigned int request, unsigned long arg)  

64. 

65. 

{  

66. 

67. 

    //控制蜂鸣器的状态   

68. 

69. 

    switch(request)  

70. 

71. 

    {  

72. 

73. 

        case 0:  

74. 

75. 

            printk(KERN_EMERG"bell on\n");  

76. 

77. 

            *bell_dat |= 0x1 ;  

78. 

79. 

            break;  

80. 

81. 

  

82. 

83. 

        case 1:  

84. 

85. 

            printk(KERN_EMERG"bell off\n");  

86. 

87. 

            *bell_dat &=~0x1 ;  

88. 

89. 

            break;  

90. 

91. 

    }  

92. 

93. 

    return 0 ;  

94. 

95. 

}  

96. 

97. 

  

98. 

99. 

struct file_operations fops = {  

100. 

101. 

    .owner = THIS_MODULE ,  

102. 

103. 

    .open = bell_open,  

104. 

105. 

    .release = bell_close,  

106. 

107. 

    .unlocked_ioctl = bell_ioctl,  

108. 

109. 

};  

110. 

111. 

  

112. 

113. 

int major ;  

114. 

115. 

int test_init(void)  

116. 

117. 

{  

118. 

119. 

    printk("bell_init\n");  

120. 

121. 

    //注册设备   

122. 

123. 

    major = register_chrdev(major, DEV_NAME, &fops);  

124. 

125. 

    //映射IO   

126. 

127. 

    bell_config = (volatile unsigned long *)ioremap(GPD0CON , 16);  

128. 

129. 

    //加4个字节偏移到GP0DAT顺便映射该物理地址   

130. 

131. 

    bell_dat = bell_config + 1 ;      

132. 

133. 

    return 0;  

134. 

135. 

}  

136. 

137. 

  

138. 

139. 

void test_exit(void)  

140. 

141. 

{  

142. 

143. 

    printk("bell_exit\n");  

144. 

145. 

    //解除注册   

146. 

147. 

    unregister_chrdev(major, DEV_NAME);  

148. 

149. 

    //取消映射   

150. 

151. 

    iounmap(bell_config);  

152. 

153. 

}  

154. 

155. 

  

156. 

157. 

module_init(test_init);  

158. 

159. 

module_exit(test_exit);  

160. 

161. 

  

162. 

163. 

MODULE_LICENSE("GPL");  

164. 

165. 

MODULE_AUTHOR("Y.X.YANG");  

166. 

167. 

MODULE_VERSION("2016.1.16");</span>  

168. 

4、写测试程序

[plain] view plain copy print?

1. 

#include <stdio.h>  

2. 

3. 

#include <sys/types.h>  

4. 

5. 

#include <sys/stat.h>  

6. 

7. 

#include <fcntl.h>  

8. 

9. 

  

10. 

11. 

int main(int argc, char **argv)  

12. 

13. 

{  

14. 

15. 

    int fd;  

16. 

17. 

    //打开设备   

18. 

19. 

    fd = open("/dev/test-dev",O_RDWR) ;  

20. 

21. 

    if(-1 == fd)  

22. 

23. 

    {  

24. 

25. 

        printf("open fair!\n");  

26. 

27. 

        return -1 ;  

28. 

29. 

    }  

30. 

31. 

    while(1){  

32. 

33. 

        //打开蜂鸣器   

34. 

35. 

        ioctl(fd,1);  

36. 

37. 

        sleep(1);  

38. 

39. 

        //关闭蜂鸣器   

40. 

41. 

        ioctl(fd,0);  

42. 

43. 

        sleep(1);  

44. 

45. 

    }  

46. 

47. 

    return 0;  

48. 

49. 

}</span>  

50. 

5、编写makefile

[plain] view plain copy print?

1. 

obj-m   += bell.o  

2. 

3. 

  

4. 

5. 

ROOTFS = /disk/A9/filesystem  

6. 

7. 

KERNEL = /disk/A9/linux-3.5/  

8. 

9. 

all:  

10. 

11. 

    make -C $(KERNEL) M=`pwd` modules  

12. 

13. 

  

14. 

15. 

clean:  

16. 

17. 

    make -C $(KERNEL) M=`pwd` clean  

18. 

19. 

    rm -rf my_bell  

20. 

21. 

  

22. 

23. 

install:  

24. 

25. 

    make -C $(KERNEL) M=`pwd` modules_install INSTALL_MOD_PATH=$(ROOTFS)  

26. 

27. 

  

28. 

29. 

my_bell:  

30. 

31. 

    arm-linux-gcc my_bell.c -o my_bell  

32. 

33. 

</span>  

34. 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于ARM-contexA9蜂鸣器驱动开发 的相关文章

随机推荐

  • 各类排序算法的比较总结

    排序算法是最基本最常用的算法 不同的排序算法在不同的场景或应用中会有不同的表现 我们需要对各种排序算法熟练才能将它们应用到实际当中 才能更好地发挥它们的优势 今天 来总结下各种排序算法 下面这个表格总结了各种排序算法的复杂度与稳定性 各种排
  • osgEarth的Rex引擎原理分析(一二三)osgEarth的缓存及其结构

    目标 十七 中问题43 1 缓存分两类 1 文件缓存 osgDB FileCache FileSystemCache 位于osgEarthDrivers cache filesystem FileSystemCache osgDB File
  • 51单片机——中断

    中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置 中断功能的存在 很大程度上提高了单片机处理外部或内部事件的能力 老版51单片机内部共有5个中断源 中断是处理器一种工作状态的描述 我们把引起中断的原因 或者能够发出中断请求信号的
  • 11-----curl命令行代替post请求带baby

    1 curl命令行代替post请求带baby 使用curl命令行代替postman在linux是非常方便的 curl H Content Type application json X POST data camera uid 123 45
  • 半虚拟化和全虚拟化的区别

    全虚拟化 Full virtualization 也称为原始虚拟化技术 是另一种虚拟化方法 该模型使用虚拟机协调客户 操作系统和原始硬件 见图2 这里 协调 是一个关键词 因为VMM在客户操作系统和裸硬件之间用于工作协调 一些受保护的指令必
  • 【nginx】静态文件处理:root和alias的区别以及try_files用法

    对于静态文件 nginx支持配置文件路径 关键字为root和alias 简介 配置系统 data www目录下有如下文件 data www file a txt b txt backup c txt d txt nginx 配置中 loca
  • 面向对象设计基本原则(举例说明)

    单一职责原则 SRP 就一个类而言 应该仅有一个引起它变化的原因 如果一个类承担的职责过多 就等于把这些职责耦合在一起 一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力 这种耦合会导致脆弱的设计 当变化发生时 设计会遭受到意想不到的
  • 基于Qt的轻量级的Ribbon控件(Office样式UI)

    基于Qt的轻量级的Ribbon控件 Office样式UI 界面截图 它支持4种目前常见的ribbon样式在线切换 包括2种office模式 office模式是最常见的ribbon模式了 就是我们经常看到的word模式 office模式的ta
  • Rust vs Go:两者结合效果更好!

    最近看到一个程序员工资排行的图 435501份数据 调查显示 Rust 是最赚钱的 随着 Rust 的发展和它表现出的很多优点 越来越多 Gopher 开始关注 Rust 首先 Rust 没有历史包袱 集表达力 高性能 内存安全于一身 可以
  • 2022年11月7日--11月13日(ue4 tf1视频教程+cesium for ue源码CesiumUtility抄写,本周10小时,合计1737小时,剩余8263小时)

    目前 mysql 7 1 tf1 3 3 oss 12 1 蓝图反射 1 7 moba 1 5 webapp 2 4 mmoarpg 00A 04 socket 2 8 根据月计划 ue4 tf1视频教程 进度按照每天一小时时长视频 其余时
  • 博客点击率过万

    写博客有5个月了 今天一看点击率过万了 但是转载的一篇文章点击了2500多次 怎么大家喜欢看文字的东西 而不喜欢技术呢 还是我写的太烂了 2012 7 9
  • QT6+Halcon

    2020年12月8日 Qt公司正式发布了Qt 6 0 这一软件开发平台全新的主要版本 Qt 6 0 已被重新设计为面向未来 以生产力为重点的基础平台 QT迎来一个新时代 Qt Halcon这种组合在机器视觉方面应用非常广泛 一 Qt6全新理
  • C++面向对象+案例(附代码)

    C 核心编程 接上一篇 c 基础入门 文章目录 C 核心编程 1 内存分区模型 1 1 程序运行前 1 2程序运行后 1 3new操作符 2 引用 略 3 函数提高 4 类和对象 4 1封装 4 1 2struct与class区别 4 1
  • 现货交易技巧有哪些可以帮助大家

    想要在现代生活中实现资产升值 或许各种投资理财是最好的选择 但是 不管是选择哪一种 大家都需要掌握基本的一些投资技巧的 比如说现货交易 作为新兴的投资行业 大家必须要认真了解现货交易技巧 这样才可以更好地开展现货交易活动 只有现货交易基础打
  • three.js入门到实战

    学习之前 示例演示 参考资料 api查询 http www webgl3d cn threejs docs index html 代码地址 https github com mrdoob three js 学习方法讲解 对于没有基础的前端小
  • 电机与接触器小结

    目录 各类电机区别 交流 直流电机的区别 同步 异步两类电机区别 为什么会同步 为什么会不同步呢 永磁同步电机 永磁同步电机内部构造 永磁同步电机工作原理 普通 变频两类电机区别 电动机的绝缘强度问题 谐波电磁噪声与震动 低转速时的冷却问题
  • 全面认识Linux下打包解压压缩命令

    1 前言 最近通过sudo tar czf usr src tgz usr src 这个命令发现我对打包方面的命令一无所知 故正式学习记录下 这个命令动作为 将 usr src 目录下的文件打包压缩为当前路径下的usr src tgz文件
  • Explain详解与索引最佳实践

    文章目录 Explain 解释 示范表 使用语句 explain 每一列说明 id select type table type key len ref rows EXTRA 索引最佳实践 Explain 解释 示范表 DROP TABLE
  • VMware虚拟机下的CentOS7网络配置

    一 虚拟机设置 VMware界面最上面 选择虚拟机 gt 设置 将网络连接改为桥接模式 如下图所示 二 查看主机DNS地址 win R 输入cmd 启动命令行界面 输入ipconfig all 查看主机DNS服务器地址 如下图所示 三 修改
  • 基于ARM-contexA9蜂鸣器驱动开发

    上次 我们写了一个LED的驱动程序 这一节 我们只需稍微改动一下就可以实现蜂鸣器的驱动 让我们来看看吧 还是跟之前一样 先找电路图 找到电路板上对应的引脚和相关联的寄存器 1 看电路图 1 蜂鸣器接口位于电路板的底板 看电路图可知道是高电平