會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





UART-RS232通訊
新會員
註冊日期:
7月31日 12:08:57
所屬群組:
註冊會員
文章: 4
等級: 1; EXP: 21
HP : 0 / 5
MP : 1 / 3
離線
不好意思前輩們小弟最近才剛開始學微控制器有些地方真的不是很懂請大家多多包涵,而這是小弟寫出來的程式,問題是終端機出來的ASCII碼都會一直跑下去無法按p讓它暫停同時也不確定按c是否有作用
#include <stdio.h>
#include <stdlib.h>
#include <p18f4520.h> //納入微控制器定義檔
#include <delays.h> //納入延遲檔
#include <adc.h>//納入類比訊號轉換函式庫定義檔
#include <timers.h>
#include <usart.h>

// 結構位元定義
#pragma config OSC=HS, BOREN=OFF, BORV = 2, PWRT=ON, WDT=OFF, LVP=OFF

#define TML1_VAL 32768 //設定1000ms中斷一次
#define DE PORTBbits.RB0
//宣告中斷執行程式
void timer1_isr(void);
void Rx_isr(void);
//狀態旗標變數
struct Flag
{
unsigned One_S :1;
unsigned TxD :1;
} FLAGbits;
//定義低優先中斷執行程式位址及內容
#pragma code low_vector = 0x18

void low_interrupt(void) {
_asm GOTO timer1_isr _endasm
}
#pragma code

#pragma interruptlow Rx_isr

void Rx_isr(void) {
unsigned char RX_Temp;
PIR1bits.RCIF = 0;
//RX_Temp=ReadUSART();


PORTB = RX_Temp;
if(RX_Temp=='c') FLAGbits.TxD=0; //c傳送資料
if(RX_Temp=='p') FLAGbits.TxD=1; //p停止傳送

}

//定義高優先中斷執行程式位址及內容
#pragma code high_vector = 0x08

void high_interrupt(void) {
_asm GOTO timer1_isr _endasm
}
#pragma code

#pragma interrupt timer1_isr

void timer1_isr(void) {
PIR1bits.TMR1IF = 0;
WriteTimer1(TML1_VAL);
FLAGbits.One_S=1;
}
void main(){
unsigned char result;
PORTD = 0x00;
TRISD = 0;

//開啟類比訊號轉換模組
OpenADC(ADC_FOSC_32 &
ADC_RIGHT_JUST &
ADC_20_TAD,ADC_CH0 &
ADC_INT_OFF &
ADC_VREFPLUS_VDD &
ADC_VREFMINUS_VSS,14);
//開啟USART通訊界面 設定8-N-1-9600 開啟資料接收中斷功能
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64);
PIR1bits.RCIF = 0;//清除中斷旗標
IPR1bits.RCIP = 0;//設定為低優先中斷

OpenTimer1(TIMER_INT_ON & // 使用C18編譯器timer函式庫
T1_16BIT_RW & // 初始化設定Timer1
T1_SOURCE_EXT & // 並開啟TIMER1中斷功能
T1_PS_1_1 &
T1_OSC1EN_ON &
T1_SYNC_EXT_ON);
WriteTimer1(TML1_VAL); //寫入預設值
PIR1bits.TMR1IF = 0; // 清除中斷旗標
IPR1bits.TMR1IP = 1;//設定為高優先中斷

RCONbits.IPEN=1;
INTCONbits.GIEL = 1; //開啟低優先中斷
INTCONbits.GIEH = 1; //開啟高優先中斷

FLAGbits.TxD = 0;
FLAGbits.One_S = 0;

while(1){
while(FLAGbits.TxD==1);//判斷資料傳送狀態旗標
DE=0;
if(FLAGbits.One_S==1){
FLAGbits.One_S=0;
Delay10TCYx(5);
ConvertADC();
while(BusyADC());

//將10位元資料分三次傳出
WriteUSART(ADRESH+0x30);

while(BusyUSART());

result=(ADRESL>>4);
if(result>9) result += 0x37;
else result+=0x30;
WriteUSART(result);
while(BusyUSART());

result=ADRESL&0x0F;
if(result>9) result += 0x37;
else result+=0x30;
WriteUSART(result);
while(BusyUSART());


WriteUSART(0x0A);
while(BusyUSART());
WriteUSART(0x0D);
while(BusyUSART());
if(DE==1)
{
DE=0;
}


}

}
}

8月01日 14:29:15
轉換PDF檔 列印


Re: UART-RS232通訊
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14499
等級: 73; EXP: 6
HP : 1080 / 1801
MP : 4833 / 76139
離線
#pragma interruptlow Rx_isr

void Rx_isr(void) {
unsigned char RX_Temp;
PIR1bits.RCIF = 0;
//RX_Temp=ReadUSART();

PORTD = RX_Temp;
if(RX_Temp=='c') FLAGbits.TxD=0; //c傳送資料
if(RX_Temp=='p') FLAGbits.TxD=1; //p停止傳送

}

