0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

采用DS80C400芯片軟件的互聯(lián)網(wǎng)揚(yáng)聲器

星星科技指導(dǎo)員 ? 來源:ADI ? 作者:ADI ? 2023-02-20 10:02 ? 次閱讀

DS80C400微處理器網(wǎng)絡(luò)功能使其成為設(shè)計(jì)簡單以太網(wǎng)揚(yáng)聲器的自然選擇。通過使用處理器ROM內(nèi)置的TCP/IP堆棧,用8051匯編編寫的應(yīng)用程序可以輕松地從網(wǎng)絡(luò)讀取流音頻數(shù)據(jù),并使用該數(shù)據(jù)驅(qū)動(dòng)數(shù)模轉(zhuǎn)換器DAC),為一組揚(yáng)聲器提供線路電平輸出。本應(yīng)用筆記介紹了運(yùn)行支持以太網(wǎng)的簡單揚(yáng)聲器所需的硬件設(shè)計(jì)和軟件。

系統(tǒng)概述

軟件

在頂層,應(yīng)用程序由一臺(tái)主機(jī)組成,通過網(wǎng)絡(luò)連接將未壓縮的音頻(如WAV文件中的數(shù)據(jù))發(fā)送到DS80C400,DS1C<>監(jiān)聽和播放音頻數(shù)據(jù)。圖<>顯示了該系統(tǒng)的框。

poYBAGPy1M2AP9VrAAArF8l5BBc415.gif?imgver=1


圖1.系統(tǒng)框圖。

必須有兩個(gè)軟件應(yīng)用程序才能使該系統(tǒng)工作。一個(gè)應(yīng)用程序必須在主機(jī)上運(yùn)行,并將音頻數(shù)據(jù)發(fā)送到DS80C400。另一個(gè)應(yīng)用程序必須在DS80C400上運(yùn)行并播放音頻數(shù)據(jù)。

主機(jī)應(yīng)用程序在此系統(tǒng)中的工作很容易。它必須從 WAV 文件中讀取原始音頻數(shù)據(jù)并通過網(wǎng)絡(luò)發(fā)送。由于主機(jī)上沒有使用大量處理能力,因此它也執(zhí)行其他一些工作,例如流控制和簡單的數(shù)據(jù)格式化。

DS80C400上的應(yīng)用稍微復(fù)雜一些。它需要通過網(wǎng)絡(luò)接收音頻數(shù)據(jù),并以指定的采樣率將該數(shù)據(jù)推送到音頻電路。

接收音頻數(shù)據(jù)是在循環(huán)中實(shí)現(xiàn)的,該循環(huán)等待音頻數(shù)據(jù),并在音頻數(shù)據(jù)可用時(shí)將其寫入循環(huán)緩沖區(qū)。當(dāng)它接收新數(shù)據(jù)時(shí),它還必須維護(hù)一個(gè)指向緩沖區(qū)中有效數(shù)據(jù)末尾的指針,以便應(yīng)用程序不會(huì)播放無效數(shù)據(jù)。

揚(yáng)聲器應(yīng)用的第二部分是將數(shù)據(jù)推送到音頻電路的部分。音頻數(shù)據(jù)被饋送到數(shù)模轉(zhuǎn)換器,該轉(zhuǎn)換器反過來驅(qū)動(dòng)普通的計(jì)算機(jī)揚(yáng)聲器。由于常規(guī)時(shí)序?qū)σ纛l應(yīng)用至關(guān)重要,因此應(yīng)用的這一部分作為定時(shí)器中斷實(shí)現(xiàn)。圖 2 顯示了應(yīng)用程序的循環(huán)和計(jì)時(shí)器部分如何通過循環(huán)音頻緩沖區(qū)進(jìn)行交互。

poYBAGPy1M6AAL57AAApWWuBfyo769.gif?imgver=1


圖2.循環(huán)音頻緩沖區(qū)。

硬件

圖3所示為音頻電路示意圖,可連接至TINIm400驗(yàn)證模塊或基于DS80C400的定制設(shè)計(jì)。對于這個(gè)項(xiàng)目,揚(yáng)聲器應(yīng)用程序是在最初為網(wǎng)絡(luò)攝像機(jī)設(shè)計(jì)的電路板上開發(fā)的,并進(jìn)行了一些小的修改。

pYYBAGPy1NKAZXpfAABGs10IY2c903.gif?imgver=1


圖3.硬件框圖。

在此配置中,數(shù)模轉(zhuǎn)換器提供 0 至 2V 的輸出。由于線路電平揚(yáng)聲器輸入為±1V,因此揚(yáng)聲器的接地連接到1V。本電路使用的數(shù)模轉(zhuǎn)換器為MAX542。1,其精度為 16 位。串行數(shù)據(jù)可以通過DS80C400的串行端口傳遞到DAC,這比以編程方式切換時(shí)鐘和數(shù)據(jù)引腳要快得多。MAX542具有一條片選線,在串行負(fù)載期間必須保持低電平,負(fù)載信號(Load DAC)必須在所有串行數(shù)據(jù)寫入后保持低電平。

主機(jī)應(yīng)用程序:發(fā)送未壓縮的音頻

主機(jī)應(yīng)用程序是一個(gè)名為 SendDataTCP 的 Java? 類。它是一個(gè)Java應(yīng)用程序,讀取PCM編碼的WAV文件,執(zhí)行一些簡單的格式化,并通過TCP連接將音頻樣本塊發(fā)送到DS80C400。

