美文网首页
C编程使用内联汇编控制PC蜂鸣器发声

C编程使用内联汇编控制PC蜂鸣器发声

作者: 网路元素 | 来源:发表于2019-10-31 17:11 被阅读0次

有了《初识Linux汇编》和《内联汇编控制PC蜂鸣器》两篇文章的基础了解后,我们使用内联汇编来改造《C编程控制PC蜂鸣器》一文的例子,最终的代码如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>

/* The clock frequency of the i8253/i8254 PIT */
#define PIT_TICK_RATE 1193182ul

void beep(unsigned int value)
{
        unsigned int count = 0;
        unsigned char val;
        unsigned short port;

        if (value > 20 && value < 32767)
                count = PIT_TICK_RATE / value;

        iopl(3);

        if (count) {
                val = 0xB6;
                port = 0x43;
                asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
                val = count & 0xff;
                port = 0x42;
                asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
                val = (count >> 8) & 0xff;
                asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
                port = 0x61;
                asm volatile("inb %1,%0" : "=a" (val) : "dN" (port));
                val = val | 3;
                asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
        } else {
                port = 0x61;
                asm volatile("inb %1,%0" : "=a" (val) : "dN" (port));
                val = val & 0xFC;
                asm volatile("outb %0,%1" : : "a" (val), "dN" (port));
        }
        iopl(0);
}

int main(int argc,char * argv[])
{
        unsigned int val;

        if (argc != 2) {
                printf("Usage:%s value\n 20<value<32767,other value will stop!\n",argv[0]);
                return 0;
        }

        val = atoi(argv[1]);
        beep(val);

        return 0;
}

对于相应的Makefile文件及C源码文件名均未更改,本次仅作8254控制部分的更改,其他均保留。

相关文章

网友评论

      本文标题:C编程使用内联汇编控制PC蜂鸣器发声

      本文链接:https://www.haomeiwen.com/subject/vmqryctx.html