日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

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

電子實訓課程實驗項目

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

【前言】

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

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

【實驗目的與要求】

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

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

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

【設計概要】

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

上位機:

?? 案例的上位機是用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個數據位,1個停止位,并設置以二進制方式撿取數據,清空緩沖區(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函數,將display中的音節(jié)在蜂鳴器中播放。

測試方法:

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

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

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

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

(5)測試完成;

?

【實驗原理】

1、實驗原理圖

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

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

(2)芯片相關引腳圖

?

(3)單片機下載電路

?

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

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ā)數據相關*/

uchardisplay;??????????????????????????? //單片機上SBUF緩沖的數據

ucharflag;

intcount=0;????????????????????????????? //計數器,用來分頻

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

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

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

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

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

//低八度

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數組中的基址為0

??? qudiao=0;

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

?????? qudiao=14;

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

?

?????? qudiao=28;

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

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

}

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

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

功能描述:延時

入口參數:xms:輸入需要延時的毫秒值

出口參數:無

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

voiddelay(uint xms)

{

??? uint i;

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

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

?????? {}

}???

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

函數名稱:Timer0

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

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

voidTimer0() interrupt 1?? ?

{

??? count++;

??? if (count==4)

??? {

?????? count=0;

??? }

??? TH0=timeh;

??? TL0=timel;

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

??? {

??? ?beep=~beep;

??? }

}

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

函數名稱: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;????? ?????????????????????????????? //總中斷允許位

}

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

函數名稱: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;???????????????? ?????????? //初始化數據緩沖器

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

}

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

函數名稱:void playmusic()

功能描述:播放音樂

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

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

{

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

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

??? 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)??????? ?????????????????????????? //接受完數據以后,RI自動轉1

??? {

?????? flag=1;

?????? RI=0;

?????? display=SBUF;

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

?????? playmusic(display);

??? }

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

??? //{

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

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

??? //}

}

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

主函數

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

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個數據位,1個停止位? ?m_ctrlComm.SetInputMode(1); //1:表示以二進制方式檢取數據?

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

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

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

設置串口屬性

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

??? if(flag==3)

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

??? else if(flag==2)

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

??? else if(flag==1)

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

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

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

【實驗心得】

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

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

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

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

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統 散熱

根據LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統,而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