該程序假設(shè)正在讀取的WAV文件包含立體聲,16位數(shù)據(jù),以44.1kHz的采樣率播放。但是,該應(yīng)用程序支持發(fā)送 44.1、22.05 和 11.025kHz 的采樣率,因此音頻數(shù)據(jù)可能需要重新格式化。假設(shè)WAV文件中的數(shù)據(jù)為16位立體聲,因此每個(gè)樣本由4個(gè)字節(jié)組成(通道2為1字節(jié),通道2為2字節(jié))。如果DS80C400需要單聲道數(shù)據(jù)而不是立體聲數(shù)據(jù),則僅從WAV文件中提取一個(gè)通道。如果采樣率低于44.1kHz,則跳過某些樣本。例如,如果DS80C400需要采樣率為22.05kHz的立體聲數(shù)據(jù),則SendDataTCP程序?qū)l(fā)送2字節(jié)的通道1數(shù)據(jù),發(fā)送2字節(jié)的通道2數(shù)據(jù),然后跳過下一個(gè)樣本。如果預(yù)計(jì)單聲道數(shù)據(jù)頻率為22.05kHz,則SendDataTCP程序?qū)l(fā)送2字節(jié)的通道1數(shù)據(jù),跳過通道2部分,然后跳過整個(gè)下一個(gè)樣本。

在發(fā)送數(shù)據(jù)之前,必須再執(zhí)行兩次轉(zhuǎn)換。首先,必須將示例從有符號數(shù)據(jù)轉(zhuǎn)換為無符號數(shù)據(jù)。WAV文件包含表示-1至1之間電壓的有符號數(shù)據(jù),但MAX542接受表示0至2之間電壓的無符號數(shù)據(jù)。請注意,由于電路為揚(yáng)聲器提供1V的虛擬地,因此所需的轉(zhuǎn)換是簡單地在WAV文件中定義的電壓上增加1 V。由于輸入值8000十六進(jìn)制代表MAX1輸出的542V,因此需要為每個(gè)8000位采樣增加16十六進(jìn)制。請注意,這與切換樣本的高位的操作相同。表 1 顯示了來自 WAV 文件的單個(gè) 16 位樣本、所需電壓、未改變樣本產(chǎn)生的電壓以及 改變后的樣本將產(chǎn)生的電壓。

表 1.改變音頻樣本以實(shí)現(xiàn)所需的電壓輸出

16 位音頻樣本(十六進(jìn)制) 所需電壓 來自未改變樣品的電壓 更改的樣本 來自改變樣品的電壓
0000 1.00 0.00 8000 1.00
7FFF 2.00 1.00 FFFF 2.00
8000 0.00 1.00 0000 0.00
4000 1.50 0.50 C000 1.50
C000 0.50 1.50 4000 0.50

必須發(fā)生的第二個(gè)轉(zhuǎn)換是位翻轉(zhuǎn)操作。DS80C400上的串行端口首先寫入最低有效位,但MAX542期望數(shù)據(jù)最高有效位優(yōu)先。此操作是使用簡單的查找表執(zhí)行的。

數(shù)據(jù)以80字節(jié)塊的形式發(fā)送到DS400C1400 - 該尺寸可提供最佳性能。數(shù)據(jù)流控制是通過跟蹤上一秒內(nèi)發(fā)送的數(shù)據(jù)量并將其與每秒預(yù)期發(fā)送的數(shù)據(jù)量進(jìn)行比較來執(zhí)行的。例如,采樣率為22.05kHz的單聲道數(shù)據(jù)每秒將產(chǎn)生44,100字節(jié)。如果 SendDataTCP 程序在過去 44 毫秒內(nèi)發(fā)送了 500,800 字節(jié),它將休眠大約 200 毫秒。DS80C400使用超過400kB的緩沖器,相當(dāng)于幾秒鐘的音頻數(shù)據(jù)。因此,準(zhǔn)確的計(jì)時(shí)在SendDataTCP程序中很重要,但并不重要。一些變化是可以接受的。

請注意,SendDataTCP程序通常會(huì)盡可能快地發(fā)送數(shù)據(jù)。如果程序由于在最后一秒發(fā)送了太多數(shù)據(jù)而從未暫停,則可能是數(shù)據(jù)速率過高,應(yīng)用程序無法處理。這可能是網(wǎng)絡(luò)流量過多的結(jié)果。

DS80C400:初始化揚(yáng)聲器應(yīng)用

DS80C400的應(yīng)用完全用8051匯編編寫。請注意,也可以使用 Keil 的編譯器在 C 中實(shí)現(xiàn)應(yīng)用程序。2,或在 Java 中使用 TINI? 運(yùn)行時(shí)環(huán)境3.該應(yīng)用程序足夠小,因此在匯編中編寫它并不是一項(xiàng)艱巨的任務(wù)。

在可能的情況下,揚(yáng)聲器應(yīng)用程序利用了ROM中的功能未占用或更改的資源。DS80C400有4個(gè)數(shù)據(jù)指針,其中只有一個(gè)不作系統(tǒng)更改。前兩個(gè)數(shù)據(jù)指針被所有函數(shù)廣泛使用,尤其是對于復(fù)制操作。第四個(gè)數(shù)據(jù)指針在某些網(wǎng)絡(luò)例程中使用,但始終保留。從不使用第三個(gè)數(shù)據(jù)指針。由于驅(qū)動(dòng)揚(yáng)聲器的中斷需要是高優(yōu)先級中斷,因此第四個(gè)數(shù)據(jù)指針不適合使用,只剩下第三個(gè)數(shù)據(jù)指針可用。DS80C400還具有四個(gè)定時(shí)器。ROM 使用定時(shí)器 0 作為時(shí)鐘周期,使用定時(shí)器 2 作為串行端口輸出。這將計(jì)時(shí)器 1 和計(jì)時(shí)器 3 留給揚(yáng)聲器應(yīng)用程序。

