999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

嵌入式Linux的時鐘語音芯片YF017驅動設計※

2016-01-26 08:18:20王吉豪崔建明
單片機與嵌入式系統應用 2015年10期

王吉豪,崔建明

(山東科技大學 電子通信與物理學院,青島 266590)

?

嵌入式Linux的時鐘語音芯片YF017驅動設計※

王吉豪,崔建明

(山東科技大學 電子通信與物理學院,青島 266590)

摘要:將低成本的時鐘語音芯片融入到嵌入式Linux系統中,不但可以豐富嵌入式設備的功能,而且可以降低開發成本。本文以ARM架構芯片S3C2440結合Linux2.6.22內核作為實例,開發出語音報時芯片YF017的驅動程序,并寫出該驅動程序的上層應用程序。測試結果表明,通過上層應用程序可以準確地調用驅動程序,并使語音芯片發出相應的語音。

關鍵詞:嵌入式Linux;驅動程序;S3C2440;時鐘語音芯片;YF017

引言

在嵌入式Linux系統中加入語音功能,傳統方式是采用聲卡芯片,但是對于僅需簡單語音的場合,使用聲卡芯片作為發音設備在功能上顯得多余,在成本上也大大提高。

YF017系列語音芯片是針對市場推出的一款具有PWM輸出的OTP語音標準芯片,共有3個I/O口,該芯片可以直接驅動喇叭,無需再設計音頻放大電路,外圍最少僅需要一個0.1 μF電容就可以穩定工作,把該芯片用到簡單的語音場合可大大節約開發時間,降低開發成本。

在嵌入式Linux系統中實現簡單的語音功能,YF017系列語音芯片成為首選之一。但是現成的Linux內核中并沒有集成YF017系列語音芯片的驅動,因此,本文將著重實現YF017語音芯片的Linux驅動程序,并實現上層應用程序以驗證驅動程序的正確性。

1YF017芯片介紹

1.1芯片引腳介紹

圖1 YF017芯片引腳圖

YF017語音芯片有8個引腳,如圖1所示。其中:VDD、GND為電源引腳,工作電壓為2.2~6 V,適用范圍很寬。PWM1、PWM2為PWM輸出引腳,用于驅動8~16 Ω范圍內的任何喇叭(建議0.25~1 W)。Vreg為調節引腳,在外接電壓大于4.5 V時,需要在Vreg和GND之間接0.1 μF電容,用于減少電源噪聲,外接電壓小于4.5 V時可不接電容。BSY、DAT、RST為數字I/O引腳,可以與控制芯片連接。

BSY:芯片播放聲音時輸出低電平,待機時保持高電平。

DAT:用于控制芯片內播放指針,收到幾個上升沿脈沖,就播放第幾個地址的聲音內容。

RST:用于復位芯片內播放指針,當該引腳收到一個上升沿脈沖時,可以使芯片的播放指針歸零,同時,芯片進入待機狀態。

1.2芯片語音內容

主控芯片通過發送相應數量的上升沿脈沖到DAT引腳,語音芯片可以播放相應的聲音,脈沖數量與播放聲音的對應關系如表1所列。

表1 對應關系

1.3芯片控制時序

主控芯片上電時,需要先將語音芯片的DAT引腳和RST引腳分別置于低電平。如果需要播放第25段聲音,先將RST引腳拉高,過1 ms再拉低,使播放指針復位。接著連續發送25個上升沿脈沖到DATA引腳,芯片即可播放第25段的聲音。如果接下來需要播放第22段的聲音,主控芯片需要檢測語音芯片的BSY引腳是否為高電平,如果BSY為低電平,則表示語音芯片正忙,主控芯片需要等待,直到BSY引腳為高電平時,可按照之前的步驟,先發送上升沿脈沖給RST,再發送22個上升沿脈沖給DAT引腳,這樣可播放語音芯片中的任意語音。RST和DAT脈沖寬度至少為0.2 ms,建議1 ms。

2YF017驅動程序設計

2.1硬件原理圖

