PIC单片机精通_A/D转换异步串口通讯实例与详解
生活随笔
收集整理的這篇文章主要介紹了
PIC单片机精通_A/D转换异步串口通讯实例与详解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1.前言
串口通信這個話題對于很多做機電一體化、機器人控制等系統(tǒng)協(xié)調的同學,根本不陌生。計算機軟件(編程技術),近些年飛速發(fā)展。尤其是以機器學習、仿生控制、大數(shù)據(jù)為代表的AI行業(yè)。但是,軟件及算法永遠不會停留在“數(shù)學”這個圈圈里,我們需要把它推向工程,推向實踐。這樣作為軟硬件交流的“握手協(xié)議”的重要性就不言自明。 這一片主要介紹比較完整的串口通信代碼,具體為PIC16F876a與上位機進行數(shù)據(jù)交流的事。這個過程包括了模擬信號到數(shù)字信號的轉換、模擬信號采樣率、通信協(xié)議、計算機軟件、算法設計等一系列有趣的問題。有了硬件的數(shù)據(jù)采集模塊,我們就可以在軟件和算法上做更多的創(chuàng)新工作! 本篇主要集中討論以下問題: 1.定時器初值該如何計算? 2.PIC系列單片機的中斷優(yōu)先級是如何設置的? 3.AD采集模塊的數(shù)據(jù)存儲與發(fā)送原理是什么? 4.左對齊、右對齊的優(yōu)勢與劣勢的缺點又是什么?2.程序與代碼詳解
/************************************************** **Author: Shen Chunxu All Rights Reserved! **Tsinghua University 2016-11-20 **ad module + usart module **************************************************/ #include <pic.h> __CONFIG(0x3ffa); #define BAUD 9600 #define FOSC 9216000L #define BaudInitVal ((int)(FOSC/(16UL * BAUD) -1)) //高速情況下設定波特率初始值#define RX_PIN TRISC7 //定義數(shù)據(jù)通訊端口 #define TX_PIN TRISC6unsigned char Rece_flag; //初始化,串口接受標志 unsigned char Time_flag; //初始化,時鐘標志 unsigned int adResult; //保存ad轉換結果void InitAdusart(void); //初始化AD模塊、串口模塊 void InitTimer(void); //定時器1初始化void main() {INTCON = 0x00; //清空中斷控制器RX_PIN = 1; //端口RX TX初始化TX_PIN = 0;InitAdusart(); //串口、AD初始化InitTimer(); //定時器初始化,預裝初值//中斷控制GIE = 1; //允許全局中斷PEIE = 1; //允許外圍觸發(fā)中斷RCIE = 1; //開啟串口接收觸發(fā)中斷 TMR1IE = 1; //開啟定時器溢出中斷TMR1IF = 0; //定時器溢出標志位初始化RCIF = 0; //串口接收標志位初始化TMR1ON = 1; //開啟定時器Timer1while(1){//'S'對應上位機“開始”按鍵if( Rece_flag == 'S'){if( Time_flag == 1){ADGO=1; //開始ad轉換采集while( ADGO==1 ) continue; //等待轉換采集完畢//adResult = (unsigned int)ADRESH<<8 + ADRESL; // 右對齊10-bit//adResult = (unsigned int)(ADRESH<<6 + ADRESL>>2); //簡化運算 10bit->8bitadResult = ADRESH;//一次串口發(fā)送過程TXREG = adResult; //把AD結果送到發(fā)送緩存區(qū)while( TRMT == 0) //等待發(fā)送完畢continue; ///裝入初值,提供足夠的采樣時間Time_flag = 0; TMR1L=0xc0; //定時50msTMR1H=0xc7; }}} }//上位機發(fā)送信號觸發(fā)中斷 void interrupt Serve(void) {if( RCIF ) //串口接收中斷,優(yōu)先級最高{RCIF = 0; //軟件清空中斷標志位Rece_flag = RCREG;if('E' == Rece_flag) //對應上位機“結束”按鍵{//給PC機反饋信號“END”TXREG = 'E';while( TRMT == 0 ) continue; //檢驗發(fā)送是否結束TXREG = 'N';while(TRMT==0) continue;TXREG = 'D';while(TRMT==0)continue; }else if( 'S' == Rece_flag ){//給PC機反饋信號“OK”TXREG = 'O';while(TRMT==0) continue; TXREG = 'K';while(TRMT==0) continue; } else //其他信號不響應{ ; }}else if( TMR1IF ) //定時器溢出串口接收中斷,優(yōu)先級次之,主要控制(AD轉換時間+串口發(fā)送時間){TMR1IF = 0; //軟件清空定時器中斷標志位Time_flag = 1;} }// 串口、AD模塊 void InitAdusart(void) {//串口模塊初始化SPBRG = BaudInitVal; //設定波特率RCSTA=0x90; //1-0-0-1-0-0-0-0=串口工作-8位接收-禁止單字節(jié)-連續(xù)-空-無幀檢錯-無溢出檢錯-無奇偶校驗TXSTA=0x24; //0-0-1-0-0-1-0-0=異步不設置時鐘-8位發(fā)送-允許發(fā)送-異步-空-高速-TSR為空-無奇偶校驗//AD模塊初始化ADCON0=0x49; //01-001-0-0-1=FOSC/16-AN1-不轉換-空-上電//ADCON1=0xc9; //1-1-00-1001=右對齊-FOSC/16-空-VDD+VSS參考電壓(AN0~AN5)ADCON1=0x49; //0-1-00-1001=左對齊-FOSC/16-空-VDD+VSS參考電壓(AN0~AN5) } //Timer初始化 void InitTimer() {T1CON=0x30; //00-11-0-0-0-0=空-8分頻-禁止起振-定時器模式-內部時鐘-暫時不開啟TMR1L=0xc0; //定時50msTMR1H=0xc7; }3.注意事項
1.PIC系列僅僅提供提供了一個中斷服務程序,并沒有提供中斷優(yōu)先級寄存器。我們要向實現(xiàn)多級中斷有序進行,這里我提供了一種“分支語句+中斷標志位”結合的方法,實驗證明,該方法確實能夠做到中斷優(yōu)先級的管控!這里還是要提示一點,一如中斷,首先要清空中斷標志寄存器!!!這很重要! 2.關于定時器的初值問題。這里僅僅就PIC16F876a的16位Timer1而言。計算如下: ? 定時時間(s) = 分頻比*(2^16 - 處置)*指令周期 指令周期 = 4*時鐘周期 ? ? 時鐘周期 = 1/晶振頻率 切記!看好自己的晶振頻率在計算。4.思考與總結
1.利用定時器的精準定時功能,實現(xiàn)周期采樣的控制。 2.采用A/D左對齊的方式,使得數(shù)據(jù)讀取更方便。 3.多個分支或者多個條件控制時,提倡采用“設標”的方法進行程序設計!這可以大大提高程序的可讀性。在這里,講一下設標的心得,建議將標志位設為靜態(tài)變量或者全局變量,這可以大大提高程序的健壯性! 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的PIC单片机精通_A/D转换异步串口通讯实例与详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞鸽类能记住传书的人类
- 下一篇: ·必须《飞鸽~飞鸽传书》