揚(yáng)聲器應(yīng)用使用定時(shí)器3產(chǎn)生中斷,用于加載MAX542數(shù)模轉(zhuǎn)換器。選擇定時(shí)器 3 以在 16 位定時(shí)器模式下運(yùn)行。在 3 位模式下,計(jì)時(shí)器 16 沒有自動(dòng)重新加載,盡管硬件會(huì)自動(dòng)清除中斷位。定時(shí)器3中斷作為高優(yōu)先級運(yùn)行,因?yàn)榧虞dMAX542的時(shí)序?qū)σ纛l質(zhì)量至關(guān)重要。

在應(yīng)用啟動(dòng)之前,ROM已經(jīng)設(shè)置了DS80C400的一些特殊功能。該處理器已經(jīng)處于 24 位尋址模式,允許跨 64kB 邊界輕松訪問代碼和數(shù)據(jù)。擴(kuò)展堆棧也已啟用,利用DS80C400的專用1024字節(jié)堆??臻g。這留下了間接內(nèi)存空間可供應(yīng)用程序使用,而不必?fù)?dān)心堆棧使用會(huì)破壞其內(nèi)容。應(yīng)用啟動(dòng)后,時(shí)鐘四倍器使能,產(chǎn)生約54ns的單周期指令時(shí)間。接下來,初始化定時(shí)器3,這必須在ROM初始化和進(jìn)程交換開始之前完成。這是因?yàn)镽OM在進(jìn)程交換時(shí)保留了中斷啟用位。由于計(jì)時(shí)器中斷需要一直運(yùn)行,因此應(yīng)在啟用進(jìn)程本身之前啟用它。

為了完成系統(tǒng)的初始化,調(diào)用了許多ROM函數(shù)。調(diào)用的第一個(gè) ROM 函數(shù)是 rom_init,它初始化內(nèi)存管理器、進(jìn)程管理器和網(wǎng)絡(luò)堆棧。接下來設(shè)置網(wǎng)絡(luò)參數(shù),為DS80C400提供靜態(tài)IP地址。

系統(tǒng)現(xiàn)已初始化并準(zhǔn)備好創(chuàng)建偵聽套接字。網(wǎng)絡(luò)功能是傳統(tǒng)伯克利式套接字的組裝版本。應(yīng)用程序通過調(diào)用create_socket創(chuàng)建新的 TCP 套接字句柄,并通過調(diào)用bind_socket將其分配給端口號。該函數(shù)setup_listen將套接字設(shè)置為服務(wù)器套接字,accept_connection等待套接字連接。

在程序進(jìn)入主循環(huán)之前,讀取和寫入指針被初始化。傳入數(shù)據(jù)來自 網(wǎng)絡(luò)連接將寫入存儲(chǔ)在間接內(nèi)存區(qū)域中的 EndBuffer 指針,因?yàn)闆]有可免費(fèi)使用且跨進(jìn)程交換安全的直接。第三個(gè)數(shù)據(jù)指針用于從緩沖區(qū)讀取下一個(gè)有效樣本。此指針由計(jì)時(shí)器 3 的中斷服務(wù)例程 (ISR) 獨(dú)占使用。在 ISR 讀取示例數(shù)據(jù)之前,它會(huì)檢查它是否也在讀取 靠近 EndBuffer 指針。如果兩個(gè)指針位于同一組(相同的 64kB 內(nèi)存區(qū)域)中,則計(jì)時(shí)器 ISR 將簡單地退出而不播放音頻數(shù)據(jù)。這不僅可以防止 ISR 讀取緩沖區(qū)末尾以外的無效數(shù)據(jù),但也提供一定量的緩沖,以防應(yīng)用程序接收數(shù)據(jù)的速度不夠快。如果應(yīng)用程序停止播放音頻數(shù)據(jù),則在至少有 64,000 字節(jié)可用之前,它不會(huì)再次啟動(dòng)。這里的權(quán)衡是,如果應(yīng)用程序接收數(shù)據(jù)的速度不夠快,則可以聽到音頻中較長的間隙,但音頻是可識(shí)別的。

循環(huán):等待來自網(wǎng)絡(luò)的數(shù)據(jù)

在應(yīng)用程序的主循環(huán)開始等待數(shù)據(jù)之前,它會(huì)檢查 EndBuffer 指針以查看它是否已環(huán)繞在循環(huán)緩沖區(qū)的末尾,并在必要時(shí)調(diào)整指向循環(huán)緩沖區(qū)開頭的指針。然后,它調(diào)用 recv_data 函數(shù),該函數(shù)讀取任何可用數(shù)據(jù)或塊,直到數(shù)據(jù)可用。接收到的網(wǎng)絡(luò)數(shù)據(jù)直接讀入循環(huán)緩沖區(qū)。這可以防止應(yīng)用程序在recv_data函數(shù)返回后復(fù)制數(shù)據(jù)。如果 EndBuffer 指針靠近循環(huán)緩沖區(qū)的末尾,則 recv_data 函數(shù)僅請求足夠的數(shù)據(jù)到達(dá)緩沖區(qū)的末尾。這意味著應(yīng)用程序有時(shí)可能會(huì)請求接收少量數(shù)據(jù),但好處是應(yīng)用程序可以直接將數(shù)據(jù)讀取到循環(huán)緩沖區(qū)中,而無需中間副本。讀取后,將更新 EndBuffer 指針,控件返回到循環(huán)的頂部。

如果在讀取時(shí)發(fā)生錯(cuò)誤,應(yīng)用程序?qū)㈥P(guān)閉其套接字并等待另一個(gè)套接字連接。通常,檢測到的錯(cuò)誤實(shí)際上意味著主機(jī)關(guān)閉了發(fā)送套接字。這允許發(fā)送方隨時(shí)啟動(dòng)和停止主機(jī)程序,并依次播放多個(gè)WAV文件。