將語音芯片接入主控芯片為S3C2440的嵌入式Linux的開發板中,S3C2440芯片的GPIO引腳GPG5、GPG6、GPG7分別接語音芯片的RST、DAT、BSY引腳,如圖2所示。

2.2驅動程序設計

2.2.1入口函數speak_init

入口函數speak_init使用register_chrdev函數向內核申請主設備號,把設備的操作函數結構體speak_ops向內核注冊,并使用class_create函數和class_device_create函數在Linux文件系統的/sys/目錄下生成設備信息,調用mdev應用程序。 mdev應用程序根據/sys/目錄下生成的設備信息在/dev/目錄下創建設備節點,該程序的設備節點為/dev/speak。

2.2.2出口函數speak_exit

圖2 硬件原理圖

出口函數speak_exit使用unregister_chrdev函數釋放之前向內核申請的主設備號,并使用class_device_destroy函數和class_destroy函數把之前在文件系統/sys/目錄下生成的設備信息刪除,并調用mdev應用程序。 mdev應用程序根據/sys/目錄下設備信息的變動,將/dev/目錄下創建的設備節點speak刪除。

2.2.3底層操作函數

把設備的底層操作函數都指向操作函數結構體speak_ops,以便使用register_chrdev函數向內核注冊。speak_ops結構體定義如下:

static struct file_operations speak_ops = {

.owner = THIS_MODULE,

.open = speak_open,

.read = speak_read,

.write = speak_write,

};

(1) speak_open函數

該函數用于配置S3C3440的GPIO引腳,將GPG5、GPG6用作輸出,GPG7用作輸入,并將GPG5、GPG6初始化為低電平。當上層應用程序調用open(“/dev/speak”)函數時,將調用到speak_open函數。實現程序代碼如下:

#define GPIO_RESETS3C2410_GPG5

#define GPIO_DATA S3C2410_GPG6

#define GPIO_BUSY S3C2410_GPG7

static int speak_open(struct inode *inode, struct file *file){

/* 1. 將GPG5、GPG6用作輸出,GPG7用作輸入*/

s3c2410_gpio_cfgpin(GPIO_RESET, S3C2410_GPIO_OUTPUT);

s3c2410_gpio_cfgpin(GPIO_DATA, S3C2410_GPIO_OUTPUT);

s3c2410_gpio_cfgpin(GPIO_BUSY, S3C2410_GPIO_INPUT);

/* 2.將GPG5、GPG6初始化為低電平 */

s3c2410_gpio_setpin(GPIO_RESET, 0);

s3c2410_gpio_setpin(GPIO_DATA, 0);

return 0;

}

(2) speak_read函數

該函數用于讀取語音芯片的BSY引腳并返回1字節狀態,返回1代表BSY引腳為高電平,返回0代表BSY引腳為低電平。當上層應用程序調用read()函數時將調用到speak_read函數。實現代碼如下:

ssize_t speak_read (struct file *file, char __user *buf, size_t len, loff_t *pos){

unsigned char val;

/* 1.讀取BSY引腳的狀態 */

val = (s3c2410_gpio_getpin(GPIO_BUSY)) ?1:0;

/* 2.將BSY的狀態從內核空間復制到用戶空間 */

if(copy_to_user(buf, &val, 1)){

return -EFAULT;

}

return 1;

}

(3) speak_write函數

該函數把用戶空間發過來的語音地址指針序號轉化為控制語音芯片的脈沖。當上層應用程序調用write()函數時將調用到speak_write函數。實現代碼如下:

static ssize_t speak_write (struct file *file, const char __user *buf, size_t len, loff_t *pos){

int i;

unsigned char val;

/* 1. 把用戶數據從用戶空間復制到內核空間 */

if(copy_from_user(&val, buf, 1)){

return -EFAULT;

}

/* 2.判斷語音地址指針是否越界,越界返回錯誤*/

if (val > 32){

printk(KERN_NOTICE VERSION"out of band ! ");

printk(KERN_NOTICE VERSION"val = %d ", val);

return -ENXIO;

}

/*3.根據時序要求,先發復位脈沖信號到語音芯片 */

s3c2410_gpio_setpin(GPIO_RESET, 1);

udelay(1000);

s3c2410_gpio_setpin(GPIO_RESET, 0);

/* 4.根據用戶傳過來的數據設置語音地址指針,讓語音芯片發出相應聲音 */

for (i = 0; i < val; i++){

s3c2410_gpio_setpin(GPIO_DATA, 1);

udelay(1000);

s3c2410_gpio_setpin(GPIO_DATA, 0);

udelay(1000);

}

return 0;

}

