开发环境

主机开发环境:ubuntu12.04
BootLoader:u-boot-1.1.6
kernel:linux-2.6.30.4
CPU:s3c2440
开发板:TQ2440

开发步骤

1、硬件分析

硬件电路图如下:

在驱动程序里面首先初始化该 PWM 所对应的管脚的功能,然后初始化定时器设置对 PWM 的定时,最后启动 PWM 功能。

2、蜂鸣器驱动代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>#define DEVICE_NAME     "Beep"
#define BEEP_MAJOR 233 /* 主设备号 *//* 应用程序对设备文件/dev/Beep 执行 ioclt(...)时,
* 就会调用 le2440_beep_ioctl 函数
*/
static int le2440_beep_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){unsigned long temp;unsigned long gpbcon;unsigned long tcfg0;unsigned long tcfg1;unsigned long tcntb;unsigned long tcmpb;unsigned long tcon;if(cmd <= 0){temp = __raw_readl(S3C2410_GPBCON); //GPBCONtemp &= ~3;temp |= 1;__raw_writel(temp, S3C2410_GPBCON);temp = __raw_readl(S3C2410_GPBDAT); //GPBDATtemp &= ~1;__raw_writel(temp, S3C2410_GPBDAT);}else{gpbcon = __raw_readl(S3C2410_GPBCON); //GPBCONgpbcon &= ~3;gpbcon |= 2;__raw_writel(gpbcon, S3C2410_GPBCON);tcfg0 = __raw_readl(S3C2410_TCFG0); //TCFG0tcfg0 &= ~0xff;tcfg0 |= 15;__raw_writel(tcfg0, S3C2410_TCFG0);tcfg1 = __raw_readl(S3C2410_TCFG1); //TCFG1tcfg1 &= ~0xf;tcfg1 |= 2;__raw_writel(tcfg1, S3C2410_TCFG1);tcntb = (50000000/128)/cmd;__raw_writel(tcntb, S3C2410_TCNTB(0));tcmpb >>= 1;__raw_writel(tcmpb, S3C2410_TCMPB(0));tcon = __raw_readl(S3C2410_TCON); //TCONtcon &= ~0x1f;tcon |= 0xb;__raw_writel(tcon, S3C2410_TCON);tcon &= ~2;__raw_writel(tcon, S3C2410_TCON);}
return 0;
}/* 这个结构是字符设备驱动程序的核心
* 当应用程序操作设备文件时所调用的 open、read、write、ioctl 等函数,
* 最终会调用这个结构中指定的对应函数
*/
static struct file_operations le2440_beep_fops = {.owner = THIS_MODULE,.ioctl = le2440_beep_ioctl,
};static struct class *beep_class;
/*
* 执行“insmod le2440_beep.ko”命令时就会调用这个函数
*/
static int __init le2440_beep_init(void)
{int ret;/* 注册字符设备驱动程序
* 参数为主设备号、设备名字、file_operations 结构;
* 这样,主设备号就和具体的 file_operations 结构联系起来了,
* 操作主设备为 BEEP_MAJOR 的设备文件时,就会调用 le2440_beep_fops 中的相关成员函数
* BEEP_MAJOR 可以设为 0,表示由内核自动分配主设备号
*/ret = register_chrdev(BEEP_MAJOR, DEVICE_NAME, &le2440_beep_fops);if (ret < 0){printk(DEVICE_NAME " can't register major number\n");return ret;}//注册一个类,使 mdev 可以在"/dev/"目录下面建立设备节点beep_class = class_create(THIS_MODULE, DEVICE_NAME);if(IS_ERR(beep_class)){printk("Err: failed in le2440-Beep class. \n");return -1;}//创建一个设备节点,节点名为 DEVICE_NAMEdevice_create(beep_class, NULL, MKDEV(BEEP_MAJOR, 0), NULL, DEVICE_NAME);printk(DEVICE_NAME " initialized\n");return 0;
}/*
* 执行”rmmod le2440_beep.ko”命令时就会调用这个函数
*/
static void __exit le2440_beep_exit(void)
{/* 卸载驱动程序 */unregister_chrdev(BEEP_MAJOR, DEVICE_NAME);device_destroy(beep_class, MKDEV(BEEP_MAJOR, 0)); //删掉设备节点class_destroy(beep_class); //注销类
}/* 这两行指定驱动程序的初始化函数和卸载函数 */
module_init(le2440_beep_init);
module_exit(le2440_beep_exit);
MODULE_LICENSE("GPL"); // 遵循的协议

Makefile如下:

#Makefile
ifeq ($(KERNELRELEASE),) KERNELDIR ?= /home/linux/sky/ker/linux-2.6.30.4/ #KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD)  modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules* .PHONY: modules modules_install clean elseobj-m := le2440_beep.oendif
3、app控制程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
struct spihr
{unsigned short status;unsigned short dat;
};
int main(int argc, char **argv)
{int fd;unsigned long temp =0;int i;fd = open("/dev/Beep", 0);if (fd < 0) {perror("open device beep");exit(1);}printf("Please enter the times number (0 is stop) :\n");for(i=0;;i++){scanf("%d",&temp);printf("times = %d \n",temp);if(temp == 0){ioctl(fd, 0);printf("Stop Control Beep!\n");break;}else{ioctl(fd, 1, temp);}}close(fd);return 0;
}

Makefile如下:

CROSS=arm-linux-
all: beep
beep: beep.c$(CROSS)gcc -o beep beep.c$(CROSS)strip beep
clean:@rm -vf beep *.o *~
4、测试现象

嵌入式驱动学习之PWM蜂鸣器驱动相关推荐

  1. Linux驱动学习之什么是驱动?

    一.什么是驱动? 1: 驱动一词的字面意思 2: 物理上的驱动 3: 硬件中的驱动 4: linux内核驱动.软件层面上的驱动广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序. ...

  2. linux2.6驱动学习笔记之字符驱动

    1.字符驱动组成 1.1字符驱动的模块加载与卸载 //设备结构体模板 struct xxx_dev_t { struct cdev cdev; ...... }xxx_dev; 在字符驱动模块加载函数 ...

  3. linux 驱动学习笔记-ALSA声卡驱动(二)

    前言 ASoC是建立在标准ALSA驱动层上 ,对底层的alsa框架封装了一层,为了更好的支持嵌入式cpu和音频解码器设备的一套软件体系 在ASOC出现之前 解码器驱动和平台CPU驱动联系过于紧密,导致 ...

  4. 【嵌入式Linux学习笔记】Linux驱动开发

    Linux系统构建完成后,就可以基于该环境方便地进行开发了,相关的开发流程与MCU类似,但是引入了设备树的概念,编写应用代码要相对复杂一点.但是省去了很多配置工作. 学习视频地址:[正点原子]STM3 ...

  5. dev layoutview 怎么显示大小_Liunx驱动学习:基于imx6ul 驱动oledssd1306 实现终端显示...

    说明: 在学习linux驱动的过程中,绕不开的就是LCD驱动,网上大部分教程都是教大家如果使用分辨率比较高的LCD作为Linux开发板的显示终端,但并没有讲过如果驱动spi或者iic这种低分辨率低帧率 ...

  6. 嵌入式开发学习之--用蜂鸣器来传递摩斯码

    本篇文章致力于从开发的角度思考问题,而不是搞学术的东西. 文章目录 前言 一.项目概况 1.1项目需求 1.2项目来源 1.3项目开发环境 1.4项目意义 二.开发步骤 2.1了解什么是摩斯码 2.2 ...

  7. linux c蜂鸣器驱动程序,Linux 设备驱动简析—PC蜂鸣器驱动

    /* *By Neil Chiao () *欢迎到"新星湾()"指导 */ 在X86平台的主板上一般都有一个蜂鸣器,有人可能认为这么简单的东西,根本不需要驱动吧?但是其实Linux ...

  8. 驱动学习 - 加载.卸载驱动

    #ifdef __cplusplus extern "C" { #endif#include <ntddk.h> //以"C"语言的方式编译 #if ...

  9. Linux驱动学习笔记之触摸屏驱动

    触摸屏归纳为输入子系统,这里主要是针对电阻屏,其使用过程如下 当用触摸笔按下时,产生中断. 在中断处理函数处理函数中启动ADC转换x,y坐标. ADC结束,产生ADC中断 在ADC中断处理函数里上报( ...

  10. linux驱动学习2(kpd驱动初步分析)

    一.kpd_pdrv_probe函数的分析: /*1. 输入设备实例 kpd_input_dev */ 全局变量:static struct input_dev *kpd_input_dev; sta ...

最新文章

  1. python字符串连接方式_Python 字符串连接方式有这么种,你知道吗?
  2. boost::hana::alignof_用法的测试程序
  3. pb预览状态下的pagecount_我为什么喜欢用Mac【预览】阅读文献?
  4. internet访问局域网内部方法之----------路由器端口映射
  5. AIDL Service,跨进程调用Services
  6. java创建response对象_javaweb入门-----request与response的作用
  7. java适配器模式 场景_详解Java适配器模式
  8. Markdown 表格
  9. 九型人格,工作中的好帮手
  10. 一篇文章教会你需求分析文档怎么写
  11. wpsmac历史版本_wps mac版-WPS Office 2019 for Mac1.9.0(2959)官方版
  12. python代码画微信标志图片_Python 一键制作微信好友图片墙
  13. python抬笔_『怎样在python里让海龟画图抬笔落笔?』
  14. 三级等保 关闭111端口
  15. html中亮度怎么写,HTML+CSS+JS模仿win10亮度调节效果的示例代码
  16. ThinkPHP php 仿千图网源码_2018最新友价内核
  17. 实数在计算机中的表示
  18. java 二进制转换成十六进制字符串_将二进制字符串转换为十六进制字符串JAVA
  19. 归一法的计算方法讲解_数学归一法是什么能举个具体例子吗
  20. Android中高级进阶知识(最新动脑学院安卓进阶视频 )

热门文章

  1. android camera hal3 新增vendor tag
  2. S5P4418裸机开发(三):运行裸机程序
  3. android_基础_修改系统背景(状态栏颜色、导航栏颜色、标题栏颜色等等)
  4. 24券创始人杜一楠的失败检讨书:24券是如何毁在我手上的?[转]
  5. Pro Tools正确卸载姿势大全
  6. antd menu 样式修改
  7. 我们怎样制作照片拼图?简单实用的拼图方法来了
  8. php 依赖安装顺序6,构建PHP框架:第6部分-依赖倒置,控制倒置,哦,天哪!
  9. IOS音视频(四十五)HTTPS 自签名证书 实现边下边播
  10. java jframe 设置背景图片_Java怎么给JFrame添加背景图片