計(jì)時(shí)器中斷:播放音頻數(shù)據(jù)

在執(zhí)行任何任務(wù)之前,計(jì)時(shí)器 3 的中斷服務(wù)例程 (ISR) 必須重新加載計(jì)時(shí)器寄存器。計(jì)時(shí)器寄存器始終以相同的值重新加載。此重新加載值與音頻樣本的播放速率相關(guān)聯(lián)。較高的重新加載值(意味著計(jì)數(shù)器翻轉(zhuǎn)的時(shí)間越短)意味著更快的音頻樣本播放速度。較低的重新加載值意味著音頻樣本播放速度較慢。

重新加載計(jì)時(shí)器寄存器后,ISR 會(huì)檢查它讀取的數(shù)據(jù)是否太靠近 EndBuffer 指針。僅檢查銀行編號(指針的最高字節(jié))有兩個(gè)好處。在前面初始化揚(yáng)聲器應(yīng)用程序一節(jié)中已經(jīng)討論了一個(gè) - 當(dāng)應(yīng)用程序接收數(shù)據(jù)的速度不夠快時(shí),防止出現(xiàn)短而難以理解的音頻突發(fā)。另一個(gè)好處是可以更快地比較 ISR。ISR 每秒運(yùn)行數(shù)千次,因此從 ISR 切割周期非常重要。通過僅檢查高地址字節(jié),可以避免對中間和低地址字節(jié)進(jìn)行兩次額外的比較。

如果有可供播放的有效音頻數(shù)據(jù),則會(huì)讀取樣本,并將數(shù)據(jù)指針遞增到下一個(gè)樣本。數(shù)據(jù)加載到MAX542數(shù)模轉(zhuǎn)換器,首先將片選線設(shè)置為低電平,將2個(gè)字節(jié)加載到串行端口,將片選線設(shè)置為高電平,然后將負(fù)載DAC線脈沖至低電平。串行端口處理串行時(shí)鐘和數(shù)據(jù)線的正確切換。每次加載串行端口后都會(huì)插入幾個(gè)nop指令,允許硬件完成字節(jié)移出。最后,ISR 檢查讀取音頻數(shù)據(jù)的指針,以查看它是否已環(huán)繞在循環(huán)緩沖區(qū)的末尾,并在必要時(shí)進(jìn)行更正。

滴答聲:覆蓋系統(tǒng)計(jì)時(shí)器

為了以允許高質(zhì)量音頻播放的速率接收數(shù)據(jù),需要更改操作系統(tǒng)的計(jì)時(shí)器滴答功能。更改計(jì)時(shí)器時(shí)鐘周期將允許對 I/O 性能進(jìn)行更多控制。以下是DS80C400 ROM中運(yùn)行時(shí)的原始定時(shí)器滴答代碼:

IOPOLL_TICK_MS    equ    4

      WOS_Tick:
             ; The timer is running in divide by 12 mode.
             push    psw
             push    acc

             clr    tr0
             clr    tf0
             mov    a, sched_reload_lsb
             add    a, tl0
             mov    tl0, a
             mov    a, sched_reload_msb
             addc   a, th0
             mov    th0, a
             setb   tr0

             inc    ms_count_0
             mov    a, ms_count_0
             jnz    wos_tick_check_sched        ; Check for byte 0 roll.
             inc    ms_count_1
             mov    a, ms_count_1
             jnz    wos_tick_check_sched        ; Check for byte 1 roll.
             inc    ms_count_2
             mov    a, ms_count_2
             jnz    wos_tick_check_sched        ; Check for byte 2 roll.
             inc    ms_count_3
             mov    a, ms_count_3
             jnz    wos_tick_check_sched        ; Check for byte 3 roll.
             inc    ms_count_4                  ; If this wraps, we are in trouble

      wos_tick_check_sched:
             jb     need_sched, wos_tick_check_critical_section

             mov    a, ms_count_0               ; See if it's time to run the
             anl    a, #IOPOLL_TICK_MS-1        ;    scheduler/iopoll routines.
             jnz    wos_timer_reload            ; If not, don't do scheduler stuff.

      wos_tick_check_critical_section:
             clr    ea                          ; Make sure nobody interrupts
                                                ; us before we want to

             mov    a, STATUS                   ; Check for low priority interrupts
             jb     acc.5, wos_tick_low_priority_in_progress
                                                ; If low priority interrupts are being
                                                ; serviced, don't run the scheduler.
                                                ; If we don't do this, we'll start running
                                                ; the scheduler as a low priority interrupt.

             mov    a, wos_crit_count           ; Check the critical section count.
             jz     wos_tick_not_critical_section
                                                ; If we're not in a critical section,
                                                ; go ahead, jump and run the scheduler.

      wos_tick_low_priority_in_progress:
             setb   need_sched                  ; Signal to ourselves, or whoever, that
                                                ; we need to run the scheduler next time
             sjmp   wos_timer_reload            ; Going to blow off this tick.

      wos_tick_not_critical_section:
             WOS_ENTER_CRITICAL_SECTION
             pop    acc                         ; Clean up stack.
             pop    psw
             pop    curr_pc_x                   ; Return address to get out of interrupt.
             pop    curr_pc_h
             pop    curr_pc_l
             PUSH_DPTR1
             push   dps
             mov    dps, #0
             mov    dptr, #WOS_IOPoll           ; Get address of IOPoll
             mov    sched_l, dpl
             mov    sched_h, dph
             mov    sched_x, dpx
             pop    dps
             POP_DPTR1

             push   sched_l                     ; Push address of IOPoll
             push   sched_h
             push   sched_x
             reti                               ; Run IOPoll

      wos_timer_reload:
             ; Interrupts must have been on when the interrupt handler
             ; was called.
             setb   ea                          ; Enable interrupts
             pop    acc
             pop    psw
             reti
 

