蜂鸣器驱动的学习
蜂鸣器驱动
蜂鸣器分直流和交流两种,所谓的直流蜂鸣器是加个电压就可以响,交流蜂鸣器其实就相当于一个喇叭,直接加直流后不会出声或者声音很低,需要外加脉冲才能正常工作,这个脉冲可以是方波,也可以是一段音乐,这个信号属于交流信号。
mini2440的蜂鸣器连接图如下:
貌似这是一个交流蜂鸣器,所以需要pwm驱动。
在此之前先介绍几个函数:
S3C2410_GPB
如果gpioa的最低位引脚偏移量为0,总的来说s3c2410_gpb求得是b中的各个引脚相对于GPIOa最低位的偏移量。
s3c2410_gpio_cfgpin
用法:
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
功能:
这个函数的功能是配置IO口的功能。
源码:
纠结了一晚上,原来奥秘就在s3c24xx_gpio_base中。
s3c24xx_gpio_base直接根据端口号算出了其对应的虚拟地址,太nb了吧,不用映射吗?下面来看看这个源码:
可以看出,根据pin对应的寄存器的偏移量计算出其虚拟地址,这里的0xf4000000是早就设定好的地址,我的理解是初始化的时候这以及这之后的一段地址就已经映射到了物理内存,现在直接用就好了。
这里有个问题,就是3G-3G+896M范围内都是直接映射,我的理解是直接映射区域最大896M,这里应该不足896M,剩下的部分分配给了动态内存映射区,也就是说0xf4000000以及之后的一块其实是动态映射到了0x51000000(差不多是这个数。。)左右的物理内存。
大神原话如下:
s3c2410_gpio_setpin
用法:
s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
功能:
将io口拉高或者拉低。
Ioctl的命令构造:
其实ioctl的命令就是个数,但是为了防止你的驱动一不小心打开别的文件结果命令恰巧还对的上,ioctl的命令分为以下几个部分:
1. 幻数:说白了,不同的驱动程序所用的幻数应该是不同的
2. 序号,你自己的驱动程序中命令的序号
3. 数据流向,如果要传参,则涉及到数据流向
4. 数据大小
Cmd的构造方式如下:
_IO(type,nr) //没有参数的命令
_IOR(type,nr,size) //该命令是从驱动读取数据
_IOW(type,nr,size) //该命令是从驱动写入数据
_IOWR(type,nr,size) //双向数据传输
从cmd中提取参数的宏如下:
_IOC_DIR(cmd) //从命令中提取方向
_IOC_TYPE(cmd) //从命令中提取幻数
_IOC_NR(cmd) //从命令中提取序数
_IOC_SIZE(cmd) //从命令中提取数据大小
混杂设备驱动
自动生成设备文件,初始化
设置PWM流程
1. 设置预分频寄存器(TCFG0)
2. 设置分割值(在预分频的基础上再次分割)(TCFG1)
3. 设置计数器的值(TCNTB)
4. 设置占空比(TCMPB)
5. 将控制寄存器器设置为自动重载,然后手动更新一次(TCNTB和TCMPB中的值装入TCNT、TCMP),开启定时器(TCON)
6. 关闭手动更新(TCON)