當前位置:首頁 > 芯聞號 > 充電吧
[導讀]電子實訓課程實驗項目????????????????????? --電子琴【前言】?????? 為進一步激發(fā)學生對于硬件編程的興趣而開展的課程“電子實訓”課程到目前為止已經要告一段落了。將近四周的時間

電子實訓課程實驗項目

????????????????????? --電子琴

【前言】

?????? 為進一步激發(fā)學生對于硬件編程的興趣而開展的課程“電子實訓”課程到目前為止已經要告一段落了。將近四周的時間,從電路板印刷、貼片參觀,到自己親手將原件焊接到電路板上,再到一步一步熟悉STC編程當中的技巧,我們漸漸對硬件編程有了初步的認識,雖然并不一定能完成什么高級的設計,但是對目前所涉及到的數(shù)碼管、LED、撥碼開關、中斷、定時器、傳感器的應用已經有了初步認識,也可以寫出一些簡單的應用。為驗證十幾天的學習成果,每個人都會根據(jù)給出的53個例程當中選擇自己比較熟悉或者擅長的方面進行一個創(chuàng)新設計或者擴展設計,也或者融合多個方面。

?? 我完成的項目是一個“電子琴”,基于工程“電子音樂”改編而來,不過也做出了很多的改變,也增加了一些東西,使得整個項目看起來還算不錯。

【實驗目的與要求】

1、???熟練掌握定時器的應用,以及如何通過定時器驅動蜂鳴器發(fā)出一定頻率的聲音,掌握簡譜與定時器重裝值之間的關系,能夠實現(xiàn)蜂鳴器譜樂;

2、???熟悉下位機編程,usb轉串口原理應用,相關寄存器的使用,并且實現(xiàn)該功能,為上、下位機通信奠定基礎;

3、???熟悉上位機編程方法,可以參考相關資料,設計并實現(xiàn)上位機;

【設計概要】

本案例的設計主要可以分為兩個部分,上位機部分的設計和下位機部分的設計

上位機:

?? 案例的上位機是用MFC以及MFC中的串口控件來完成的。上位機中共有8個按鍵,一個下拉框,三個復選框,七個按鍵完成對音符頻率的選擇,對應簡譜中的DO,RE,MI,FA,SO,LA,XI,每當一個按鍵被按下的時候,上位機會通過串口將一個字節(jié)發(fā)送到單片機,在發(fā)送的時候,上位機會檢測被選中的復選框,若選中的是“低八度”,則會發(fā)送低八度對應的音節(jié);若選中的是“中八度”,則會發(fā)送中八度對應的音節(jié),高八度也類似。下拉框控制的是串口號的選擇,列出了電腦主機所配置的串口號,串口號下面有一個“打開窗口”的按鈕,當點擊的時候,上位機會檢測下拉框中選擇的串口號,并將其對應的串口號打開。在點擊的同時,上位機會設置串口的相關屬性值,m_ctrlComm.SetSettings("9600,n,8,1");設置串口波特率為9600,無校驗位,8個數(shù)據(jù)位,1個停止位,并設置以二進制方式撿取數(shù)據(jù),清空緩沖區(qū)。

下位機:

? 下位機設計的重要部分在于串口和蜂鳴器兩個部分。串口部分使用的是串口1中斷,串口1中斷使用TH1和TL1作為串口中斷的計時器,使用TL1=(65536-(Machine_Focs/4/BAUD1));TH1=(65536-(Machine_Focs/4/BAUD1))>>8作為重裝值,當串口發(fā)生中斷的時候,會觸發(fā)中斷處理程序。中斷處理程序中會將已經轉換成1的RI端口和TI端口轉換成0,返回源程序,開始下一次中斷的歷程,并且會觸發(fā)playmusic函數(shù),將display中的音節(jié)在蜂鳴器中播放。

測試方法:

(1)打開“piano”工程文件,找到“hex”文件;

(2)打開ISP下載器,選中該“hex文件”,選中對應的端口,點擊下載;

(3)下載完成,打開上位機“test.exe”,選中對應的端口,點擊“打開串口”;