此即時(shí)報(bào)價(jià)函數(shù)最重要的更改是使用 1 而不是 4 的IOPOLL_TICK_MS值,并更改sched_reload_xxx值,以便即時(shí)報(bào)價(jià)函數(shù)更頻繁地運(yùn)行。請注意,通過使用IOPOLL_TICK_MS值 1,行anl a,#IOPOLL_TICK_MS-1的計(jì)算結(jié)果始終為 0,從而允許一些代碼和邏輯減少。此外,由于我們不擔(dān)心準(zhǔn)確的系統(tǒng)時(shí)鐘計(jì)時(shí),因此我們可以減少時(shí)鐘重新加載代碼。

一個(gè)復(fù)雜情況是通過覆蓋計(jì)時(shí)器滴答函數(shù)來引入的。揚(yáng)聲器代碼應(yīng)在DS80C400 ROM的任何未來版本上運(yùn)行,因此我們無法對WOS_IOPoll功能的地址進(jìn)行硬編碼。幸運(yùn)的是,WOS_IOPoll函數(shù)的地址在 ROM 導(dǎo)出表中。揚(yáng)聲器程序在啟動(dòng)時(shí)讀取此地址并將其存儲(chǔ)在間接內(nèi)存中,然后由計(jì)時(shí)器 tick 函數(shù)用于調(diào)用 WOS_IOPoll 函數(shù)。以下是針對揚(yáng)聲器應(yīng)用定制的定時(shí)器滴答功能:

 speaker_wos_tick:
             ; The timer is running in divide by 12 mode.
             push   psw
             push   acc

             ;
             ; We know what we want our timer reload to be.
             ; And our millisecond count doesn't have to be too
             ; accurate, so we can just straight load the
             ; timer registers.
             ;
             mov    tl0, #TICK_RELOAD_LOW       ; TICK_RELOAD_LOW  = 80h
             mov    th0, #TICK_RELOAD_HIGH      ; TICK_RELOAD_HIGH = FDh

             inc    ms_count_0
             mov    a, ms_count_0
             jnz    wos_tick_check_sched        ; Check for byte 0 roll.
             inc    ms_count_1
             mov    a, ms_count_1
             jnz    wos_tick_check_sched        ; Check for byte 1 roll.
             inc    ms_count_2
             mov    a, ms_count_2
             jnz    wos_tick_check_sched        ; Check for byte 2 roll.
             inc    ms_count_3
             mov    a, ms_count_3
             jnz    wos_tick_check_sched        ; Check for byte 3 roll.
             inc    ms_count_4                  ; If this wraps, we are in trouble

      wos_tick_check_sched:
             clr    ea                          ; Make sure nobody interrupts
                                                ; us before we want to
             mov    a, STATUS                   ; Check for low priority interrupts
             jb     acc.5, wos_tick_low_priority_in_progress
                                                ; If low priority interrupts are being
                                                ; serviced, don't run the scheduler.
                                                ; If we don't do this, we'll start running
                                                ; the scheduler as a low priority interrupt.
             mov    a, wos_crit_count           ; Check the critical section count.
             jz     wos_tick_not_critical_section
                                                ; If we're not in a critical section, go
                                                ; ahead, jump and run the scheduler.

      wos_tick_low_priority_in_progress:
             setb   need_sched                  ; Signal to ourselves, or whoever, that we
                                                ; need to run the scheduler next time
             sjmp   wos_timer_reload            ; Going to blow off this tick.

      wos_tick_not_critical_section:
             WOS_ENTER_CRITICAL_SECTION
             mov    psw, #0
             push   r0_b0
             mov    r0, #wos_iopoll_x
             mov    a, @r0                      ; xhigh byte of wos_iopoll address
             inc    r0
             mov    sched_x, a
             mov    a, @r0                      ; high byte of wos_iopoll address
             inc    r0
             mov    sched_h, a
             mov    a, @r0                      ; low byte of wos_iopoll address
             inc    r0
             mov    sched_l, a
             pop    r0_b0

             pop    acc                         ; Clean up stack.
             pop    psw

             pop    curr_pc_x                   ; Return address to get out of interrupt.
             pop    curr_pc_h
             pop    curr_pc_l

             push   sched_l                     ; Push address of IOPoll
             push   sched_h
             push   sched_x

             reti                               ; Run IOPoll

      wos_timer_reload:
             ; Interrupts must have been on when the interrupt handler
             ; was called.
             setb   ea                          ; Enable interrupts
             pop    acc
             pop    psw
             reti

通過實(shí)驗(yàn)測定了FD80h的定時(shí)器重載值。此重新加載值允許以每秒約 88,000 字節(jié)發(fā)送的音頻數(shù)據(jù)流暢播放,中斷最小,具體取決于其他網(wǎng)絡(luò)流量。這意味著以44.1kHz播放單聲道音頻數(shù)據(jù),或以22.05kHz播放立體聲音頻數(shù)據(jù)。

應(yīng)用:構(gòu)建和運(yùn)行

主機(jī)應(yīng)用程序是 Java 應(yīng)用程序,因此需要 Java 開發(fā)工具包來構(gòu)建和運(yùn)行它。在開發(fā)過程中使用了版本 1.3.1,但 SendDataTCP 程序中的代碼非常簡單,任何已發(fā)布的 Java 開發(fā)工具包版本都應(yīng)該足夠了。要構(gòu)建的命令行很簡單:

  javac SendDataTCP.java