2.3驅動程序編譯

寫Makefile并在程序所在的目錄執行make命令,將編譯生成drv_speak.ko文件。

Makefile內容如下:

#用于指定內核源碼目錄

KERN_DIR = /work/system/Linux-2.6.22.6

all:

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

clean:

make-C $(KERN_DIR) M=`pwd` modules clean

rm-rf Module.symvers

#指定驅動源程序文件

obj-m += drv_speak.o

2.4驅動程序安裝與卸載

將編譯生成的drv_speak.ko文件,復制到嵌入式Linux文件系統中,執行命令insmod drv_speak.ko將把該驅動模塊加載到內核中。通過rmmod drv_speak命令可將驅動卸載,insmod和rmmod命令的執行將分別調用驅動中的speak_init 和speak_exit函數。

可以通過命令 cat /proc/devices 查看speak設備的存在,也可以在/dev/目錄下查看speak設備節點,在/sys/目錄下查看生成的設備信息。

3YF017應用程序設計

3.1應用程序設計

應用程序通過讀取本地時間并控制/dev/speak發出相應的聲音來驗證驅動程序的正確性。

3.1.1主函數main

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

int fd;

time_t t;

struct tm* time_now;

/* 1.打開語音報時設備 */

fd = open("/dev/speak", O_RDWR);

if (fd < 0){

printf("can't open /dev/speak ");

return -1;

}

/* 2.獲取時間 */

time(&t);

time_now = localtime(&t);

/* 3.報時 */

speak_time(fd, time_now);

return 0;

}

3.1.2報時函數speak_time

void speak_time(int fd, struct tm* t){

unsigned int month, day, week, hour, min;

/*1. 獲取日期和時間 */

month = t->tm_mon + 1;

……

min = t->tm_min;

/*2. 將報時分單字段 */

speak_segment(fd, SPK_NUM_2, month);

speak_segment(fd, SPK_MONTH, 0);

speak_segment(fd, SPK_NUM_2, day);

speak_segment(fd, SPK_DAY, 0);

……

}

3.1.3單字段報音函數speak_segment

void speak_segment(int fd, unsigned int which, unsigned int val){

unsigned char addr;

/* 根據傳入的命令值which和val分別調用write_and_wait函數 */

switch (which){

case SPK_MONTH:

case SPK_DAY:

……

case SPK_HOUR:

case SPK_MIN:

case SPK_TIDY:

addr = which;

write_and_wait(fd, &addr, 1);

break;

……

}

}

3.1.4寫等待函數write_and_wait

該函數將用戶傳來的指令寫到/dev/speak設備中,并用睡眠方式等待/dev/speak設備空閑。程序實現代碼如下:

void write_and_wait(int fd, void* buf, int cnt){

unsigned char busy;

write(fd, buf, cnt);

do {

read(fd, &busy, 1);

usleep(1000);

}while(!busy);

}

3.2應用程序編譯

使用交叉編譯工具編譯,執行命令“arm-Linux-gcc-o app_speak app_speak.c”將生成app_speak可執行文件。

3.3應用程序運行

將可執行文件app_speak復制到嵌入式Linux文件系統中,運行前確保drv_speak.ko已經安裝到內核中。在app_speak所在目錄執行./app_speak命令,將聽到語音芯片發出報時聲音。語音報時時間和執行date命令顯示的時間一致。

結語

通過編寫對/dev/speak進行控制的上層應用程序并運行,可以正確發出報時聲音,表明驅動程序已成功加載進內核并能正常地工作。