(4)串口打開,選中對應的音階,低八度,中八度,或者高八度,然后點擊按鈕,蜂鳴器發(fā)出聲音;

(5)測試完成;

?

【實驗原理】

1、實驗原理圖

(1)無源蜂鳴器電路原理圖

?????????????????????????????

(2)芯片相關引腳圖

?

(3)單片機下載電路

?

2、USB轉串口原理:單片機集成了USB轉串口模塊,對應使用RXD線接收數(shù)據(jù),用TXD發(fā)送數(shù)據(jù)。每個串口由2個數(shù)據(jù)緩沖器(相互獨立1收1發(fā))、一個移位寄存器(一字節(jié)數(shù)據(jù)一位一位發(fā)送出去)、一個串行控制器和一個波特率發(fā)生器(這個比較重要,結合相關的定時器)組成。對應發(fā)送、接收數(shù)據(jù)完成(RI、TI硬件置1)都會觸發(fā)串口中斷,但是無法確定是哪個觸發(fā)的,所以在串口中斷中我們要判斷是接收數(shù)據(jù)產生的中斷還是發(fā)送數(shù)據(jù)產生的中斷,對于發(fā)送數(shù)據(jù)產生的中斷,我們要軟件將TI清0,并將數(shù)據(jù)就緒標志清0,允許下一字節(jié)數(shù)據(jù)發(fā)送,發(fā)送數(shù)據(jù)函數(shù)中通過while循環(huán),等待發(fā)送數(shù)據(jù)準備就緒,完了將就緒的數(shù)據(jù)復制給SBUF;對于接收數(shù)據(jù)產生的中斷,我們要軟件將RI清0,并從SBUF中讀取數(shù)據(jù)。

3、蜂鳴器原理:

本實驗板采用的是無源蜂鳴器,無源內部不帶震蕩源,所以如果用直流信號無法令其鳴叫。必須用2K~5K的方波去驅動它。相比與有源蜂鳴器,無源蜂鳴器的優(yōu)點在于價格便宜,可以通過控制其振動頻率來改變發(fā)出的聲音,做出“多來米發(fā)索拉西”的效果。因此,無源蜂鳴器可以用于音樂的播放。而有源蜂鳴器的優(yōu)點在于使用簡單,不需要編寫“樂譜”。本實驗板使用的無源蜂鳴器是電磁式蜂鳴器,電磁式蜂鳴器由振蕩器、電磁線圈、磁鐵、振動膜片及外殼等組成。接通電源后,接收到的音頻信號電流通過電磁線圈,使電磁線圈產生磁場。振動膜片在電磁線圈和磁鐵的相互作用下,周期性地振動發(fā)聲。

蜂鳴器部分每個音符都有自己對應的頻率,每個頻率也多有自己對應的簡譜碼,每一個簡譜碼都對應了一個計時器重裝值,比如說低1DO頻率是262Hz,則振動周期T=1000ms/262Hz=3.817ms,要求定時器在3.817ms會產生一個周期振動,由于一個周期振動是兩次電平變化,而每一次定時器中斷只有一次電平變化,所以要將定時器設置成1.908ms震動一次,也就是1908us,因此可以得到定時器重裝值為65536-1908=63628。

?

【源碼展示與說明】

下位機部分:

/*文件名稱piano.c

通過串口用上位機控制單片機上面的蜂鳴器發(fā)出不同頻率的聲音

*/

#include"STC15F2K60S2.H"

//宏定義

#defineuchar unsigned char

#defineuint unsigned int

?

#defineMachine_Focs 11059200L? ?????????? //晶振頻率 11.0592MHz

#defineBAUD1 9600??????????????????????? //波特率,這里使用的是9600

?

sbitLED_SEL=P2^3;

sbitbeep=P3^4;????????? ? ??????????????? //蜂鳴器引腳

uchartimeh,timel;?????? ? ??????????????? //定時器的重裝值

?

/*收發(fā)數(shù)據(jù)相關*/

uchardisplay;??????????????????????????? //單片機上SBUF緩沖的數(shù)據(jù)

ucharflag;