若要運(yùn)行 SendDataTCP 程序,請使用如下所示的命令行: 在本例中,10.0.0.1 是偵聽端口 80 上的連接的 DS400C5555 的 IP 地址。WAV文件some_song.wav將用于將音頻樣本發(fā)送到DS80C400。請注意,假定使用的WAV文件包含44.1kHz立體聲數(shù)據(jù)樣本。有幾種工具可用于從 MP3 文件生成 WAV 文件。JavaLayer MP3套件中包含一個(gè)免費(fèi)工具

      java SendDataTCP 10.0.0.1 5555 some_song.wav

大多數(shù)(但不是全部)MP3 文件都包含 44.1kHz 立體聲數(shù)據(jù),因此請注意任何工具生成的 WAV 文件類型。

在DS80C400上運(yùn)行的揚(yáng)聲器應(yīng)用采用8051匯編編寫,需要TINI軟件開發(fā)套件中免費(fèi)提供的工具5.揚(yáng)聲器應(yīng)用程序是為地址為400000-47FFFF(十六進(jìn)制)具有閃存,在地址00000-7FFFF和60000-67FFFF(十六進(jìn)制)具有RAM的電路板開發(fā)的。圖 4 描述了該板的內(nèi)存配置。

poYBAGPy1NOAatGAAAB_ZWeRzmg903.gif?imgver=1


圖4.板內(nèi)存配置。

其他主板的開發(fā)人員需要記住,可能需要更改地址以匹配其主板配置。以下是用于創(chuàng)建揚(yáng)聲器應(yīng)用程序的生成腳本:

 macro speaker.a51
      a390 -l -Ftbin -d -p 390 speaker.mpp
      java fixBankNum speaker.tbin 66

工具宏和 a390 是 TINI SDK 的一部分。fixBankNum 程序是一個(gè)小型 Java 應(yīng)用程序,它更改了用于加載應(yīng)用程序的目標(biāo)內(nèi)存庫,并包含在達(dá)拉斯半導(dǎo)體 FTP 站點(diǎn)上本應(yīng)用筆記的源文件中6.請注意,“66”是十進(jìn)制的,因此speaker.tbin文件將針對位于閃存中的銀行 42(十六進(jìn)制)。

fixBankNum程序是必需的,因?yàn)閾P(yáng)聲器應(yīng)用程序不會(huì)耗盡閃存,但將程序存儲(chǔ)在閃存中是確保在DS80C400電源中斷時(shí)不會(huì)擦除程序的唯一方法。揚(yáng)聲器應(yīng)用程序不會(huì)用完閃存,因?yàn)闀r(shí)鐘翻了兩番,它超過了指定的閃存訪問時(shí)間。因此,將運(yùn)行一個(gè)小的初始化應(yīng)用程序,將揚(yáng)聲器應(yīng)用程序從閃存復(fù)制到RAM中。然后,控制跳轉(zhuǎn)到 RAM 中揚(yáng)聲器應(yīng)用程序的副本,然后啟用時(shí)鐘四倍器并開始正常運(yùn)行。此初始化應(yīng)用程序的源稱為 init.a51,也包含在本應(yīng)用筆記的源文件中。使用以下腳本生成初始化應(yīng)用程序:

 macro init.a51
      a390 -l -Ftbin -d -p 390 init.mpp

要運(yùn)行揚(yáng)聲器應(yīng)用,必須將初始化和揚(yáng)聲器文件加載到DS80C400上。這是使用JavaKit完成的,JavaKit是TINISDK中包含的另一個(gè)應(yīng)用程序。文檔Running_JavaKit.txt(也是 TINI SDK 的一部分)詳細(xì)介紹了如何運(yùn)行 JavaKit。上面的構(gòu)建腳本生成名為speaker.tbin和init.tbin的文件。使用 JavaKit 將這些文件加載到 DS80C400 中。文件應(yīng)加載到庫 41 和 42(十六進(jìn)制)中。要運(yùn)行揚(yáng)聲器應(yīng)用程序,請?jiān)?JavaKit 裝入器提示符處鍵入以下內(nèi)容: 初始化應(yīng)用程序應(yīng)將揚(yáng)聲器應(yīng)用程序復(fù)制到內(nèi)存,打印一些調(diào)試,并且揚(yáng)聲器應(yīng)用程序已啟動(dòng)。運(yùn)行 SendDataTCP 程序以發(fā)送音頻數(shù)據(jù)。經(jīng)過一兩秒鐘的音頻緩沖后,音樂應(yīng)該開始。 B41 X

應(yīng)用:更改程序參數(shù)

揚(yáng)聲器應(yīng)用程序和主機(jī)代碼支持以 44.1kHz、22.05kHz 或 11.025kHz 播放單聲道數(shù)據(jù)。選擇數(shù)據(jù)速率時(shí)要考慮的權(quán)衡是音頻質(zhì)量與網(wǎng)絡(luò)中斷。在低流量網(wǎng)絡(luò)上,應(yīng)用程序可能能夠以 44.1kHz 的頻率播放數(shù)據(jù)而不會(huì)中斷。在高流量網(wǎng)絡(luò)上,音頻中的可聽見的閃光點(diǎn)可能會(huì)變得明顯。請按照以下步驟更改采樣率:

1) 在文件揚(yáng)聲器頂部附近找到等效RELOAD_44_1_at_18.a51。對于 390.44kHz,將此值更改為 1,對于 800.22kHz,將此值更改為 05,對于 1600.11kHz,將此值更改為 025。
2) 在文件頂部附近找到變量 static int audio_quality SendDataTCP.java。將此值更改為MONO_44100、MONO_22050或MONO_11025。
3) 重新編譯并重建應(yīng)用的兩個(gè)部分,并在DS80C400上重新加載揚(yáng)聲器應(yīng)用。

