所有資料打包下載:
http://www.zg4o1577.cn/bbs/dpj-57024-1.html
下面是部分內容預覽:
隨著控制理論和電子技術的發展,控制芯片的發展可謂速度迅猛。從當初風靡業界的51單片機,到如今dsp、fpga、arm等等的百花齊放,這無不印證的控制處理器芯片發展的強大動力。而stm32芯片(st:意法半導體公司;m:cortex-m系列芯片;32:32位芯片)由于其具有優秀的運算速度和豐富的芯片資源以及低廉的價格(低至1美元)已經漸漸取代單片機。
Stm32對比起單片機,不僅僅運算速度幾十倍之差,而且對于其豐富的內部資源(例如一般STM均集成多路ADC、DAC、DMA、多路IIC、多路UART、SPI等等眾多功能)單片機是無法匹敵的。而且stm芯片已經越來越接近單片機價格。眾多優秀的表現可以看出stm32將取代單片機。 本次作品的原理是通過以STM32芯片作為主控芯片,通過利用STM32芯片自帶的AD功能實時識別信號源的電壓,并且以一定的采樣周期采樣電壓數據,并按照隊列方式儲存芯片當中。再通過4.2英寸的顯示屏把波形實時地顯示出來。即可完成功能的實現。
引 言 由于傳統示波器雖然功能齊全但是體積旁大,不方便攜帶,本設計針對這種缺點設計一種體積小、成本低、功耗小、便攜數字示波器,同時達到學以致用,理論和實踐相結合,進一步學習課外知識,培養綜合應用知識,鍛煉動手和實際工作的能力。示波器實現輸入頻率范圍為20HZ—1KHZ,幅度范圍為0V—+3.26V(由于時間和元件關系只能做到這一量程,換上帶有vref-和vref+的stm芯片即可做出正負電壓檢測的功能),實現波形實時顯示以及幅度測量。示波器在電子、電氣、控制等領域應用十分廣泛,隨著計算機的發展,示波器已經實現了和計算機互聯,共享數據,但現有示波器有諸多不足,體積龐大,價格昂貴,功能齊全的示波器在某些場合并不能得到充分的應用。本課題所研究的示波器定位于抵擋型,即在性能上滿足大多場合的需要,努力實現小型化,價格低廉,攜帶方便,這樣在財力有限的小用戶能夠普及,并和功能齊全高檔示波器配合使用,取長補短。本設計的硬件設計簡潔,結構明了,而且體積細小,非常方便攜帶。而且電池采用可充電大容量鎳鎘電池,可使用時間長。本設計對信號的采樣,使用實時采樣方式和有限的數據隊列儲存方式存儲,這種方法的優點是,設計相對簡單,能實時顯示所測信號的波形。缺點是,由于受AD轉換速率的限制不能測量頻率很高的信號。另外,AD只能測量范圍很小的電壓信號,單輸入信號可能更小,或者更大,所以要對信號進行程控放大和衰減。由于本設計時間和元件有限,只能做出檢測0到3.26v的示數。只要在信號輸入處加上加法電路改變量程或者把stm32f103c8t6芯片換成stm32f103vct6(帶vref+和vref-)即可。
第一章 系統整體概述 從任務的要求分析,主要包括的內容為電壓的實時測量和采集,通過stm32f103c8t6控制,運用算法描繪成連續曲線,在4.2英寸液晶顯示屏上顯示出來。 整體設計思路:stm32的PA0~PA7與4.2英寸液晶屏的8個數據位通信,通過PB8、PB9,、PB10、PB11分別控制液晶屏的RST、CS、RS、WR、液晶屏的RD接3.3v來控制液晶屏的顯示。通過PB0輸入信號進行信號采集。PB1為暫停鍵,方便暫停波形觀測波形。PB7和PB4分別為增大網格時間間隔和減少網格時間間隔。 系統如下圖1.1:
0.png (20.32 KB, 下載次數: 111)
下載附件
2016-10-20 23:41 上傳
圖1.1 系統圖 本設計使用方法: - 把電路板背面的電池盒開關由OFF撥去ON,即可進入波形顯示界面。
- 如果暫停鍵沒有按下,信號輸入插針的地接信號器的地線,IN接信號輸入。即可有輸出波形顯示到顯示屏上。
- 網格橫向方向有時間軸,縱軸為電壓值,電壓縱軸已有標注,而橫軸時間的每一個網格間隔相距的時間間隔在顯示屏的右上方已經顯示出來。
- 通過按按鍵T+或者T-即可改變橫軸每個網格之間的時間間隔。
- 按下暫停鍵即可得到暫停在一個時間點的波形。再按一次暫停鍵又可繼續觀察實時的波形。
第二章 硬件電路的設計
2.1STM32最小系統介紹 STM32系列基于專為要求高性能、低成本、低功耗的嵌入式應用專門設計的ARM Cortex-M3內核。按性能分成兩個不同的系列:STM32F103“增強型”系列和STM32F101“基本型”系列。增強型系列時鐘頻率達到72MHz,是同類產品中性能最高的產品;基本型時鐘頻率為36MHz,以16位產品的價格得到比16位產品大幅提升的性能,是16位產品用戶的最佳選擇。兩個系列都內置32K到128K的閃存,不同的是SRAM的最大容量和外設接口的組合。時鐘頻率72MHz時,從閃存執行代碼,STM32功耗36mA,是32位市場上功耗最低的產品。 本設計所用的STM32F103C8T6集成的片上功能如下: (1) 1.2v內核供電,1.8V/2.5V/3.3/V存儲器供電,3.3V外部I/O供電 (2) 外部存儲控制器 (3) LCD 控制器 (4) 4通道DNA并有外部請求引腳 (5) 3通道UART電子技術綜合實踐 (5) 3通道UART (6) 2通道SPI (7) 1通道IIC總線接口1通道IIS總線接口 (8) AC’97編解碼器接口 (9) 兼容SD主接口協議1.0版和MMC卡協議2.11兼容版 (10) 2通道USB主機1通道USB設備 (11) 4通道PWM定時器和1通道內部定時器/看門狗定時器 (12) 8通道10位ADC和觸摸屏接口 (13) 80個通用I/O和24通道外部中斷源 而本次使用的是STM32F103C8T6是已經集成好的最小系統板如下圖:
1.010.jpg (26.81 KB, 下載次數: 107)
下載附件
2016-10-20 23:42 上傳
圖2.1.1 STM32F103C8T6最小系統實物圖
1.011.jpg (24.75 KB, 下載次數: 109)
下載附件
2016-10-20 23:42 上傳
圖2.1.2 STM32F103C8T6最小系統電路圖 2.2 、4.2英寸TFT液晶顯示屏 尺寸:320*400;
1.012.jpg (40.21 KB, 下載次數: 107)
下載附件
2016-10-20 23:42 上傳
圖2.2 4.2英寸液晶顯示屏圖片 2.3電源設計:雖然stm32是低功耗芯片,可以因為4.2英寸液晶屏是高功耗器件,所以在電源的選擇上,我選擇了四個可充電的1000mah的1.2v鎳鎘電池串聯起來提供4.8v作為供電電源,工作續航能力得到大大提高。
1.013.jpg (26.88 KB, 下載次數: 88)
下載附件
2016-10-20 23:42 上傳
圖2.2 電池盒 附:實物效果圖一張:
1.014.jpg (38.61 KB, 下載次數: 125)
下載附件
2016-10-20 23:42 上傳
51開發板作為波形發生器
1.015.jpg (27.47 KB, 下載次數: 89)
下載附件
2016-10-20 23:42 上傳
正弦波、三角波、梯形波、正弦波
1.016.jpg (16.07 KB, 下載次數: 100)
下載附件
2016-10-20 23:42 上傳
1.017.jpg (13.4 KB, 下載次數: 109)
下載附件
2016-10-20 23:42 上傳
1.018.jpg (12.12 KB, 下載次數: 93)
下載附件
2016-10-20 23:42 上傳
1.019.jpg (12.09 KB, 下載次數: 117)
下載附件
2016-10-20 23:42 上傳
軟件的任務包括通過初始化GPIO、RCC、ADC、 SYSTICK、EXIT、NVIC、4.2英寸液晶屏等進行初始化。然后通過AD采集的信號以隊列方式儲存起來,再輸送到液晶屏。當完成了一個屏幕的數據點采集,再從頭開始消點、采集、畫點,當然在寫程序的時候加入了一個使數據點連在一起的小算法達到顯示效果。 所編寫程序如下:(以下為主要程序,其他次要程序文件均在附錄中)
通過無數的錯誤與更正,總結如下幾點特別需要注意的要點: - 由于本人設計的顯示方式的橫向顯示,所以在字符取模的時候要注意要橫向取模。其中,取模軟件zimo221。
1.021.jpg (62.37 KB, 下載次數: 111)
下載附件
2016-10-20 23:42 上傳
2、經過很多次調試,已經搞清楚本程序編寫液晶屏顏色參數時,24位顏色參數格式為G-R-B,其中G、R、B各用一個8位數據表示。而顏色表數據也比較難找。我的微博中有轉發過有關顏色RGB混合參數的非常實用的微博。詳情請關注新浪微博@中南大學陳錦熙。 3、 以下程序為調試多天之后能最終成功的“消點-采點-畫點”的程序,也是本設計的核心程序。其中加入了讓采集點連續起來的小算法,參考自百度的資料。曾試過在每一次采集結束時通過for(mm=0;mm<400;mm++)adre[mm]=ad[mm];使ad[mm]為實時數據,adre[mm]為上一輪數據。利用adre[mm]在下一輪消點(包括連續算法的連線),但是調試過幾天發現adre[mm]=ad[mm]得到的的數據竟然是亂值。所以在調試程序時必須要靈活變通,敢于懷疑。 if(clr_flag==1) //清點 { draw_point(allnum + move_x ,ad[allnum]+ move_y,0x0000); if((allnum<=398)&&(ad[allnum+1]>ad[allnum])) for(nn=ad[allnum+1]-ad[allnum];nn>0;nn--) draw_point(allnum +1+ move_x ,ad[allnum+1]-nn+move_y,0x0000); if((allnum<=398)&&(ad[allnum+1]0;nn--) draw_point(allnum +1+ move_x ,ad[allnum+1]+nn+move_y,0x0000); } ad[allnum]=ADC_GetConversionValue(ADC1)/30; //取值畫圖 draw_point(allnum + move_x ,ad[allnum]+ move_y,0xffc000); if((allnum>=1)&&(ad[allnum]>ad[allnum-1])) for(nn=ad[allnum]-ad[allnum-1];nn>0;nn--) draw_point(allnum + move_x ,ad[allnum]-nn+move_y,0xffc000); if((allnum>=1)&&(ad[allnum]0;nn--) draw_point(allnum + move_x ,ad[allnum]+nn+move_y,0xffc000); allnum++; 4、做按鍵程序的時候,打算用中斷做,可是全局變量定義總是出錯。克服了這個問題之后,發現芯片用PB3做中斷按鍵時運作失敗。通過多次的調試,發現PB3總是為低電平。換了芯片之后情況一樣。所以換做PB4、PB7作為中斷按鍵。而PB1作為常開/常閉開關用來暫停波形。最后得到了應有效果。 5、關于4.2英寸液晶屏的調解程序,復雜度相當高。而且大部分指令都難以理解。連說明書都只有英文版的。所以在此我已經在本次工程的4.2寸液晶屏c文件中用中文注釋了所有命令的中文功能。便于自己理解,也可以幫助大家的學習液晶屏這一個優秀的輸出平臺。
通過這次基于STM32的微型掌上示波器的設計,我更加深入地理解和運用到了更多關于ARM尤其是STM32的特點和功能。 在之前我也用過51做溫度器、做霍爾元件測速器、振動報警器、用過stm32做水力發電葉片、風力發電葉片控制電路(比賽作品)。但這次示波器的設計斷斷續續耗計了我三個星期,是我學習到最多的一次。因為這次設計涉及到的AD、和42英寸液晶屏都是STM32的中端應用。其實這個設計如果用COSII來做的話應該能達到更豐富的效果。 STM32F103C8T6的參考正、負電壓默認連接到芯片工作電壓3.3V(實際3.26V)和地(0V)。所以示波器檢測的電壓區間只能為0~3.26V。如果要實現負電壓的檢測,則要加入加法電路。市面上的STM32F103C8T6升級版STM32F103VCT6有AD對應的的VREF+和VREF-接口,可以完美地解決這個問題。 這次沒有用PCB板做,是因為芯片用的是最小系統集成板,顯示屏用的是ili9325和液晶板的集成板,核心器件已經是高度集成化的,連接電路比較簡單,所以選用了較為簡便的洞洞板來拼接這兩個模塊。 因為沒有昂貴的函數發生器,而且去物理院借用函數發生器非常麻煩,所以我用51單片機開發板做出來了簡易函數發生器(能產生矩形波、三角波、鋸齒波、正弦波,用獨立按鍵1、2、3、4控制)。程序在附錄中。 這次的作品需要改進的地方有很多: 1、運用多路AD即可做出多蹤示波器,這個很容易實現。 2、可以做儲存數據的程序; 3、可以做成觸屏,使用界面更加友好; 4、用UCOSII做可能有更佳的效果。 總之,通過這次作品設計,我撞到了數不清的困難和到現在解不開的難題。可以有困難就去克服,克服不了就尋求網絡資源幫忙。如果實在解不開,就用另一種方法代替。雖然“寫程序用了三個小時,調試用了三天。”可是堅持下去,我得到的是鍛煉和經驗。這個設計有很多廢命令和不太合理、累贅的地方,還望大家指正! 附錄一 字庫(本程序適用) - // ------------------ 漢字字模的數據結構定義 ------------------------ //
- struct typFNT_GB16 // 漢字字模數據結構
- {
- unsigned char Index[3]; // 漢字內碼索引
- unsigned char Msk[32]; // 點陣碼數據
- };
-
- /////////////////////////////////////////////////////////////////////////
- // 漢字字模表 //
- // 漢字庫: 宋體16.dot,橫向取模左高位,數據排列:從左到右從上到下 // (原來為橫向不倒序)
- /////////////////////////////////////////////////////////////////////////
- const struct typFNT_GB16 codeGB_16[] = // 數據表
- {
- /*-- 文字: 簡 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "簡",0x00,0x08,0x00,0x04,0xFF,0xC3,0x00,0x12,0x00,0x26,0x3F,0x8A,0x24,0xA2,0x24,0xAA,
- 0x24,0xA4,0x3F,0xA3,0x00,0x22,0x80,0x26,0xFF,0xEA,0x00,0x02,0x00,0x02,0x00,0x00,
- /*-- 文字: 易 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "易",0x00,0x00,0x08,0x00,0x04,0x00,0x42,0x00,0x23,0x7F,0x12,0xC9,0x8E,0x49,0x42,0x49,
- 0x32,0x49,0x0E,0x49,0x42,0x49,0x82,0x7F,0x42,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 示 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "示",0x20,0x40,0x10,0x40,0x08,0x42,0x06,0x42,0x00,0x42,0x40,0x42,0x80,0x42,0x7F,0xC2,
- 0x00,0x42,0x00,0x42,0x00,0x42,0x02,0x42,0x04,0x42,0x08,0x40,0x30,0x40,0x00,0x00,
- /*-- 文字: 波 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "波",0x04,0x10,0x04,0x60,0x7C,0x02,0x03,0x0C,0x80,0xC0,0x60,0x00,0x1F,0xF8,0x80,0x88,
- 0x43,0x88,0x2C,0x88,0x10,0xFF,0x28,0x88,0x46,0x88,0x81,0xA8,0x80,0x18,0x00,0x00,
- /*-- 文字: 器 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "器",0x08,0x80,0x08,0x80,0xF4,0x9E,0x94,0x92,0x92,0x92,0x92,0x92,0xF1,0x9E,0x00,0xE0,
- 0x01,0x80,0xF2,0x9E,0x92,0xB2,0x94,0xD2,0x94,0x92,0xF8,0x9E,0x08,0x80,0x00,0x00,
- /*-- 文字: 時 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "時",0x00,0x00,0x3F,0xFC,0x10,0x84,0x10,0x84,0x10,0x84,0x3F,0xFC,0x00,0x00,0x00,0x10,
- 0x01,0x10,0x06,0x10,0x40,0x10,0x80,0x10,0x7F,0xFF,0x00,0x10,0x00,0x10,0x00,0x00,
- /*-- 文字: 間 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "間",0x00,0x00,0xFF,0xF8,0x00,0x01,0x00,0x06,0x00,0x00,0x1F,0xF0,0x11,0x12,0x11,0x12,
- 0x11,0x12,0x1F,0xF2,0x00,0x02,0x40,0x02,0x80,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,
- /*-- 文字: 隔 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "隔",0x00,0x00,0xFF,0xFE,0x04,0x22,0x08,0x5A,0x07,0x86,0x00,0x00,0xFF,0x02,0x09,0x7A,
- 0x0B,0x4A,0x0D,0x4A,0x79,0x4A,0x0D,0x4A,0x4B,0x4A,0x89,0x7A,0x7F,0x02,0x00,0x00,
- /*-- 文字: 0 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "0",0x00,0x00,0x0F,0xE0,0x10,0x10,0x20,0x08,0x20,0x08,0x10,0x10,0x0F,0xE0,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 1 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "1",0x00,0x00,0x20,0x10,0x20,0x10,0x3F,0xF8,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- /*-- 文字: 2 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "2",0x00,0x00,0x30,0x70,0x28,0x08,0x24,0x08,0x22,0x08,0x21,0x88,0x30,0x70,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- /*-- 文字: 3 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "3",0x00,0x00,0x18,0x30,0x20,0x08,0x20,0x88,0x20,0x88,0x11,0x48,0x0E,0x30,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- /*-- 文字: 4 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "4",0x00,0x00,0x07,0x00,0x04,0xC0,0x24,0x20,0x24,0x10,0x3F,0xF8,0x24,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 5 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "5",0x00,0x00,0x19,0xF8,0x21,0x08,0x20,0x88,0x20,0x88,0x11,0x08,0x0E,0x08,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 6 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "6",0x00,0x00,0x0F,0xE0,0x11,0x10,0x20,0x88,0x20,0x88,0x11,0x18,0x0E,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 7 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "7",0x00,0x00,0x00,0x38,0x00,0x08,0x3F,0x08,0x00,0xC8,0x00,0x38,0x00,0x08,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 8 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "8",0x00,0x00,0x1C,0x70,0x22,0x88,0x21,0x08,0x21,0x08,0x22,0x88,0x1C,0x70,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 9 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "9",0x00,0x00,0x00,0xE0,0x31,0x10,0x22,0x08,0x22,0x08,0x11,0x10,0x0F,0xE0,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: M --*/
- /*-- 宋體14; 此字體下對應的點陣為:寬x高=10x19 --*/
- "M",0x20,0x08,0x3F,0xF8,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x3F,0xF8,0x20,0x08,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: S --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "S",0x00,0x00,0x38,0x70,0x20,0x88,0x21,0x08,0x21,0x08,0x22,0x08,0x1C,0x38,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 調入了一幅圖像:這是您新建的圖像 --*/
- /*-- 寬度x高度=16x16 --*/
- "花",0x00,0x80,0x00,0x40,0x00,0x20,0x03,0x10,0x03,0x10,0x00,0x20,0x00,0x40,0x00,0x80,
- 0x01,0x00,0x02,0x00,0x04,0x00,0x08,0xC0,0x08,0xC0,0x04,0x00,0x02,0x00,0x01,0x00,
-
- /*-- 文字: 陳 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "陳",0x00,0x00,0xFF,0xFE,0x04,0x22,0x08,0x5A,0x07,0x86,0x20,0x08,0x11,0x88,0x0D,0x68,
- 0x41,0x18,0x81,0x0F,0x7F,0xE8,0x01,0x08,0x05,0x08,0x09,0x08,0x30,0x08,0x00,0x00,
- /*-- 文字: 錦 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "錦",0x01,0x20,0x01,0x10,0x01,0x2C,0x7F,0xE7,0x21,0x24,0x11,0x24,0x3E,0x00,0x02,0x7C,
- 0x02,0x54,0x02,0x56,0xFF,0xD5,0x02,0x54,0x12,0x54,0x22,0x7C,0x1E,0x00,0x00,0x00,
- /*-- 文字: 熙 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "熙",0x80,0x00,0x47,0xFE,0x34,0x02,0x04,0xF2,0x04,0x92,0x17,0x9E,0x64,0x92,0x04,0xF2,
- 0x14,0x00,0x63,0xFE,0x04,0x22,0x04,0x22,0x14,0x22,0xE4,0x3E,0x07,0x00,0x00,0x00,
- /*-- 文字: 中 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "中",0x00,0x00,0x00,0x00,0x0F,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0xFF,0xFF,
- 0x04,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 南 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "南",0x00,0x04,0xFF,0xE4,0x00,0x24,0x08,0x24,0x09,0x64,0x09,0xA4,0x09,0x24,0x7F,0x3F,
- 0x09,0x24,0x09,0xA4,0x09,0x64,0x48,0x24,0x80,0x24,0x7F,0xE4,0x00,0x04,0x00,0x00,
- /*-- 文字: 大 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "大",0x80,0x20,0x80,0x20,0x40,0x20,0x20,0x20,0x10,0x20,0x0C,0x20,0x03,0x20,0x00,0xFF,
- 0x03,0x20,0x0C,0x20,0x10,0x20,0x20,0x20,0x40,0x20,0x80,0x20,0x80,0x20,0x00,0x00,
- /*-- 文字: 學 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "學",0x04,0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,0x90,0x44,0x90,0x84,0x91,0x7E,0x96,
- 0x06,0x90,0x05,0x90,0x04,0x98,0x04,0x14,0x04,0x13,0x04,0x50,0x04,0x30,0x00,0x00,
- /*-- 文字: --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "暫",0x00,0x82,0x01,0x9A,0x00,0x96,0xFE,0x93,0x93,0xFA,0x92,0x52,0x93,0x52,0x92,0x80,
- 0x92,0x7E,0x92,0x12,0x92,0x12,0xFE,0x12,0x03,0xF1,0x00,0x11,0x00,0x10,0x00,0x00,
- /*-- 文字: --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
- "停",0x00,0x80,0x00,0x60,0xFF,0xF8,0x00,0x07,0x03,0x00,0x01,0x04,0x05,0x74,0x45,0x54,
- 0x85,0x55,0x7D,0x56,0x05,0x54,0x05,0x54,0x05,0x74,0x01,0x04,0x03,0x00,0x00,0x00,
- /*-- 文字: . --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- ".",0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: V --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
- "V",0x00,0x08,0x00,0x78,0x07,0x88,0x38,0x00,0x0E,0x00,0x01,0xC8,0x00,0x38,0x00,0x08,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- };
復制代碼
附錄二 51單片機波形發生器(本程序適用)
其中獨立按鍵1、2、3、4按下時會產生四個不同波形(矩形、三角波、梯形波、正弦波)
主函數:
Main.c
- #include
- #include "i2c.h"
- #define AddWr 0x90 //寫數據地址
- #define AddRd 0x91 //讀數據地址
-
- /*unsigned char code tab[]={
- 0,25,50,75,100,125,150,175,200,225,250 //表格數值越多,波形越平滑
- };*/
- unsigned char code tab1[]={
- 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,
- 170,180,190,200,210,220,230,240,250
- };
- unsigned char code juchi[64]={
- 0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
- 146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
- };
-
- unsigned char code sin[64]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
- 146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
- unsigned char code sanjiao[64]={
- 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
- 248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
- };
- unsigned char code tixing[64]={
- 0,13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
- 247,247,247,247,247,247,247,242,229,216,203,190,177,164,151,138,125,112,99,86,73,60,47,34,21,8
- };
- unsigned char code juxing[64]={
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- };
-
-
-
-
- extern bit ack;
- bit WriteDAC(unsigned char dat,unsigned char num);
- /*------------------------------------------------
- 主程序
- ------------------------------------------------*/
- main()
- {
- unsigned char i;
- while (1) //主循環
- {
- // for(i=0;i<26;i++)
- // WriteDAC(tab1[i],1);
- while(P1==0xff)
- {
- for(i=0;i<64;i++)
- WriteDAC(juxing[i]*6/10,1);
- if(P1!=0xff)break;
- }
- while(P1==0xfe)
- {
- for(i=0;i<64;i++)
- WriteDAC(tixing[i]*6/10,1);
- if(P1!=0xfe)break;
- }
- while(P1==0xfd)
- {
- for(i=0;i<64;i++)
- WriteDAC(sanjiao[i]*6/10,1);
- if(P1!=0xfd)break;
- }
- while(P1==0xfb)
- {
- for(i=0;i<64;i++)
- WriteDAC(sin[i]*6/10,1);
- if(P1!=0xfb)break;
- }
- while(P1==0xf7)
- {
- for(i=0;i<64;i++)
- WriteDAC(juchi[i]*6/10,1);
- if(P1!=0xf7)break;
- }
- }
- }
-
- /*------------------------------------------------
- 寫入DA轉換數值
- 輸入參數:dat 表示需要轉換的DA數值,范圍是0-255
- ------------------------------------------------*/
- bit WriteDAC(unsigned char dat,unsigned char num)
- { unsigned char i;
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發送器件地址
- if(ack==0)return(0);
- SendByte(0x40); //發送器件子地址
- if(ack==0)return(0);
- for(i=0;i<num;i++)
- {
- SendByte(dat); //發送數據
- if(ack==0)return(0);
- }
- Stop_I2c();
-
- }
-
-
- IIC協議:
- IIC.C
-
-
-
- #include "i2c.h"
-
- #define _Nop() _nop_() //定義空指令
-
- bit ack; //應答標志位
-
- sbit SDA=P2^1;
- sbit SCL=P2^0;
-
- /*------------------------------------------------
- 啟動總線
- ------------------------------------------------*/
- void Start_I2c()
- {
- SDA=1; //發送起始條件的數據信號
- _Nop();
- SCL=1;
- _Nop(); //起始條件建立時間大于4.7us,延時
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=0; //發送起始信號
- _Nop(); //起始條件鎖定時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //鉗住I2C總線,準備發送或接收數據
- _Nop();
- _Nop();
- }
- /*------------------------------------------------
- 結束總線
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA=0; //發送結束條件的數據信號
- _Nop(); //發送結束條件的時鐘信號
- SCL=1; //結束條件建立時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=1; //發送I2C總線結束信號
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
-
-
-
-
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: void SendByte(unsigned char c);
- 功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
- 此狀態位進行操作.(不應答或非應答都使ack=0 假)
- 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
-
- for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數據長度為8位
- {
- if((c<<bitcnt)&0x80)sda=1; 判斷發送位
- else SDA=0;
- _Nop();
- SCL=1; //置時鐘線為高,通知被控器開始接收數據位
- _Nop();
- _Nop(); //保證時鐘高電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- }
-
- _Nop();
- _Nop();
- SDA=1; //8位發送完后釋放數據線,準備接收應答位
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; //判斷是否接收到應答信號
- SCL=0;
- _Nop();
- _Nop();
- }
-
-
-
-
-
-
-
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: unsigned char RcvByte();
- 功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
- 發完后請用應答函數。
- ------------------------------------------------------------------*/
- /*unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
-
- retc=0;
- SDA=1; //置數據線為輸入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; //置時鐘線為低,準備接收數據位
- _Nop();
- _Nop(); //時鐘低電平周期大于4.7us
- _Nop();
- _Nop();
- _Nop();
- SCL=1; //置時鐘線為高使數據線上數據有效
- _Nop();
- _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; //讀數據位,接收的數據位放入retc中
- _Nop();
- _Nop();
- }
- SCL=0;
- _Nop();
- _Nop();
- return(retc);
- }
- */
-
-
- /*----------------------------------------------------------------
- 應答子函數
- 原型: void Ack_I2c(void);
-
- ----------------------------------------------------------------*/
- /*void Ack_I2c(void)
- {
-
- SDA=0;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續接收
- _Nop();
- _Nop();
- }*/
- /*----------------------------------------------------------------
- 非應答子函數
- 原型: void NoAck_I2c(void);
-
- ----------------------------------------------------------------*/
- /*void NoAck_I2c(void)
- {
-
- SDA=1;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續接收
- _Nop();
- _Nop();
- }
-
- */
-
-
-
-
- /*----------------------------------------------------------------
- 向無子地址器件發送字節數據函數
- 函數原型: bit ISendByte(unsigned char sla,ucahr c);
- 功能: 從啟動總線到發送地址,數據,結束總線的全過程,從器件地址sla.
- 如果返回1表示操作成功,否則操作有誤。
- 注意: 使用前必須已結束總線。
- ----------------------------------------------------------------*/
- /*bit ISendByte(unsigned char sla,unsigned char c)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(c); //發送數據
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- */
-
- /*----------------------------------------------------------------
- 向有子地址器件發送多字節數據函數
- 函數原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
- 功能: 從啟動總線到發送地址,子地址,數據,結束總線的全過程,從器件
- 地址sla,子地址suba,發送內容是s指向的內容,發送no個字節。
- 如果返回1表示操作成功,否則操作有誤。
- 注意: 使用前必須已結束總線。
- ----------------------------------------------------------------*/
- /*bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
- {
- unsigned char i;
- for(i=0;i<no;i++)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(suba); //發送器件子地址
- if(ack==0)return(0);
-
- SendByte(*s); //發送數據
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- DelayMs(1); //必須延時等待芯片內部自動處理數據完畢
- s++;
- suba++;
- }
- return(1);
- }
- */
- /*----------------------------------------------------------------
- 向無子地址器件讀字節數據函數
- 函數原型: bit IRcvByte(unsigned char sla,ucahr *c);
- 功能: 從啟動總線到發送地址,讀數據,結束總線的全過程,從器件地
- 址sla,返回值在c.
- 如果返回1表示操作成功,否則操作有誤。
- 注意: 使用前必須已結束總線。
- ----------------------------------------------------------------*/
- /*bit IRcvByte(unsigned char sla,unsigned char *c)
- {
- Start_I2c(); //啟動總線
- SendByte(sla+1); //發送器件地址
- if(ack==0)return(0);
- *c=RcvByte(); //讀取數據
- NoAck_I2c(); //發送非就答位
- Stop_I2c(); //結束總線
- return(1);
- }
-
- */
- /*----------------------------------------------------------------
- 向有子地址器件讀取多字節數據函數
- 函數原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
- 功能: 從啟動總線到發送地址,子地址,讀數據,結束總線的全過程,從器件
- 地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個字節。
- 如果返回1表示操作成功,否則操作有誤。
- 注意: 使用前必須已結束總線。
- ----------------------------------------------------------------*/
- /*bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
- {
- unsigned char i;
-
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(suba); //發送器件子地址
- if(ack==0)return(0);
-
- Start_I2c();
- SendByte(sla+1);
- if(ack==0)return(0);
-
- for(i=0;i<no-1;i++)
- {
- *s=RcvByte(); //發送數據
- Ack_I2c(); //發送就答位
- s++;
- }
- *s=RcvByte();
- NoAck_I2c(); //發送非應位
- Stop_I2c(); //結束總線
- return(1);
- }
- */
復制代碼
|