intcount=0;????????????????????????????? //計數(shù)器,用來分頻

ucharduanxuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,

0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

????????????????????????????????????????? //段選信號,選擇0-f

/*蜂鳴器振動頻率相關*/

ucharcode quzi[] ={ ? ??????????? ?????? //此數(shù)組作為各個音符在定時器中的重裝值

//低八度

0xf8,0x8c,0xf9,0x5b,0xfa,0x15,0xfa,0x67,0xfb,0x04,0xfb,0x90,0xfc,0x0c,

//中八度

0xfc,0x44,0xfc,0xac,0xfd,0x09,0xfd,0x34,0xfd,0x82,0xfd,0xc8,0xfe,0x06,

//高八度

0xfe,0x22,0xfe,0x56,0xfe,0x6e,0xfe,0x9a,0xfe,0xc1,0xfe,0xe4,0xff,0x03

};

/***************************************************************

曲調

****************************************************************/

ucharquyin(uchar tem)

{

??? uchar qudiao,jp,weizhi;???? ? //定義曲調,音符,位置

??? qudiao=tem/16;????????????? ? //高四位為是曲調值

??? jp=tem%16;?????????????? ? ???//低四位是音符

??? if(qudiao==1)??????????? ? ???//當曲調值為1的時候,低八度,低八度在quzi數(shù)組中的基址為0

??? qudiao=0;

??? else if(qudiao==2)????????? ? //當曲調值為2的時候,中八度,中八度在quzi數(shù)組中的基址為14

?????? qudiao=14;

??? else if(qudiao==3)????????? ? //當曲調值為3的時候,高八度,高八度在quzi數(shù)組中的基址為28

?

?????? qudiao=28;

??? weizhi=qudiao+(jp-1)*2;???? ? //基址加上偏移量得到音符對應數(shù)組中的位置

??? return weizhi;????????????? ? //返回位置值

}

/**********************

函數(shù)名稱:void delay(unsigned int xms)

功能描述:延時

入口參數(shù):xms:輸入需要延時的毫秒值

出口參數(shù):無

***********************/

voiddelay(uint xms)

{

??? uint i;

??? for(; xms>0; xms--)???????????????????

?????? for(i=114; i>0; i--)

?????? {}

}???

/**********************

函數(shù)名稱:Timer0

功能描述:定時器0的中斷響應函數(shù),用來控制蜂鳴器

***********************/

voidTimer0() interrupt 1?? ?

{

??? count++;

??? if (count==4)

??? {

?????? count=0;

??? }

??? TH0=timeh;

??? TL0=timel;

??? if(flag==1&&count==3)????????????? //四分頻

??? {

??? ?beep=~beep;

??? }

}

/**************************************************************

函數(shù)名稱:Uart1_Init

功能描述:初始化串口中斷

***************************************************************/

voidUart1_Init(void)

{

??? AUXR=0X80;??????????????????????????????? //輔助寄存器,使T0x12=1,此時不分頻

??? SCON|=0X50; ????????????????????????????? //SM0=0,SM1=1,串口以方式1工作,8位Uart,串行口1用定時器1作為其波特率發(fā)生器且定時器1工作于模式0;REN=1,開啟串口接收

??? TL1=(65536-(Machine_Focs/4/BAUD1));

??? TH1=(65536-(Machine_Focs/4/BAUD1))>>8;

??? AUXR|=0X40;?????????????????????????????? //使T0x12=1,此時不分頻

??? RI=0;????? ?????????????????????????????? //接收終端標志位

??? TI=0;????? ?????????????????????????????? //發(fā)送中斷標志位

??? TR1=1;???? ?????????????????????????????? //啟動的定時器1

??? ES=1;????? ?????????????????????????????? //串口中斷允許位

??? EA=1;????? ?????????????????????????????? //總中斷允許位

}

/**************************************************************

函數(shù)名稱:Init

功能描述:完成各部分功能模塊的初始化

***************************************************************/

voidInit()?????????????????????????????????? //初始化操作