數(shù)據(jù)存儲(chǔ)在音樂光盤上,以立體聲、44.1kHz 16 位樣本形式存儲(chǔ)。單聲道數(shù)據(jù)僅表示播放一個(gè)通道,而不是兩個(gè)通道。音樂的足夠質(zhì)量是22.05kHz;11.025kHz 足以滿足語音數(shù)據(jù)的需求。

揚(yáng)聲器應(yīng)用程序的 IP 地址和參數(shù)也是可配置的。在 speaker.a51 文件底部附近是以下聲明:

network_parameters:
    db  0, 0, 0                                                 ; 3 bytes overhead
    db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 1         ; ip address
    db  255, 255, 0, 0                                          ; subnet mask
    db  16                                                      ; ipv4 netmask len
    db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 2         ; gateway

該結(jié)構(gòu)的格式在DS80C400用戶指南中有描述。但是,請注意,揚(yáng)聲器應(yīng)用程序中使用的當(dāng)前 IP 地址為 10.0.0.1,當(dāng)前網(wǎng)關(guān)設(shè)置為 10.0.0.2。更改以使應(yīng)用程序使用不同的 IP 地址應(yīng)該是微不足道的。在源文件中稍低一點(diǎn),指定了服務(wù)器套接字的端口號:請注意,傳遞給 SendDataTCP 程序的端口號假定為十六進(jìn)制值。

address:
    db  0, 0, 0                                             ; overhead
    db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 1     ; address
    db  55h, 55h                                            ; port
    db  0                                                   ; family

未來:添加第二個(gè)頻道和其他改進(jìn)

可以對揚(yáng)聲器應(yīng)用程序進(jìn)行許多改進(jìn)和修改。組播UDP可以取代TCP,允許一臺(tái)服務(wù)器向多個(gè)DS80C400廣播消息。DHCP 可用于動(dòng)態(tài)獲取 IP 地址,從而允許自行配置安裝。配置字節(jié)可能會(huì)告訴揚(yáng)聲器應(yīng)用程序音頻質(zhì)量是多少,因此它可以輕松地動(dòng)態(tài)播放 11kHz、22kHz 或 44kHz 的音頻數(shù)據(jù)。控制從主機(jī)到DS80C400的數(shù)據(jù)流也有待改進(jìn)。

另一個(gè)關(guān)鍵的改進(jìn)是增加了另一個(gè)音頻通道,允許立體聲。這里的訣竅是確保添加另一個(gè)通道不會(huì)使計(jì)時(shí)器 3 中斷例程運(yùn)行太長。最好的解決方案可能是使用串行端口 0 輸出另一個(gè)音頻通道。應(yīng)用程序?qū)⑹ネㄟ^串行端口發(fā)送調(diào)試消息的能力,但計(jì)時(shí)器中斷的額外開銷將降至最低。

結(jié)論

DS80C400 是支持互聯(lián)網(wǎng)的揚(yáng)聲器的完美選擇。DS80C400的ROM使應(yīng)用能夠以傳輸原始音頻數(shù)據(jù)的速度通過網(wǎng)絡(luò)進(jìn)行通信。通過增加一個(gè)16位DAC、一些電阻和少量的焊接工作,DS80C400成為互聯(lián)網(wǎng)揚(yáng)聲器。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 芯片
    +關(guān)注

    關(guān)注

    455

    文章

    50851

    瀏覽量

    423981
  • 揚(yáng)聲器
    +關(guān)注

    關(guān)注

    29

    文章

    1304

    瀏覽量

    63053
  • 計(jì)時(shí)器
    +關(guān)注

    關(guān)注

    1

    文章

    420

    瀏覽量

    32722
