x86主板蜂鸣器操作

x86架构上蜂鸣器控制原理图如下:

x86主板蜂鸣器操作_第1张图片

由上图可知,我们要控制蜂鸣器,那么首先通过定时器2产生一个驱动方波信号,然后控制io使能信号,驱动蜂鸣器工作。
通常计算机系统提供了三个定时器,其中定时器0用于产生操作系统的心跳时钟;
定时器1用于产生SDRAM的周期性刷新信号(20ms左右);
定时器2用于驱动蜂鸣器,产生报警信号。
Intel的8254芯片就提供了三路可编程定时器,一直沿用至今。
8254控制该芯片的IO端口为IO_BASE + 0x40 ~ IO_BASE + 0x43,
其中0x40、0x41、0x42分别为三路定时器的16位定时值寄存器,0x43为控制命令寄存器。
控制命令寄存器的格式定义如下:

        1. bit[7:6]——定时器选择位。选择对哪个计数器进行操作。“00”表示选择Counter 0,“01”表示选择Counter 1,“10”表示选择Counter 2,“11”表示Read-Back Command(仅对于8254,对于8253无效)。

        2. bit[5:4]——Read/Write/Latch格式位。“00”表示锁存(Latch)当前计数器的值;“01”只读写计数器的高字节(MSB);“10”只读写计数器的低字节(LSB);“11”表示先读写计数器的LSB,再读写MSB。
3. bit[3:1]——Mode bits,控制各通道的工作模式。“000”对应Mode 0;“001”对应Mode 1;“010”对应Mode 2;“011”对应Mode 3(方波信号发生器);“100”对应Mode 4;“101”对应Mode 5。
4. bit[0]——控制计数器的存储模式。0表示以二进制格式存储,1表示计数器中的值以BCD格式存储。
知道如何控制定时器2之后,剩下的一个问题就需要了解speaker使能的IO端口了。
这个端口就是0x61,0x61是8255的一个端口,这个端口的低两位用来控制蜂鸣器,位信息描述如下:
1、bit0用来使能counter2,当bit0==0时,禁止counter2,否则使能counter2。
2、bit1用来控制counter2输出的方波信号,当为1时输出使能,否则禁止输出。

控制函数如下:

#include   <sys/io.h>   
#include   <unistd.h>   
int   speaker(unsigned   int   freq,unsigned   int   delay)   
{   	
		static   int  bit;    
           iopl(3);   
          outb(0xb6,0x43);   //设置控制命令字
          outb((freq   &   0xff),0x42);  //设置定时器2的低8位 
          outb((freq   >>   8),0x42);   //设置定时器2的高8位
          bit=inb(0x61);   
          outb(3   |   bit,0x61);  //11使能峰鸣器输出 
          sleep(delay);   
          outb(0xfc&bit,0x61);   //00禁止峰鸣器输出
 }  

你可能感兴趣的:(x86主板蜂鸣器操作)