{

??? P3M0=0x00;??????????????????????????????? //推挽模式

??? P3M1=0x00;

??? P2M0=0xff;

? ? P2M1=0x00;

? ? P0M0=0xff;

? ? P0M1=0x00;

??? TMOD=0x01;??????????????????????????????? //定時器0,方式1,要求每一次中斷之后手動重裝

??? ET0=1;??????????????????????????????????? //開啟定時器0中斷

??? EA=1;??????????????????????????????????? //開啟總中斷

??? TH0=0x00;

??? TL0=0x00;

??? TR0=1;???? ??????????????????????????????? //啟動定時器0

??? beep=0;?????????????????????????????????? //蜂鳴器初始化0

??? flag=0;

??? P0=0;

??? Uart1_Init();???????????????????????????? //串口中斷

??? display = 0x00;???????????????? ?????????? //初始化數(shù)據(jù)緩沖器

??? LED_SEL=0;??????????????????????????????? //設置數(shù)碼管顯示狀態(tài)

}

/**********************

函數(shù)名稱:void playmusic()

功能描述:播放音樂

***********************/

voidplaymusic(uchar p)?????????????????????? //p為音節(jié)

{

??? uchar tem;?????????????????????????????? ???

??? tem=quyin(p);???? ???????????????????????? //找到p音節(jié)在quzi數(shù)組中的位置

??? timeh=quzi[tem];? ?????? ????????????????? //音節(jié)重裝值的高八位

??? timel=quzi[tem+1];??????????????????????? //音節(jié)重裝值的低八位

??? TR0=1;???????????? ???????????????????????//開啟定時器0中斷

??? delay(0x10*180);??????????? ?????????? ???//延時一個節(jié)拍?

??? TR0=0;??????????????????????????????????? //關閉定時器0中斷

}

/*************************************************************

串口1中斷相應程序

**************************************************************/

voidUart1_fun() interrupt 4

{

??? if(RI)??????? ?????????????????????????? //接受完數(shù)據(jù)以后,RI自動轉1

??? {

?????? flag=1;

?????? RI=0;

?????? display=SBUF;

?????? //TR0=1;

?????? playmusic(display);

??? }

??? //if(TI)????? ??? ??????????????????????? //接受完數(shù)據(jù)以后,RI自動轉1

??? //{

?????? //TI=0;

?????? //Uart1_Sendbusy=0;

??? //}

}

/**************************************************************

主函數(shù)

***************************************************************/

voidmain()?????????????????????????????????????

{

??? Init();???

??? while(1){}??????????????????????????????? //執(zhí)行死循環(huán)

}

?

上位機部分:

int nIndex =m_chuankou_select.GetCurSel();

CString strCBText;

m_chuankou_select.GetLBText(nIndex,strCBText);

用來控制從下拉框m_chuankou_select中獲得已經選擇的串口號,并且將其存儲在字符串strCBText中;

if(strCBText=="")

?????? AfxMessageBox("請選擇串口");

??? else if(strCBText=="com1")

?????? m_ctrlComm.SetCommPort(1);

??? else if(strCBText=="com2")

?????? m_ctrlComm.SetCommPort(2);

。。。。。。

用來打開strCBText對應的串口號

m_ctrlComm.SetSettings("9600,n,8,1");//波特率9600,無校驗,8個數(shù)據(jù)位,1個停止位? ?m_ctrlComm.SetInputMode(1); //1:表示以二進制方式檢取數(shù)據(jù)?

m_ctrlComm.SetRThreshold(1);//參數(shù)1表示每當串口接收緩沖區(qū)中有多于或等于1個字符時將引發(fā)一個接收數(shù)據(jù)的OnComm事件?

m_ctrlComm.SetInputLen(0);//設置當前接收區(qū)數(shù)據(jù)長度為0?

m_ctrlComm.GetInput();//先預讀緩沖區(qū)以清除殘留數(shù)據(jù)?

設置串口屬性

UpdateData(TRUE); //讀取編輯框內容

??? if(flag==3)

?????? m_ctrlComm.SetOutput(COleVariant((CString)0x31));//發(fā)送數(shù)據(jù)

??? else if(flag==2)