收藏 人收藏

    評論

    相關(guān)推薦

    用IAR編譯開發(fā)DS80C400

    本應(yīng)用筆記闡述了如何開始使用8051 IAR Embedded Workbench?來創(chuàng)建DS80C400C語言應(yīng)用程序。通過一個(gè)簡單的HTTP服務(wù)演示如何使用DS80C400的R
    發(fā)表于 12-07 09:35 ?3076次閱讀
    用IAR編譯<b class='flag-5'>器</b>開發(fā)<b class='flag-5'>DS80C400</b>

    工業(yè)互聯(lián)網(wǎng)

    工業(yè)互聯(lián)網(wǎng)是全球工業(yè)系統(tǒng)與高級計(jì)算、分析、感應(yīng)技術(shù)以及互聯(lián)網(wǎng)連接融合的結(jié)果。它通過智能機(jī)器 間的連接并最終將人機(jī)連接,結(jié)合軟件和大數(shù)據(jù)分析,重構(gòu)全球工業(yè)、激發(fā)生產(chǎn)力,讓世界更美好、更快速、更安全、更
    發(fā)表于 01-25 09:29

    怎樣在80C51單片機(jī)中寫揚(yáng)聲器報(bào)警程序

    怎樣在80C51單片機(jī)中寫揚(yáng)聲器報(bào)警程序
    發(fā)表于 04-14 21:31

    工業(yè)互聯(lián)網(wǎng)

    斷發(fā)展。伴隨著這樣的發(fā)展,三種元素逐漸融合,充分體現(xiàn)出工業(yè)互聯(lián)網(wǎng)之精髓:智能機(jī)器:以嶄新的方法將現(xiàn)實(shí)世界中的機(jī)器、設(shè)備、團(tuán)隊(duì)和網(wǎng)絡(luò)通過先進(jìn)的傳感、控制軟件應(yīng)用程序連接起來。高級分
    發(fā)表于 04-17 15:56

    什么是產(chǎn)業(yè)互聯(lián)網(wǎng)?

    2018年10月,騰訊宣傳進(jìn)軍產(chǎn)業(yè)互聯(lián)網(wǎng);2019年9月,騰訊完成了史上最大的組織架構(gòu)調(diào)整,新成立云與智慧產(chǎn)業(yè)事業(yè)群,正式發(fā)力產(chǎn)業(yè)互聯(lián)網(wǎng);2020年1月,騰訊發(fā)布《2020產(chǎn)業(yè)安全報(bào)告:產(chǎn)業(yè)互聯(lián)網(wǎng)
    發(fā)表于 01-18 11:40

    如何在音視頻范例網(wǎng)絡(luò)多媒體系統(tǒng)中應(yīng)用DS80C400網(wǎng)絡(luò)型微控制?

    本文對如何在音視頻范例網(wǎng)絡(luò)多媒體系統(tǒng)中應(yīng)用DS80C400網(wǎng)絡(luò)型微控制進(jìn)行分析與討論。
    發(fā)表于 06-02 06:24

    DS80C400評估板中文資料pdf

    DS80C400評估板
    發(fā)表于 04-15 17:42 ?50次下載

    采用DS80C400創(chuàng)建網(wǎng)絡(luò)多媒體應(yīng)用

    采用DS80C400建立網(wǎng)絡(luò)多媒體應(yīng)用令人振奮的多媒體應(yīng)用——包括有線廣播(PA)系統(tǒng)、網(wǎng)絡(luò)門、MP3播放以及安全攝像機(jī)等——可以采用一種低成本的網(wǎng)絡(luò)型微處理
    發(fā)表于 07-21 00:47 ?16次下載

    DS80C400在嵌入式智能網(wǎng)橋中的應(yīng)用

    文章提出了以DS80C400 為核心處理將多路CAN 網(wǎng)絡(luò)與多路以太網(wǎng)互連的嵌入式智能網(wǎng)橋?qū)崿F(xiàn)方案。給出了 DS80C400 MII 與外部物理設(shè)備之間的連接,詳細(xì)闡述JAVAKIT 在WINDOWS 開發(fā)平臺(tái)下的
    發(fā)表于 06-03 08:51 ?7次下載

    采用DS80C400建立網(wǎng)絡(luò)多媒體應(yīng)用

    令人振奮的多媒體應(yīng)用——包括有線廣播(PA)系統(tǒng)、網(wǎng)絡(luò)門、MP3播放以及安全攝像機(jī)等可以采用一種低成本的網(wǎng)絡(luò)型微處理建立。本文將討論如何在音視頻范例系統(tǒng)中應(yīng)用DS80C40
    發(fā)表于 12-09 15:11 ?8次下載

    用Keil MON390編程TINIm400

    在設(shè)計(jì) DS80C400軟件時(shí)就決定公開一套組合功能可以由C 語言編程者來訪問在一些程序庫的幫助下C語言編程者可以訪問網(wǎng)絡(luò)堆棧過程管理
    發(fā)表于 12-10 16:03 ?29次下載

    基于DS80C400微控制實(shí)現(xiàn)音視頻范例網(wǎng)絡(luò)多媒體系統(tǒng)的設(shè)計(jì)

    新型DS80C400是具有高性能結(jié)構(gòu)和多層網(wǎng)絡(luò)節(jié)點(diǎn)和I/O口及穩(wěn)定的ROM固件的網(wǎng)絡(luò)微控制,它廣泛應(yīng)用于工業(yè)控制/自動(dòng)化、數(shù)據(jù)轉(zhuǎn)換、遠(yuǎn)距離數(shù)據(jù)采集設(shè)備、環(huán)境監(jiān)測、家庭/辦公室自動(dòng)化、交易/支付
    的頭像 發(fā)表于 06-23 15:38 ?2514次閱讀
    基于<b class='flag-5'>DS80C400</b>微控制<b class='flag-5'>器</b>實(shí)現(xiàn)音視頻范例網(wǎng)絡(luò)多媒體系統(tǒng)的設(shè)計(jì)

    利用DS16C32/DS80C390加速80/400位數(shù)學(xué)運(yùn)算

    Maxim DS80C390/DS80C400高速微控制為最終用戶提供專用的硬件16/32位數(shù)學(xué)加速。訪問數(shù)學(xué)加速是通過使用五個(gè)專用的
    的頭像 發(fā)表于 02-21 10:36 ?1217次閱讀
    利用<b class='flag-5'>DS16C</b>32/<b class='flag-5'>DS80C</b>390加速<b class='flag-5'>80</b>/<b class='flag-5'>400</b>位數(shù)學(xué)運(yùn)算

    采用DS80C400芯片軟件互聯(lián)網(wǎng)揚(yáng)聲器

    DS80C400 是支持互聯(lián)網(wǎng)揚(yáng)聲器的完美選擇。DS80C400的ROM使應(yīng)用能夠以傳輸原始音頻數(shù)據(jù)的速度通過網(wǎng)絡(luò)進(jìn)行通信。通過增加一個(gè)16位DAC、一些電阻和少量的焊接工作,
    的頭像 發(fā)表于 06-13 15:41 ?614次閱讀
    <b class='flag-5'>采用</b><b class='flag-5'>DS80C400</b><b class='flag-5'>芯片</b><b class='flag-5'>軟件</b>的<b class='flag-5'>互聯(lián)網(wǎng)</b><b class='flag-5'>揚(yáng)聲器</b>

    DS80C400應(yīng)用中使用SDCC編譯

    DS80C400包含一個(gè)提供網(wǎng)絡(luò)棧、內(nèi)存管理和進(jìn)程調(diào)度的ROM,可以靈活地用于由Java、C和8051匯編編程的應(yīng)用中。SDCC為8051器件提供了一個(gè)免費(fèi)、開放源碼的編譯,并兼容DS80C
    的頭像 發(fā)表于 06-16 17:32 ?1368次閱讀
    在<b class='flag-5'>DS80C400</b>應(yīng)用中使用SDCC編譯<b class='flag-5'>器</b>