2015-05-26 105 views
0

我是微控制器技術的初學者。我想傳輸從模數轉換器得到的10位輸出,但只能通過UART發送8位數據。我怎樣才能發送10位?通過PIC16F877A的UART發送10bit數據

請幫我寫C代碼來解決這個問題。我的代碼到目前爲止在下面給出。使用的編譯器是XC8。

#pragma config PWRTE = OFF  // Power-up Timer Enable bit (PWRT disabled) 
#pragma config BOREN = ON  // Brown-out Reset Enable bit (BOR enabled) 
#pragma config LVP = OFF  // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) 
#pragma config CPD = OFF  // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) 
#pragma config WRT = OFF  // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) 
#pragma config CP = OFF   // Flash Program Memory Code Protection bit (Code protection off) 
#define _XTAL_FREQ 4000000 

#include <stdio.h> 
#include <stdlib.h> 

#include <htc.h> 

void uart_init(void); 
void TX(unsigned char TX_BYTE); 
void configure_pins(); 
unsigned char read_input(unsigned char channel); 

void main() 
{ 
    __delay_ms(2); 
    while (1) { 
     TRISB = 0; //configuring portB as output 
     TRISC = 0; 
     TRISA = 1; 

     configure_pins();     //calling methods 
     unsigned char x = read_input(0); 
     uart_initialize(); 
     assign_data_to_tx_pin(x); 
    } 
} 

void configure_pins(){ 
    ADCON1 = 0b10000000;    //The result is right justified 
} 

unsigned char read_input(unsigned char channel){ // converting the Analog input to digital 
    ADCON0=0b00000000; 
    CHS0=0;     // AN0 is selected 
    CHS1=0;     // " 
    CHS2=0;     // " 

    ADON = 1; 
    GO_DONE = 1; 

    while (GO_DONE); 
    ADON = 0; 
    return ((ADRESH >> 2) + ADRESL);  // return the result of conversion 
} 

void uart_initialize(void)   // initializing the UART for data transmission 
{ 

    TRISC = 0;   //configuring portC as output 

    TXSTA = 0b100000000; 
    TXEN = 1;   //enable transmission mode 
    SPEN = 1;   //enable UART 
    BRGH = 0;   //enable low baud 
    SPBRG = 6;   //set baud rate as 9600 
    SYNC = 0;   //enable asynchronous transmission 

    RCIE = 1; 
    GIE = 1; 
    PEIE = 1; 
} 

void assign_data_to_tx_pin(unsigned char converted_data) { // assigning the data to the Tx pin for transmission 
    while(!TRMT) { 
     unsigned char a = converted_data; 

     TXREG = a; 
     TXREG = a >> 2; 
     PORTCbits.RC6 = TXREG; 

     __delay_ms(100); // Delay 
    } 
} 
+0

您可以發送從'ADRESH'和'ADRESL'中讀取的兩個8位值。即使有些位未被使用,你也不能傳送它們。如果您將它們組合爲16位值,則仍然必須以兩個8位值進行傳輸。 –

+0

非常感謝。 –

+0

然後精度等級從1024 t0減少256.不是嗎? –

回答

0

您正在閱讀的10位ADC結果像這樣

return ((ADRESH>>2)+ADRESL); 

但功能恢復unsigned char,它應該是unsigned int

unsigned int read_input(unsigned char channel) 

,並調用函數也扔掉兩位

unsigned char x=read_input(0); 

這應該是

unsigned int x=read_input(0); 

讀完一個10位的值轉換成(推測)16位變量,你現在有將其傳送到串行端口。我們首先發送最重要的8位數據。

TX (x >> 8); 
TX (x & 0xFF); 

然後在接收端你讀的兩個字節,並把他們重新走到一起

unsigned adcval = RX() << 8; 
adcval |= RX(); 
+0

非常感謝你 –

+0

@ChamiPerera事後認爲,這個(ADRESH >> 2)+ ADRESL)'不可能是正確的。假設兩個ms位是b0和b1,它應該是'((ADRESH << 8)&3)+ ADRESL)' –

+0

你能否告訴我3的目的?(ADRESH <<8) & 3> –

0

典型的UART不允許每個傳輸的數據超過8位。有些允許9.發送10位可以在選擇UARTS上使用9位並控制奇偶校驗,但這很少見。

而是建議發送數據作爲2傳輸,並留出一定的位以表示發送了哪一部分。

Send_ADC(void){ 
    ADCON0=0b00000000; 
    CHS0=0;     // AN0 is selected 
    CHS1=0;     // " 
    CHS2=0;     // " 
    ADON = 1; 
    GO_DONE = 1; 
    while (GO_DONE); 
    ADON = 0; 
    unsigned adc10 = ((ADRESH >> 2) + ADRESL); 
    assign_data_to_tx_pin((adc10 % 32) * 2 + 0); // 00lllll0 
    assign_data_to_tx_pin((adc10/32) * 2 + 1); // 00hhhhh1 
} 

在接收端,確保收到的字節是正確的字節順序。這將按照正確的順序重新構造接收到的數據,即使接收不是同相啓動或通信中丟失了一個字節。

// return 0: success, else 1 
int ReadSerialADC(unsigned *data) { 
    unsigned adc; 
    unsigned low = read_from_comport(); 
    if (low %2) return 1; 
    low /= 2; 
    unsigned high = read_from_comport(); 
    if (high %2 == 0) return 1; 
    high /= 2; 
    *data = high * 32 + low; 
    return 0; 
} 
+0

非常感謝 –