?????? m_ctrlComm.SetOutput(COleVariant((CString)0x21));//發(fā)送數(shù)據(jù)

??? else if(flag==1)

?????? m_ctrlComm.SetOutput(COleVariant((CString)0x11));//發(fā)送數(shù)據(jù)

??? else

?????? AfxMessageBox("請選擇一個音階");?

控制發(fā)送高中低八度的DO,其他音節(jié)類似

CStringstr[]={"com1","com2","com3","com4","com5","com6","com7","com8","com9"};

??? ((CComboBox*)GetDlgItem(IDC_chuankou_select))->ResetContent();

??? CString defaultstr=str[0];

??? SetDlgItemText(IDC_chuankou_select,defaultstr);

??? for(int i=1;i

??? {

?????? ((CComboBox*)GetDlgItem(IDC_chuankou_select))->AddString(str[i]);

??? }

填充下拉框

【實驗總結】

1、???接收中斷自動置1的問題:在串口傳輸?shù)倪^程當中,使用RXD接收上位機傳過來的數(shù)據(jù),使用TXD傳出數(shù)據(jù),每當數(shù)據(jù)發(fā)送完成,TI會自動置位為1,請求接收中斷處理;每當數(shù)據(jù)接收完成,RI會自動置位為1,請求發(fā)送中斷處理,由于TI和RI以“或”邏輯關系向主機請求中斷,所以主機響應中斷時事先并不知道是TI還是RI請求的中斷,必須在中斷服務程序中查詢TI和RI進行判別,然后分別處理,因此,兩個中斷請求標志位均不能由硬件自動置位,必須通過軟件置零,否則將出現(xiàn)一次請求多次向英的錯誤。這里采用的是在中斷處理程序中進行軟件置位,也就是每一次中斷結束時檢測中斷的類型,進而對對應的中斷標志位進行置位。

2、???音節(jié)的節(jié)拍的完成:即控制某一頻率的震動在某一指定時間內完成。這一功能是通過控制定時器0的開關實現(xiàn)的,即當單片機接收到串口數(shù)據(jù)時,會執(zhí)行playmusic函數(shù),在默認情況下,定時器0開關TR0=0是關閉狀態(tài),執(zhí)行playmusic的同時,打開定時器開關TR0=1,中間延時0x10*180ms一個節(jié)拍,延時結束后將定時器控制TR0置0,等待下一次輸入。由于在之前的“電子音樂”工程當中是用數(shù)組存儲音節(jié)和節(jié)拍的,每兩個字節(jié)決定一個音階和一個節(jié)拍,在串口中一次只能傳輸一個字節(jié),所以如果要實現(xiàn)節(jié)拍功能就會給用戶帶來很多不便,所以在這里舍去了節(jié)拍的選擇,轉而采用固定的一個節(jié)拍。

【實驗心得】

1、???單片機使用c語言進行編程,這樣給嵌入式開發(fā)者帶來了很大的方便,畢竟我們最初接觸到的語言就是c語言,不過和之前的c語言編程相對比,現(xiàn)在編程語句結構相對分散或者說是獨立而不像之前的編程當中體現(xiàn)的非常強的邏輯,但是由于新加入的中斷定時器等會再各個結構之間產生影響,仍然需要非常注意,特別是對于中斷概念的理解,可以參考“深入理解計算機系統(tǒng)”這本書;

2、???要多編程,了解各個引腳,寄存器的用法、功能。雖說我們做硬件編程的時候可以隨時查找數(shù)據(jù)手冊尋找需要的知識,但是如果能記住這些寄存器、引腳的分布、用法,無疑會給硬件編程帶來非常大的方便,這就要求我們多編程,才能比較好的掌握;

3、???stc硬件編程入門很容易,也就是說很容易便可以掌握stc板的一些基本用法,像是數(shù)碼管、led、定時器等等,但是要編出比較強大好用的硬件程序,就必須多去了解各種中斷用法、編程技巧等,并且這些知識經驗只能靠自己在編程的過程中發(fā)現(xiàn),不是任何老師可以教授的,所以,學習單片機,要親力親為。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