參考文獻

[1] 宋寶華.Linux設備驅動開發詳解[M].北京:人民郵電出版社,2008.

[2] 倪繼利.Linux內核分析及編程[M].北京:電子工業出版社,2007.

[3] 何永琪.嵌入式Linux系統實用開發[M].北京:電子工業出版社,2010.

[4] 孫瓊.嵌入式Linux應用程序開發詳解[M].北京:人民郵電出版社,2006.

王吉豪(研究生),研究方向為嵌入式系統及應用;崔建明(副教授),從事集成電路設計教學與研究。

Voice Chip YF017 Driver Design Based on Linux※

Wang Jihao,Cui Jianming

(College of Electronic,Communication and Physics,Shandong University of Science and Technology,Qingdao 266590,China)

Abstract:Taking the low cost voice chip into the embedded Linux system,it is not only can enrich the function of embedded system,but also can reduce the cost of development.This paper develops the voice chip YF107 driver and the upper application program,using ARM chip S3C2440 with Linux2.6.22 kernel as an example.The test results shows that the program can accurately call the driver through the upper application,and the voice chip can send out the corresponding voice.

Key words:embedded Linux;driver;S3C2440;voice chip;YF017

收稿日期:(責任編輯:楊迪娜2015-05-07)

中圖分類號:TP311

文獻標識碼:A

主站蜘蛛池模板: 99热这里都是国产精品| 国产女人喷水视频| 最新国产高清在线| 亚洲欧美日韩精品专区| 一区二区三区四区在线| 久久精品只有这里有| 欧美日韩午夜视频在线观看 | 影音先锋丝袜制服| 国产成a人片在线播放| 精品少妇人妻无码久久| 亚洲人妖在线| 人妻丰满熟妇av五码区| 被公侵犯人妻少妇一区二区三区 | 国产精品高清国产三级囯产AV| 欧美视频在线观看第一页| 国产精品三区四区| 欧美一级在线| 亚洲人成影视在线观看| 日韩欧美中文| 国产黄在线免费观看| 狠狠亚洲婷婷综合色香| 亚洲欧美在线看片AI| 午夜一区二区三区| 国产成人亚洲欧美激情| 四虎成人在线视频| 国产成人精品18| 青青草国产一区二区三区| 亚洲欧洲国产成人综合不卡| 四虎永久免费地址| 欧美色综合网站| 亚洲男人的天堂网| 亚洲AV成人一区国产精品| 亚洲三级影院| 99视频精品在线观看| 久久久久久久97| 40岁成熟女人牲交片免费| 啪啪啪亚洲无码| 国产理论最新国产精品视频| 精品视频第一页| 2019国产在线| 国产在线观看99| 青青青国产精品国产精品美女| 国产成人午夜福利免费无码r| 国产在线视频欧美亚综合| 国产综合色在线视频播放线视| 99re精彩视频| 在线色国产| 极品性荡少妇一区二区色欲| 国产欧美日韩资源在线观看| 亚洲精品无码日韩国产不卡| 婷婷综合缴情亚洲五月伊| 亚洲一级无毛片无码在线免费视频| 91久久国产综合精品女同我| 亚洲无限乱码一二三四区| 免费视频在线2021入口| 欧美成人午夜视频免看| 国产高清不卡| 91国内在线观看| 91福利在线观看视频| 精品一区二区三区自慰喷水| 激情视频综合网| 99精品一区二区免费视频| 91在线视频福利| 亚洲欧美综合精品久久成人网| 欧美第九页| 黄色网页在线播放| 欧美色伊人| 国产成人高清在线精品| 99国产在线视频| 欧美丝袜高跟鞋一区二区| 波多野结衣二区| 国产欧美日韩一区二区视频在线| 亚洲午夜片| 中文字幕天无码久久精品视频免费| 日韩中文欧美| 新SSS无码手机在线观看| 欧美人在线一区二区三区| 好吊色国产欧美日韩免费观看| 日本高清免费一本在线观看| 国产激情第一页| h视频在线播放| 国产无套粉嫩白浆|