• 單片機MCU如何實現讓部分代碼運行在RAM中?看這裏

     MCU 異於 資源豐富的linux 平台。 MCU(如: 基於Cortex V6M 的Cortex M0+ 等) Code 通常運行在內嵌Flash 中。 在某些特定應用場合,需要將部分函數運行於RAM 中。 昨天,為解決次問題,實現了一種解法,具體做法如下: 1. 實現要運行在RAM的 routine, 本routine 使用純彙編實現, 如: __asm void program_word2addr(uint32_t addr, uint32_t data) { push {r3, r4, r5, lr} ;save some regsiters /*your code for this routine*/ pop {r3, r4, r5, pc} } 2. 編譯時,採用code 與運行位置無關的編譯選項 如 (Keil --apcs /ropi/rwpi), 生成 *.axf; 3. 通過fromelf -c 將生成 *.axf 反彙編,找到對應program_word2addr 實現部分, 並將routine 對應的binary code Copy 到所要應用的 Code 中,以只讀數組的形式出現: 如: const staic uint16_t s_flashProg2AddressCode[16] = {...., ....} 4. 定義 一個全局數組, 如 static uint16_t g_code[16], size正好等於 s_flashProg2AddressCode的長度; 5. 定義一個函數指針, 如 static void (*callFlashPrg2Address)(uint32_t addr, uint32_t data) 6. 定義一個函數實現將Code 運行與 RAM如: void run_prgcode_onram(uint32_t addr, uint32_t data) { memcpy(g_code,s_flashProg2AddressCode,32 ); callFlashPrg2Address = (void (*)(uint32_t addr, uint32_t data))((uin32_t)g_code + 1); callFlashPrg2Address (address, data); } run_prgcode_onram, 便可以將program_word2addr 運行於RAM中。 callFlashPrg2Address = (void (*)(uint32_t addr, uint32_t data))((uin32_t)g_code + 1); +1 的目的,時由於運行平台為 Cortex V6M , 採用的thumb指令集,根據ARM Spec 要 求完成。 callFlashPrg2Address (address, data); 則是實現RAM運行program_word2addr 的關鍵所在。

    時間:2018-08-14 關鍵詞: MCU RAM 單片機

  • 關於SPI-Flash的一些基礎知識

     1.不同的SPIFLASH芯片可能會提供的擦除方式:扇區擦除(4KBytes),半塊擦除(32KBytes),塊擦除(64KBytes),片擦除。 2.不同的SPIFLASH芯片可能會提供的編程方式(也就是寫數據):頁編程(256Bytes),扇區編程(4KBytes)。 3.SPIFLASH如果擦除過,在往裏面寫0xFF這樣的數據意義不大,因為它的特性就是擦除後數據就是0xFF。 4.寫入flash時,只能把數據(bit)從1該為0。 5.傳統的EEPROM的特點就是可以隨機訪問和修改任何一個字節,可以往每個bit中寫入0或1。而寫入flash時,只能把數據(bit)從1該為0。但是傳統的EEPROM容量因成本的緣故收到限制,絕少有超過有512K的。 6.Nor Flash容量相對小,成本高,基本沒壞塊,數據線和地址線分開,可以實現隨機尋址,讀取任何一個字節,擦除任然要按塊來擦。NAND FLASH容量大,成本低,壞塊經常出現,但可以標記壞塊,使軟件跳過,數據線和地址線複用,按塊擦除按頁讀取。

    時間:2018-08-14 關鍵詞: Flash spi

  • 單片機MCU相關基礎知識整理篇

     1.MCU有串口外設的話,在加上電平轉換芯片,如MAX232,SP3485就是RS232和RS485接口了。 2.RS485採用差分信號負邏輯,+2~+6V表示0,-6~-2表示1。有兩線制和四線制兩種接線,四線制是全雙工通訊方式,兩線制是半雙工通訊方式。在RS485一般採用主從通訊方式,即一個主機帶多個從機。 3.Modbus是一種協議標準,可以支持多種電氣接口,如RS232,RS485,也可以在各種介質上傳輸,如雙絞線,光纖,無線。 4.很多MCU的串口都開始自帶FIFO,收發FIFO主要是為了解決串口收發中斷過於頻繁而導致CPU的效率不高的問題。如果沒有FIFO,則沒收發一個數據都要中斷處理一次,有了FIFO,可以在連續收發若干個數據(根據FIFO的深度而定)後才產生一次中斷去處理數據,大大提高效率。 5.有些工程師在調試自己的系統時一出現系統跑飛,就馬上引入看門狗來解決問題,而沒有思想程序為什麼會跑飛?程序跑飛可能是程序本身的bug,也可能是硬件電路的問題(本身就是易受干擾或自己就是干擾源)。通常建議在調試自己的系統時,先不加看門狗,等完全調試穩定了,在補上(危機產品安全,人身安全的除外)。 6.如何區分有源蜂鳴器和無源蜂鳴器? 從外觀上看,如將兩種蜂鳴器的引腳都朝上放置時,可以看出綠色電路板的一種是源蜂鳴器,沒有電路板而用黑膠密封的一種是有源蜂鳴器。 有源蜂鳴器直接接上額定電源就可以連續發聲,而無源蜂鳴器則和電磁揚聲器一樣,需要接在音頻輸出電路上才能發聲。 7.電壓比較器的用途主要是波形的產生和變換,模擬電路到數字電路的接口。 8.低功耗喚醒的常用方式:處理器進入低功耗後就停止了很多活動,當出現一箇中斷時,可以喚醒處理器,使其從低功耗模式返回到正常運行模式。因此在進入低功耗模式之前,必須配置莫個片內外設的中斷,並允許其在低功耗模式下繼續工作。如果不這樣,只有復位和重新上電才能結束低功耗模式。處理器喚醒後首先執行中斷服務程序,退出後接着執行主程序中的代碼。 9.觸摸屏的特徵: 1)透明,直接影響到觸摸屏的視覺效果。從這一點看紅外線技術觸摸屏和表面聲波觸摸屏由於只隔了一層純玻璃,視覺效果突出。而很多觸摸屏是很多層的複合薄膜,僅用透明一點來概括它的視覺效果是不夠的,還可以包括色彩失真度,反光性,清晰度。色彩失真度也就是圖中的最大色彩失真度,自然是越小越好。反光性主要是指由於鏡面反射造成圖像上重疊後產生的光影,如人影。大多數存在反光性的觸摸屏提供另外一種型號,磨砂面觸摸屏,也叫防眩型。 2)觸摸屏是據對座標系統,也就是不管在什麼情況下,同一點的輸出數據時穩定的,如果不穩定,就會定位不準,也就是觸摸屏最怕的問題:漂移。技術原理上凡是不能保證同一點觸摸每一次採樣數據相同的觸摸屏都免不了漂移問題,目前有漂移現象的只有電容觸摸屏。 10.註冊中斷服務函數:中斷服務函數已經編寫好,但當中斷事件發生時,CPU還是無法找到它,因為我們還缺少最後一步:註冊中斷服務函數。註冊有兩種方法:一是直接利用中斷註冊函數,優點是操作簡單,可移植性好,缺點是由於把中斷向量表重新映射到SRAM中而導致執行效率下降:還有一種是需要修改啓動文件,優點效率很高,確定可移植性不高。 11.很多的MCU提供數字電源VDD/GND和模擬電源VDDA/GNDA。通常建議是採用兩路不同的3.3V電源供電。但為了節省成本,也可以採用單路3.3V電源,但VDDA/GNDA要通過電感從VDD/GND分離出來。一般GNDA和GND最終還是要連接在一起的,建議用一個繞線電感連接並且接點儘可能靠近芯片(電感最好放置在PCB背面)。

    時間:2018-08-14 關鍵詞: MCU 單片機

  • 電平控制LED燈,電平轉換電路

    電平控制LED燈 電平轉換 單向 12V轉3V (其中Vgs>2.5V導通,用的7002所以Vg需要小於60V)

    時間:2018-08-14 關鍵詞: 電子電路 電平轉換

  • 關於C語言內存的一些理解

     內存這個大話題 key:心裏一定要有內存的邏輯圖。 程序是什麼? 程序 = 代碼 + 數據 代碼放在Flash中代碼段,可變的數據(全局變量、局部變量)放在內存中。 運行程序的目的是什麼? 得到運行結果; 關注運行過程;既要結果又要過程; 為什麼需要內存? 程序中有可變數據(全局變量、局部變量),這些可變數據就是放在內存中的。 內存如何管理? 每個內存單元都有唯一的地址,通過尋址來管理內存。 關鍵點 一個字節為一個內存單元,一個內存單元有一個內存地址。 C語言是如何操作內存的? 定義變量時,編譯器自動的申請一塊內存供我們使用。 管理內存的各種方式? 數組、結構體、棧(FILO)、堆(大內存)

    時間:2018-08-08 關鍵詞: C語言

  • 單片機學習記錄——開發總流程

     開發總流程 1.打開keil,建立新的工程。 2.新建 .c 文件和 .h 文件,再把.c文件添加到工程中。 3.在新建的.c文件中編輯c代碼就可以了。 4.編譯程序,生成.hex可執行文件。 所需查看的文檔 查看原理圖,瞭解硬件如何接線,知道控制哪幾個IO口 查看單片機的datasheet和各個外設芯片的datasheet,瞭解如何編程,尤其是外設芯片的工作時序。 如何燒錄程序至單片機? 答:編譯編寫好的單片機程序,生成.hex文件,打開燒錄軟件,選擇單片機型號和COM端口,再選擇.hex文件,點擊下載,然後打開開發板的電源。至此,程序就已燒錄進單片機。

    時間:2018-08-08 關鍵詞: 單片機開發 單片機

  • 如何設計一個三極管放大電路

      設計步驟 1) 分析設計要求 電壓增益可以用於計算電壓放大倍數;最大輸出電壓可以用於設置電源電壓 輸出功率可以用於計算髮射極電流;在選擇晶體管時需要注意頻率特性。 2)確定電源電壓 在第一個圖中我們觀察到最大輸出電壓幅值為5V, 三極管輸出電壓幅度由Vc極電壓決定,而Vc端的電壓要設置為電源電壓的1/2左右。在這裏我們設置為電源電壓為15V (為了使信號正負能有對稱的變化空間,在沒有信號輸入的時候,即信號輸入為0,假設Uce為電源電壓的一半,我們當它為一水平線,作為一個參考點。當輸入信號增大時,則Ib增大,Ic電流增大,則電阻R2的電壓U2=Ic×R2會隨之增大,Uce=VCC-U2,會變小。U2最大理論上能達到等於VCC,則Uce最小會達到0V,這是説,在輸入信增加時,Uce最大變化是從1/2的VCC變化到0V. 同理,當輸入信號減小時,則Ib減小,Ic電流減小,則電阻R2的電壓U2=Ic×R2會隨之減小,Uce=VCC-U2,會變大。在輸入信減小時,Uce最大變化是從1/2的VCC變化到VCC。這樣,在輸入信號一定範圍內發生正負變化時,Uce以1/2VCC為準的話就有一個對稱的正負變化範圍。) 3)選擇晶體三極管 用三極管需要考慮的問題: 1)耐壓夠不夠 2)負載電流夠不夠大 3)速度夠不夠快(有時卻是要慢速) 4)B極控制電流夠不夠 5)有時可能考慮功率問題 6)有時要考慮漏電流問題(能否“完全”截止)。 7)一般都不怎麼考慮增益(我的應用還沒有對此參數要求很高) 4)確定發射極電流Ie 根據發射極的頻率特性與發射極的頻率特性關係。小信號共發射極的發射極的電流大小為0.1到數毫安。 5)確定Rc和Re的值 通常Vce設定為VCC的一半,Vce=Ic*(Rc+Re),Rc和Re跟放大倍數有關。 6)確定基極偏置電路R1和R2的值 我們已知Ic值,由Ic=β*Ib(β一般取100 ),然後估算流過R1的電流值,一般取值為Ib的10倍左右。計算R1和R2。 R1、R2為三極管V1的直流偏置電阻,什麼叫直流偏置?簡單來説,做工要吃飯。要求三極管工作,必先要提供一定的工作條件,電子元件一定是要求有電能供應的了,否則就不叫電路了。在電路的工作要求中,第一條件是要求要穩定,所以,電源一定要是直流電源,所以叫直流偏置。為什麼是通過電阻來供電?電阻就象是供水系統中的水龍頭,用調節電流大小的。所以,三極管的三種工作 狀態“:載止、飽和、放大”就由直流偏置決定,在圖1中,也就是由R1、R2來決定了。 7)確定耦合電容C1和C2 C1與輸入阻抗,C2與連接在輸出端的負載電阻分別形成高通濾波器。要經過計算中心頻率勁兒得到C1和C2的值。 C1,C2為耦合電容,耦合就是起信號的傳遞作用,電容器能將信號信號從前級耦合到後級,是因為電容兩端的電壓不能突變,在輸入端輸入交流信號後,因兩端的電壓不能突變因,輸出端的電壓會跟隨輸入端輸入的交流信號一起變化,從而將信號從輸入端耦合到輸出端。但有一點要説明的是,電容兩端的電壓不能突變,但不是不能變。

    時間:2018-08-08 關鍵詞: 放大電路 三極管

  • 教你如何在短時間內快速掌握一款新的MCU

    任何一款MCU,其基本原理和功能都是大同小異,所不同的只是其外圍功能模塊的配置及數量、指令系統等。對於指令系統,雖然形式上看似千差萬別,但實際上只是符號的不同,其所代表的含義、所要完成的功能和尋址方式基本上是類似的。因此,對於任何一款MCU,主要應從如下的幾個方面來理解和掌握: * MCU的特點:要了解一款MCU,首先需要知道就是其ROM空間、RAM空間、IO口數量、定時器數量和定時方式、所提供的外圍功能模塊(Peripheral Circuit)、中斷源、工作電壓及功耗等等。 * 瞭解這些MCU 特點後,接下來第一步就是將所選MCU的功能與實際項目開發的要求的功能進行對比,明確那些資源是目前所需要的,那些是本項目所用不到的。對於項目中需要用到的而所選MCU不提供的功能,則需要認真理解MCU的相關資料,以求用間接的方法來實現,例如,所開發的項目需要與PC機COM口進行通訊,而所選的MCU不提供UART口,則可以考慮用外部中斷的方式來實現; * 對於項目開發需要用到的資源,則需要對其手冊進行認真的理解和閲讀,而對於不需要的功能模塊則可以忽略或瀏覽即可。對於MCU學習來講,應用才是關鍵,也是最主要的目的。 * 明確了MCU的相關功能後,接下來就可以開始編程了。對於初學者或初次使用此款MCU的設計者來説,可能會遇到很多對MCU的功能描述不明確的地方,對於此類問題,可以通過兩種方法來解決,一種是編寫特別的驗證程序來理解資料所述的功能;另一種則可以暫時忽略,程序設計中則按照自己目前的理解來編寫,留到調試時去修改和完善。前一種方法適用於時間較寬鬆的項目和初學者,而後一種方法則適合於具有一定MCU開發經驗的人或項目進度較緊迫的情況; * 指令系統千萬不要特別花時間去理解。指令系統只是一種邏輯描述的符號,只有在編程時根據自己的邏輯和程序的邏輯要求來查看相關的指令即可,而且隨着編程的進行,對指令系統也會越來越熟練,甚至可以不自覺地記憶下來; MCU的基本功能: 對於絕大多數MCU,下列功能是最普遍也是最基本的,針對不同的MCU,其描述的方式可能會有區別,但本質上是基本相同的: * Timer(定時器):Timer的種類雖然比較多,但可歸納為兩大類:一類是固定時間間隔的Timer,即其定時的時間是由系統設定的,用户程序不可控制,系統只提供幾種固定的時間間隔給用户程序進行選擇,如32Hz,16Hz,8Hz等,此類Timer在4位MCU中比較常見,因此可以用來實現時鐘、計時等相關的功能;另一類則是Programmable Timer(可編程定時器),顧名思義,該類Timer的定時時間是可以由用户的程序來控制的,控制的方式包括:時鐘源的選擇、分頻數(Prescale)選擇及預製數的設定等,有的MCU三者都同時具備,而有的則可能是其中的一種或兩種。此類Timer應用非常靈活,實際的使用也千變萬化,其中最常見的一種應用就是用其實現PWM輸出(具體的應用,後續會有特別的介紹)。由於時鐘源可以自由選擇,因此,此類Timer一般均與Event Counter(事件計數器)合在一起; * IO口:任何MCU都具有一定數量的IO口,沒有IO口,MCU就失去了與外部溝通的渠道。根據IO口的可配置情況,可以分為如下幾種類型: 1.純輸入或純輸出口:此類IO口有MCU硬件設計決定,只能是輸入或輸出,不可用軟件來進行實時的設定; 2.直接讀寫IO口:如MCS-51的IO口就屬於此類IO口。當執行讀IO口指令時,就是輸入口;當執行寫IO口指令則自動為輸出口 3.程序編程設定輸入輸出方向的:此類IO口的輸入或輸出由程序根據實際的需要來進行設定,應用比較靈活,可以實現一些總線級的應用, 如I2C 總線,各種LCD、LED Driver 的控制 總線等; 對於IO口的使用,重要的一點必須牢記的是:對於輸入口,必須有明確的電平信號,確保不能浮空(可以通過增加上拉或下拉電阻來實現);而對於輸出口,其輸出的狀態電平必須考慮其外部的連接情況,應保證在Standby或靜態狀態下不存在拉電流或灌電流。 * 外部中斷:外部中斷也是絕大多數MCU所具有的基本功能,一般用於信號的實時觸發,數據採樣和狀態的檢測,中斷的方式由上升沿、下降沿觸發和電平觸發幾種。外部中斷一般通過輸入口來實現,若為IO口,則只有設為輸入時其中斷功能才會開啓;若為輸出口,則外部中斷功能將自動關閉(ATMEL的ATiny系列存在一些例外,輸出口時也能觸發中斷功能)。外部中斷的應用如下: ** 外部觸發信號的檢測:一種是基於實時性的要求,比如可控硅的控制,突發性信號的檢測等;而另一種情況則是省電的需要; ** 信號頻率的測量;為了保證信號不被遺漏,外部中斷是最理想的選擇; ** 數據的解碼:在遙控應用領域,為了降低設計的成本,經常需要採用軟件的方式來對各種編碼數據進行解碼,如Manchester和PWM編碼的解碼; ** 按鍵的檢測和系統的喚醒:對於進入Sleep狀態的MCU,一般需要通過外部中斷來進行喚醒,最基本的形式則是按鍵,通過按鍵的動作來產生電平的變化; * 通訊接口:MCU所提供的通訊接口一般包括SPI接口,UART,I2C接口等,其分別描述如下: ** SPI接口:此類接口是絕大多數MCU都提供的一種最基本通訊方式,其數據傳輸採用同步時鐘來控制,信號包括:SDI(串行數據輸入)、SDO(串行數據輸出)、SCLK(串行時鐘)及Ready信號;有些情況下則可能沒有Ready信號;此類接口可以工作在Master方式或Slave方式下,通俗説法就是看誰提供時鐘信號,提供時鐘的一方為Master,相反的一方則為Slaver; ** UART(Universal Asynchronous Receive Transmit):屬於最基本的一種異步傳輸接口,其信號線只有Rx和Tx兩條,基本的數據格式為:Start Bit + Data Bit(7-bits/8-bits) + Parity Bit(Even, Odd or None) + Stop Bit(1~2Bit)。一位數據所佔的時間稱為Baud Rate(波特率)。對於大多數的MCU來講,數據為的長度、數據校驗方式(奇校驗、偶校驗或無校驗)、停止位(Stop Bit)的長度及Baud Rate是可以通過程序編程進行靈活設定。此類接口最常用的方式就是與PC機的串口進行數據通訊。 ** I2C接口:I2C是由Philips開發的一種數據傳輸協議,同樣採用2根信號來實現:SDAT(串行數據輸入輸出)和SCLK(串行時鐘)。其最大的好處是可以在此總線上掛接多個設備,通過地址來進行識別和訪問;I2C總線的一個最大的好處就是非常方便用軟件通過IO口來實現,其傳輸的數據速率完全由SCLK來控制,可快可慢,不像UART接口,有嚴格的速率要求。 * Watchdog(看門狗定時器):Watchdog也是絕大多數MCU的一種基本配置(一些4位MCU可能沒有此功能),大多數的MCU的Watchdog只能允許程序對其進行復位而不能對其關閉(有的是在程序燒入時來設定的,如Microchip PIC系列MCU),而有的MCU則是通過特定的方式來決定其是否打開,如Samsung的KS57系列,只要程序訪問了Watchdog寄存器,就自動開啓且不能再被關閉。一般而言watchdog的復位時間是可以程序來設定的。Watchdog的最基本的應用是為MCU因為意外的故障而導致死機提供了一種自我恢復的能力。 MCU程序的編寫: MCU的程序的編寫與PC下的程序的編寫存在很大的區別,雖然現在基於C的MCU開發工具越來越流行,但對於一個高效的程序代碼和喜歡使用匯編的設計者來講,彙編語言仍然是最簡潔、最有效的編程語言。對於MCU的程序編寫,其基本的框架可以説是大體一致的,一般分為初始化部分(這是MCU程序設計與PC最大的不同),主程序循環體和中斷處理程序三大部分(見圖1 a 和 b),其分別説明如下: * 初始化:對於所有的MCU程序的設計來講,出世化是最基本也是最重要的一步,一般包括如下內容: ** 屏蔽所有中斷並初始化堆棧指針:初始化部分一般不希望有任何中斷髮生; ** 清除系統的RAM區域和顯示Memory:雖然有時可能沒有完全的必要,但從可靠性及一致性的角度出發,特別是對於防止意外的錯誤,還是建議養成良好的編程習慣; ** IO口的初始化:根據項目的應用的要求,設定相關IO口的輸入輸出方式,對與輸入口,需要設定其上拉或下拉電阻;對於輸出口,則必須設定其出世的電平輸出,以防出現不必要的錯誤; ** 中斷的設置:對於所有項目需要用到的中斷源,應該給予開啓並設定中斷的觸發條件,而對於不使用的多餘的中斷,則必須給予關閉; ** 其他功能模塊的初始化:對於所有需要用到的MCU的外圍功能模塊,必須按項目的應用的要求進行相應的設置,如UART的通訊,需要設定Baud Rate,數據長度,校驗方式和Stop Bit的長度等,而對於Programmer Timer,則必須設置其時鐘源,分頻數及Reload Data等; ** 參數的出世化:完成了MCU的硬件和資源的出世化後,接下來就是對程序中使用到的一些變量和數據的初始化設置,這一部分的初始化需要根據具體的項目及程序的總體安排來設計。對於一些用EEPROM來保存項目預製數的應用來講,建議在初始化時將相關的數據拷貝到MCU的RAM,以提高程序對數據的訪問速度,同時降低系統的功耗(原則上,訪問外部EEPROM都會增加電源的功耗)。 * 主程序循環體:大多數MCU是屬於長時間不間斷運行的,因此其主程序體基本上都是以循環的方式來設計,對於存在多種工作模式的應用來講,則可能存在多個循環體,相互之間通過狀態標誌來進行轉換。對於主程序體,一般情況下主要安排如下的模塊: ** 計算程序:計算程序一般比較耗時,因此堅決反對放在任何中斷中處理,特別是乘除法運算; ** 實時性要求不高或沒有實時性要求的處理程序; ** 顯示傳輸程序:主要針對存在外部LED、LCD Driver的應用; * 中斷處理程序:中斷程序主要用於處理實時性要求較高的任務和事件,如,外部突發性信號的檢測,按鍵的檢測和處理,定時計數,LED顯示掃描等。一般情況下,中斷程序應儘可能保證代碼的簡潔和短小,對於不需要實時去處理的功能,可以在中斷中設置觸發的標誌,然後由主程序來執行具體的事務――這一點非常重要,特別是對於低功耗、低速的MCU來講,必須保證所有中斷的及時響應。 * 對於不同任務體的安排,不同的MCU其處理的方法也有所不同。例如,對於低速、低功耗的MCU(Fosc=32768Hz)應用,考慮到此類項目均為手持式設備和採用普通的LCD顯示,對按鍵的反應和顯示的反應要求實時性較高,應此一般採用定時中斷的方式來處理按鍵的動作和數據的顯示;而對於高速的MCU,如Fosc>1MHz的應用,由於此時MCU有足夠的時間來執行主程序循環體,因此可以只在相應的中斷中設置各種觸發標誌,並將所有的任務放在主程序體中來執行; * 在MCU的程序設計中,還需要特別注意的一點就是:要防止在中斷和主程序體中同時訪問或設置同一個變量或數據的情況。有效的預防方法是,將此類數據的處理安排在一個模塊中,通過判斷觸發標誌來決定是否執行該數據的相關操作;而在其他的程序體中(主要是中斷),對需要進行該數據的處理的地方只設置觸發的標誌。――這可以保證數據的執行是可預知和唯一的。

    時間:2018-08-07 關鍵詞: MCU 單片機

  • 複習!PWM基礎概念知識

     PWM脈寬調製,是靠改變脈衝寬度來控制輸出電壓,通過改變週期來控制其輸出頻率。而輸出頻率的變化可通過改變此脈衝的調製週期來實現。這樣,使調壓和調頻兩個作用配合一致,且於中間直流環節無關,因而加快了調節速度,改善了動態性能。 由於輸出等幅脈衝只需恆定直流電源供電,可用不可控整流器取代相控整流器,使電網側的功率因數大大改善。利用PWM逆變器能夠抑制或消除低次諧波。加上使用自關斷器件,開關頻率大幅度提高,輸出波形可以非常接近正弦波。

    時間:2018-08-07 關鍵詞: pwm

  • 單片機上拉電阻、下拉電阻的詳解和選取

     一、定義 1、上拉就是將不確定的信號通過一個電阻嵌位在高電平!“電阻同時起限流作用”!下拉同理! 2、上拉是對器件注入電流,下拉是輸出電流 3、弱強只是上拉電阻的阻值不同,沒有什麼嚴格區分 4、對於非集電極(或漏極)開路輸出型電路(如普通門電路)提升電流和電壓的能力是有限的,上拉電阻的功能主要是為集電極開路輸出型電路輸出電流通道。 二、拉電阻作用 1、一般作單鍵觸發使用時,如果IC本身沒有內接電阻,為了使單鍵維持在不被觸發的狀態或是觸發後回到原狀態,必須在IC外部另接一電阻。 2、數字電路有三種狀態:高電平、低電平、和高阻狀態,有些應用場合不希望出現高阻狀態,可以通過上拉電阻或下拉電阻的方式使處於穩定狀態,具體視設計要求而定! 3、一般説的是I/O端口,有的可以設置,有的不可以設置,有的是內置,有的是需要外接,I/O端口的輸出類似與一個三極管的C,當C接通過一個電阻和電源連接在一起的時候,該電阻成為上C拉電阻,也就是説,如果該端口正常時為高電平;C通過一個電阻和地連接在一起的時候,該電阻稱為下拉電阻,使該端口平時為低電平,作用嗎:比如:“當一個接有上拉電阻的端口設為輸入狀態時,他的常態就為高電平,用於檢測低電平的輸入”。 4、上拉電阻是用來解決總線驅動能力不足時提供電流的。一般説法是拉電流,下拉電阻是用來吸收電流的,也就是我們通常所説的灌電流 5、接電阻就是為了防止輸入端懸空 6、減弱外部電流對芯片產生的干擾 7、保護cmos內的保護二極管,一般電流不大於10mA 8、通過上拉或下拉來增加或減小驅動電流 9、改變電平的電位,常用在TTL-CMOS匹配 10、在引腳懸空時有確定的狀態 11、增加高電平輸出時的驅動能力。 12、為OC門提供電流 三、上拉電阻應用原則 1、當TTL電路驅動COMS電路時,如果TTL電路輸出的高電平低於COMS電路的最低高電平(一般為3。5V),這時就需要在TTL的輸出端接上拉電阻,以提高輸出高電平的值。…………………….. 2、OC門電路“必須加上拉電阻,才能使用”。 3、為加大輸出引腳的驅動能力,有的單片機管腳上也常使用上拉電阻。 4、在COMS芯片上,為了防止靜電造成損壞,不用的管腳不能懸空,一般接上拉電阻產生降低輸入阻抗,提供泄荷通路。 5、芯片的管腳加上拉電阻來提高輸出電平,從而提高芯片輸入信號的噪聲容限增強抗干擾能力。 6、提高總線的抗電磁干擾能力。管腳懸空就比較容易接受外界的電磁干擾。 7、長線傳輸中電阻不匹配容易引起反射波干擾,加上下拉電阻是電阻匹配,有效的抑制反射波干擾。 8、在數字電路中不用的輸入腳都要接固定電平,通過1k電阻接高電平或接地。 四、上拉電阻阻值選擇原則 1、從節約功耗及芯片的灌電流能力考慮應當足夠大;電阻大,電流小。 2、從確保足夠的驅動電流考慮應當足夠小;電阻小,電流大。 3、對於高速電路,過大的上拉電阻可能邊沿變平緩。綜合考慮 以上三點,通常在1k到10k之間選取。對下拉電阻也有類似道理。 對上拉電阻和下拉電阻的選擇應“結合開關管特性和下級電路的輸入特性進行設定,主要需要考慮以下幾個因素”: 1。驅動能力與功耗的平衡。以上拉電阻為例,一般地説,上拉電阻越小,驅動能力越強,但功耗越大,設計是應注意兩者之間的均衡。 2。下級電路的驅動需求。同樣以上拉電阻為例,當輸出高電平時,開關管斷開,上拉電阻應適當選擇以能夠向下級電路提供足夠的電流。 3。高低電平的設定。不同電路的高低電平的門檻電平會有不同,電阻應適當設定以確保能輸出正確的電平。以上拉電阻為例,當輸出低電平時,開關管導通,上拉電阻和開關管導通電阻分壓值應確保在零電平門檻之下。 4。頻率特性。以上拉電阻為例,上拉電阻和開關管漏源級之間的電容和下級電路之間的輸入電容會形成“RC延遲”,電阻越大,延遲越大。上拉電阻的設定應考慮電路在這方面的需求。 下拉電阻的設定的原則和上拉電阻是一樣的。 OC門輸出高電平時是一個高阻態,其上拉電流要由上拉電阻來提供,設輸入端每端口不大於100uA,設輸出口驅動電流約500uA,標準工作電壓是5V,輸入口的高低電平門限為0.8V(低於此值為低電平);2V(高電平門限值)。 選上拉電阻時:500uA x 8.4K= 4.2即選大於8.4K時輸出端能下拉至0.8V以下,此為最小阻值,再小就拉不下來了。如果輸出口驅動電流較大,則阻值可減小,保證下拉時能低於0.8V即可。當輸出高電平時,忽略管子的漏電流,兩輸入口需200uA,200uA x15K=3V即上拉電阻壓降為3V,輸出口可達到2V,此阻值為最大阻值,再大就拉不到2V了。選10K可用。【邯鄲到香港物流】 COMS門的可參考74HC系列設計時管子的漏電流不可忽略,IO口實際電流在不同電平下也是不同的,上述僅僅是原理,一句話概括為:“輸出高電平時要餵飽後面的輸入口,輸出低電平不要把輸出口喂撐了”(否則多餘的電流餵給了級聯的輸入口,高於低電平門限值就不可靠了) 此外,還應注意以下幾點: A、要看輸出口驅動的是什麼器件,如果該器件需要高電壓的話,而輸出口的輸出電壓又不夠,就需要加上拉電阻。 B、如果有上拉電阻那它的端口在默認值為高電平,你要控制它必須用低電平才能控制如三態門電路三極管的集電極,或二極管正極去控制把上拉電阻的電流拉下來成為低電平。反之, C、尤其用在接口電路中,為了得到確定的電平,一般採用這種方法,以保證正確的電路狀態,以免發生意外,比如,在電機控制中,逆變橋上下橋臂不能直通,如果它們都用同一個單片機來驅動,必須設置初始狀態。防止直通! 驅動儘量用灌電流。 電阻在選用時,選用經過計算後與標準值最相近的一個! P0為什麼要上拉電阻原因有: 1。 P0口片內無上拉電阻 2。 P0為I/O口工作狀態時,上方FET被關斷,從而輸出腳浮空,因此P0用於輸出線時為開漏輸出。 3。 由於片內無上拉電阻,上方FET又被關斷,P0輸出1時無法拉昇端口電平。 P0是雙向口,其它P1,P2,P3是準雙向口。準雙向口是因為在讀外部數據時要先“準備”一下,為什麼要準備一下呢? 單片機在讀準雙向口的端口時,先應給端口鎖存器賦1,目的是使FET關斷,不至於因片內FET導通使端口鉗制在低電平。 上下拉一般選10k!

    時間:2018-08-07 關鍵詞: 上拉電阻 單片機

  • 關於STC單片機IO口的狀態

     新入職一個公司,做智能家居的,只用宏晶51單片機。好長時間沒搞了,今天就遇到一個問題之前沒遇到過,就是配置IO口的工作類型。 數據手冊裏面是這樣説的,在此多説一句,數據手冊做的真爛。 這裏舉個例子。 如果給P1M1賦值0X03,給P1M0賦值0X05,那麼P1口各個引腳對應的模式就是: { P1M1=0x03=00000011b P1M0=0x05=00000101b } P1M1 P1M0 IO口模式0 0 P1.7準雙向口0 0 P1.6準雙向口0 0 P1.5準雙向口0 0 P1.4準雙向口0 0 P1.3準雙向口0 1 P1.2推輓輸出1 0 P1.1高阻1 1 P1.0開漏

    時間:2018-08-07 關鍵詞: stc 單片機

  • 51單片機內核的中斷及中斷向基礎知識

     51內核的最基礎的中斷源請求有外部中斷、定時器中斷和串口中斷,這也是學習和開發者最長用的。當然還有其他的中斷源,比如ADC、SPI、PWM等。以外部中斷0為例,在編程中常使用的方式為: void INT0()interrupt 0 using 1 { …… } 在這裏特別做上筆記:其中前面的void INT0() 只是代表一個普通沒有形參的函數而已,函數名寫成什麼都是可以的,這個到不重要。那麼後面的就一個一個詞的扣把:(2-1-i-c-中國-電子網,防抓取) 其中 interrupt n 組成一組,n用來指明中斷號,在函數後使用了interrupt關鍵字後,就會自動的生成中斷向量,51內核中斷號如下圖,這是我今天查的正在使用的MCU: 例如: 12 interrupt 1 指明是定時器中斷0; interrupt 2 指明是外部中斷1; interrupt 3 指明是定時器中斷1 。。。 對於51內核的MCU,不同廠家及不同型號的內部資源會有所不同,上圖是我正在開發的一款中穎SH88F516單片機,由上圖可見內部資源還算可以,能夠滿足一般的產品。後面的using n 指的是使用第n組寄存器。這個之前我在使用的過程中往往忽略了這個,也沒有出現什麼問題。但是今天注意到這個問題,查完資料後用上發現效果還不如不用,很有肯能是沒有把這個知識用好的原因把。對比之後給我的感覺是在使用C語言寫程序時,能不用就不用吧。查資料解釋説假如在中斷函數中使用了using n,中斷不再保存R0-R7的值,這也就意味着假如一個高優先級的中斷及一個低優先級的中斷同時使用了using n,而這個n恰恰相等,那就等着哭把,因為這個BUG還真不是那麼好找出來的(今天我就遇到了這個問題)。21ic整理 其次就是中斷優先級的問題了,如圖上面的中斷表,在右側第二欄標的很清楚,除了復位之外,就數外部中斷0優先級最高了,依次往下排列,那麼問題來了,今天剛好就碰到了需要串口0的優先級比定時器0的優先級高。沒辦法,只好接着啃數據手冊,還好這寄存器不多,一會就查到了下表和相關的描述: 所以按照描述修改下優先級就可以達到目的了。 總結:用到回過頭來用到51的中斷,發現有些東西在之前學習的時候並沒有太在意,導致現在在開發產品上使用的時候不清楚用途。因為工作跟學習性質是不一樣的,作為開發者的角度來説,質量往往是第一要求。同時會接觸到很多新鮮的事物和技術,但是話又説回來了,最基本的知識還是需要打牢。

    時間:2018-07-24 關鍵詞: 內核 51單片機

  • 單片機學習筆記之51內核軟件延時和串口的巧妙方法

     不知道大家學習51是怎麼過來的,反正我是一路忽悠過來的。現在用51來開發產品必須要充分用到它的內部資源,本來主頻、資源就比不上32,不充分的利用怎麼才能開發好的產品,那麼今天我又學習到兩個小技能:延時和串口的發送中斷 情況是這樣的,在產品的開發中,遇到了74HC595控制數碼管,這個數字邏輯芯片用過的都知道,一位數碼管還好,要是有多位那就得不斷的刷新,為快不破,進而達到不同位顯示不同斷碼(數字)的效果。這個刷新頻率還有講究,我不知道我的理論對不對,反正我知道民用電50Hz接在燈泡上,人眼是看不出燈泡在不斷的閃爍的。那麼就根據這個原理我只要保證在50Hz以上的頻率(20ms以內)及時的刷新一次顯示就行了。不過實際效果是我延時個5ms刷新一次才差不多看不到頻閃,延時是軟件的for循環延時,不太準,但是也差不多把。我也不明白為什麼要到5ms才能把頻閃給消除掉。反正就按照實際效果來咯。問題來了,5ms的週期性刷新,難道MCU就單純的給這個數碼管刷新不幹別的活了,這往往是不太可能的。那在調試的過程中我實現的方法是這樣的: 程序沒有操作系統,就是普通的while循環,一個循環裏面有很多任務,跑一趟下來時間可能比較長,那我就多copy幾個刷新函數唄,根據任務大概的耗時放置在不同的位置。這樣下來結果還是比較明顯的,最起碼效果好很多。接着就是新問題了,當一個任務函數執行的時間比較長的情況下,還是會出現頻閃,有朋友可能會想到,那就在任務函數裏面放刷新顯示函數唄,的確這是一個好方法。在程序中我也用到了。可是有些任務函數對時間要求比較嚴格,還就真的不能放在裏面干擾它的底層驅動程序。重點來了,我就來記錄下我使用的兩個方法; 1、 巧妙的使用任務函數本身的延時函數 例如我在工程裏面用到了DHT11温濕度傳感器,這個傳感器(包括DS18B20)是單總線協議,對時間要求相當嚴格,我就看着底層驅動去找,找到了一個時間相對來説比較長的地方: 上圖是DHT11的時序圖,紅線標註的地方是MCU給傳感器的其實信號,這裏手冊上説的是至少拉低18ms,那就在這個地方做文章,以下是我修改的代碼: 只是讓這個20ms的時間去幹點別的事情,就是刷新數碼管。當然了,如果有操作系統的話,操作系統延時的調用機制會把效率進一步提高。在這裏只要保證紅色方框內的執行時間和需要延時的時間差不多,保證能正常讀取到傳感器數據就行了,我也就估算出來的沒有實際測試時間,畢竟不方便仿真,不在公司手邊也沒有示波器。 2、串口發送中斷的使用 除了這裏的延時時間修改之外還有一個地方比較棘手,那就是串口發送一幀數據,一幀數據比較長,用一個個字節等待發送完成的方式太費時間了,其中又不好加上刷新函數,怎麼辦,突然想到了之前用過32的串口發送中斷。於是就查了下寄存器試用了下,還真可以。表示之前幾乎沒有用過串口的發送中斷,最多用過接收中斷。修改前和修改後的代碼如下: 註釋的就是一個個字節數序發送了,發送一個字節的函數原型如下: 修改後的串口中斷函數: 從代碼的結構來看,大致的原理就是在沒有數據需要發送的時候串口中斷處於關閉狀態,當有數據需要發送的時候,先把數據先準備好存儲在一個數組裏面,然後調用發送函數。發送函數的內容先是把串口的中斷打開(ES=1),清零發送完成標誌位(TI = 0),把需要發送的第一個數據放進以為寄存器(SBUF = dat[0]),把模擬的發送數據地址指向發送的第二個字節(因為第一個已經發送了),然後就等着中斷吧。每發送完成一個字節串口就會進入中斷函數,在中斷函數裏面先判斷是不是發送中斷(51內核串口的發送中斷和接收中斷使用的是同一個中斷向量),確保是發送中斷後先清除中斷標誌,然後繼續放入需要發送的下一個數據(SBUF = WIFI_TX_DATA[TX_CNT++];)同時需要發送的數據地址後移。判斷需要發送的數據是不是全部發送完成了,發送完了那就關閉串口中斷。這樣一幀數據就完美的發送完成而且效率有所提升! 上述方法只是一個簡單的處理,偵長度是定長14個字節,如果是不定長度的偵也是可以根據實際情況修改的。還有一個問題我在這裏沒有處理但是需要注意,那就是有一種情況需要考慮到,當一幀數據還沒有發送完成,新的一幀數據又需要發送。那麼這種情況就需要修改下存儲的方法了。這裏記上一筆,解決方式是把需要發送的數據存進一個相對大一點的數組裏面,然後給這個數組分配兩個指針,分別是頭指針(p)和尾指針(q),每次發送的時候先判斷是不是(p=q)如果是的話就證明之前的數據都發送完了,現在可以暢通無阻;如果不相等,那就繼續存儲並同時後移尾指針q的位置(如果溢出了那就重新回頭唄—循環數組的方法)。

    時間:2018-07-24 關鍵詞: 51內核 單片機

  •  先上一個低功耗的一鍵開關機電路,這個電路的特點在於關機時所有三極管全部截止幾乎不耗電。 原理很簡單: 利用Q10的輸出與輸入狀態相反(非門)特性和電容的電流積累特性。剛上電時Q6和Q10的發射結均被10K電阻短路所以Q6和Q10均截止,此時實測電路耗電流僅為0.1uA,L_out輸出高,H_out輸出低。此時C3通過R22緩慢充電最終等於VCC電壓,當按下S3後C3通過R26給Q10基極放電,Q10迅速飽和,Q6也因此飽和,H_out變為高電平,當C3放電到Q10be結壓降0.7V左右時C3不再放電,此時若按鍵彈開C3將進一步放電到Q10的飽和壓降0.3V左右,當再次按下S3,Q10即截止。 這個電路可以完美解決按鍵抖動和長按按鍵跳檔的問題,開關狀態翻轉只發生在按鍵接觸的瞬間,之後即便按鍵存在抖動或長按按鍵的情況開關狀態不會受到影響。這是因為R22的電阻很大(相對R23,R26,R25)當C3電容的電壓穩定後,R22遠不足以改變Q10的開關狀態,R22要能改變Q10的狀態必須要等S3彈開後C3將流過R22的小電流累積存儲,之後再通過S3的瞬間接觸快速大電流釋放從而改變Q10的狀態。 非低功耗的三極管一鍵開關機電路: 這個電路的原型來自互聯網,參數有調整,原理和第一個低功耗電路相似在此不再贅述。以上兩個電路都深入瞭解之後再看本帖的主題一鍵三檔電路: 這個電路實際就是本帖前兩個電路的融合,可以實現低功耗待機和1檔、2檔、關機等3個檔位。上電之初由於Q1,Q4,Q5的be結都並聯了電阻,因此所有三極管都截止電路低功耗待機,C3開始充電到VCC電壓。當按下S1後,Q5飽和,同時Q1也因此飽和,L_out1輸出低電平Q4截止—>Q3截止、Q2飽和,C3放電為0.3V(Q5的飽和壓降)左右。再次按下S1,Q5截止L_out1輸出高電平—>Q2截止,Q4飽和L_out2輸出低電平,由於R4和C1的延時作用Q3會延遲飽和,可以保證Q2完全截止後Q3基極才會為低電平,因此Q2,Q3都不會飽和。當再次按下S1,Q5由截止變為飽和L_out1再次輸出低電平—>Q2飽和(同時Q4截止),Q3飽和延遲—>Q1截止,電路進入待機狀態。

    時間:2018-07-24 關鍵詞: 三極管 單片機

  • 單片機有源蜂鳴器驅動之效率編程

     蜂鳴器是很常見的設備,分為無源和有源兩種。根據項目需求選擇不同類型的蜂鳴器。最近的項目裏有用到有源蜂鳴器對有源蜂鳴器。還是老一套,把電路板畫完,接着編程。 在項目中原理圖如下: 如果不能保證I/O的輸出性能可以根據情況增加上拉或者下拉電阻。 切入正題:在程序裏面這個蜂鳴器的驅動就是個高低電平驅動。高電平三極管導通、蜂鳴器發聲,低電平三極管關斷、蜂鳴器不發聲。這的確很簡單,程序上最開始我是這樣寫的: 當然,如果單片機沒有很好的I/O跳變函數也可以這樣修改: 這裏稍作解釋: 1) 函數功能:蜂鳴器發聲驅動 傳入參數:蜂鳴器發聲的次數 2) 傳入的次數cnt需要再函數內翻倍。這是因為傳入的參數是想讓蜂鳴器連續的發cnt聲。但是蜂鳴器除了發聲還有不發聲的時候。也就是説蜂鳴器每響一次都需要關閉一次,如果沒有關閉操作肯定就不會出現響幾聲而是連續的響一聲,這個也很容易推理。 3) 在while循環完之後需要加一個蜂鳴器關閉操作。 這裏假如傳進的參數是2,目的是讓蜂鳴器響兩聲。根據程序的執行步驟: cnt2變成4。 第1次while(4) 蜂鳴器開 cnt自減到3 第2次while(3) 蜂鳴器關 cnt自減到2 第3次while(2) 蜂鳴器開 cnt自減到1 第4次while(1) 蜂鳴器關 cnt自減到0 第5次while(0) 跳出while 可以看出其實在while之後蜂鳴器狀態已經是關閉的了,但是保險起見,確保函數調用完之後蜂鳴器是關閉的狀態。比如第一個函數I/O跳變的就更需要保障了,因為代碼上只能看出跳變,看不到跳變之後的狀態。 至此,一個簡單的蜂鳴器電路和驅動程序就都温習完了,接下來上乾貨: 在寫程序的時候很多時候講究程序的效率,比如這個蜂鳴器驅動,驅動過程中會降低效率,厲害的人很快能看出來,就是這個Delay延時的問題。但是上面也説了,不延時也是不行的。所以趨於效率我嘗試着換了一種方法驅動蜂鳴器。 代碼如下: 實現起來也很簡單,簡單説下原理: 1)首先是提供蜂鳴器驅動的I/O配置, 2)其次是定時器的配置 3)最後是定時器中斷函數實現 我選用的定時器是項目單片機中最簡單的一個定時器,配製成1ms中斷,能夠提供溢出中斷。其實這個定時器我常用做計系統運行時間Systick_ms。但是該項目對這個系統時間沒有用到,那就用這個定時器做文章把。 實現方法: 1、同樣函數在調用蜂鳴器驅動的時候接口是一樣的,傳入的參數還是蜂鳴器的響聲次數。 2、函數體變了,這裏改成了兩個變量的賦值,第一個BELL_CNT同普通方法中的cnt2,這裏不再贅述。第二個是FLAG_BELL是用來保存蜂鳴器是否需要驅動的狀態變量。所以既然是調用驅動函數,那肯定這個變量要為真。 3、定時器中斷函數裏面加上了一個靜態變量NOW,他的作用就是和Systic_ms產生一個50ms的時間片,幹嘛用?肯定是給蜂鳴器開關之間的延時用咯。模擬軟件延時嘛。然後再來分析下這段代碼: 1)首先這個NOW和Systic_ms是無條件需要賦值保證50ms時間片的。對應的代碼為NOW=Systick_ms+50; 2)判斷蜂鳴器驅動狀態變量是不是真,如果不為真就關閉蜂鳴器,這個也是無條件的。 3)如果狀態變量為真:蜂鳴器先跳變Bell_Tog();當然如果沒有這個跳變函數也可以用上述的判斷cnt的方法,就不多寫了都是一樣的。同時次數自減BELL_CNT--;同時判斷是不是減到0了,減到0了説明響完了啊,那就把狀態變量賦值為假。再次進來不管蜂鳴器是開着的還是關着的都會執行關閉操作,這個跟上面説的保險一樣。 4)最後,這兩個變量用的是全局變量,這裏是以結構體的形式呈現的,因為很多情況這兩個函數不在一個C裏面。如果硬要寫在一個C可以忽略本條。

    時間:2018-07-24 關鍵詞: 蜂鳴器 單片機

首頁  上一頁  1 2 3 4 5 6 7 8 9 10 下一頁 尾頁
發佈文章