在低修先權的接收中斷函式裡並沒有去讀取 UART 的接收暫存器,所以就無法設定是否有收到 "p" 的字元。

啟動一下接收 //RX_Temp=ReadUSART(); 將 // 註解移除後試看看

或直接看 PORTD 的結果。

8月01日 14:54:42
轉換PDF檔 列印


Re: UART-RS232通訊
新會員
註冊日期:
7月31日 12:08:57
所屬群組:
註冊會員
文章: 4
等級: 1; EXP: 21
HP : 0 / 5
MP : 1 / 3
離線
不好意思還是一樣問題,我覺得是DE那邊有出問題在那半雙工裡我在那時間點的切換真的不太會除錯

8月02日 09:25:32
轉換PDF檔 列印


Re: UART-RS232通訊
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14499
等級: 73; EXP: 6
HP : 1080 / 1801
MP : 4833 / 76139
離線
#pragma interruptlow Rx_isr

void Rx_isr(void) {
unsigned char RX_Temp;
PIR1bits.RCIF = 0;
RX_Temp=ReadUSART();
PORTD = RX_Temp;

if(RX_Temp=='c')
FLAGbits.TxD=0; //c傳送資料
if(RX_Temp=='p') FLAGbits.TxD=1; //p停止傳送

}

修改過的低修先權中斷的函式如上。先顯查一下當終端機按下任何鍵時,PORTD 的 LED 是否會隨著不同的按鍵而有不同的變化。這是你所要檢查的第一步。

你所說的 DE 在程式裡看不出它的作用為何?
建議刪除 DE 的部分。

不知你會不會用斷點及變數的觀察? 這對你的除錯會有很大的幫助的。因為你使用 C18 所以應該是使用舊版的 MPLAB IDE。可以參考教育訓練 W401 的教材及範例,在第五章節就有類似你的範例可以參考。

8月02日 11:13:57
轉換PDF檔 列印


Re: UART-RS232通訊
新會員
註冊日期:
7月31日 12:08:57
所屬群組:
註冊會員
文章: 4
等級: 1; EXP: 21
HP : 0 / 5
MP : 1 / 3
離線
不好意思我所用的是MPLAB X IDE,也跟你說聲抱歉我沒跟你說明清楚我所用的通訊是SN75176所以才用到DE,可以在請問你,我也找了很多資料,那我現在所轉換是ASC是16進至想轉換0~5的電壓值來量測可變電阻值?
他現在所包含是1024位元我現在知道要/1024在*5,那我現在是想說要再重新定義一個電壓值轉換完後讓他在0~5伏內嗎再都到傳送數值嗎

8月03日 11:29:33
轉換PDF檔 列印


Re: UART-RS232通訊
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14499
等級: 73; EXP: 6
HP : 1080 / 1801
MP : 4833 / 76139
離線
如果是使用到辦雙工的 RS-485 則 DE 的輸出控制的啟用是很重要的。在第一次送出 UART 之前 (WriteUSART(ADRESH+0x30);) 就需要 Enable DE 的輸出值到這個封包的結束送完 0x0A & 0x0D 的資料。
種要的是因為 while(BusyUSART()); 檢查的是 TXIF 為 1 了嗎? 實際上最後一筆 0x0D 的資料還在 TSR Register 等待移出到 TxD 的腳位,所以這時切斷 DE 會造成最後一筆的 0x0D 的資料無法送出。解決方法有一是檢查 TMRT 位元是否變成 1 了,還有就是加上 Delay 延遲一個 10 x bps 的時間後再關閉 DE,這樣最後一個 Byte 0x0D 才能完整的送出。

8月03日 13:47:53
轉換PDF檔 列印


Re: UART-RS232通訊
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14499
等級: 73; EXP: 6
HP : 1080 / 1801
MP : 4833 / 76139
離線
關於 ADC 值轉電壓的顯示:

這只是觀念問題,千萬不要用浮點運算來寫,使用整數的運送即刻完成。

在 8-Bits MCU 相關課程下的 W301 Advance PICC Application 的教育訓練裡的練習六就有此應用,參考如下的說明:

程式裡顯示電壓值到mV 是怎樣做到的?
􀂄 Disp_Temp = (((unsigned long) Temp_Buff ) *
4883 ) / 100 ;
Temp_Buff 是 ADC 0 ~ 5V 轉換的結果,unsigned long 是轉型運算,因為是 16-bit ADC x 4883 (16-bit) 後必須用 long 來接資料。

􀂄 5V / 1024 = 4.883 mV , 要顯示4.9mV 的精度
1 bit = 488300uV x ADC 的值後,再除以 100 就可以得到 0.1mV 的經度後,再種 ASCII Code 顯示即可。

􀂄 不要使用浮點數運算,只要用整數運算即可

8月03日 13:59:51
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
Microchip連結

網頁捷徑
2018 Winter Elite 報名
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project