Reputation: 19
I'm beginner to micro controller technology. I want to transmit the 10-bit output I got from an Analog to Digital Conversion, but only 8 bits can be sent via the UART. How can I send 10 bits?
Please help me to write C code to solve this problem. My code so far is given below. The compiler used is 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
}
}
Upvotes: 1
Views: 1995
Reputation: 154208
Typical UARTs do not allow for more than 8 bits of data per transmission. Some allow 9. Sending 10 bits may be available on select UARTS using 9 bits and controlling the parity, but that is rare.
Instead recommend to send the data as 2 transmission with a bit set aside to denote which half is sent.
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
}
On receiver side, insure bytes received are in the proper byte order. This will re-construct the received data in the proper order, even if reception does not start in phase or if a byte was lost in communication.
// 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;
}
Upvotes: 1
Reputation: 34583
You are reading a 10-bit ADC result with like this
return ((ADRESH>>2)+ADRESL);
But the function is return unsigned char
, it should be unsigned int
unsigned int read_input(unsigned char channel)
and the calling function is also throwing away two bits with
unsigned char x=read_input(0);
which should be
unsigned int x=read_input(0);
Having read a 10-bit value into a (presumably) 16-bit variable, you now have to transmit it to the serial port. Let's do this by sending the most significant 8 bits first.
TX (x >> 8);
TX (x & 0xFF);
Then at the receiver end you read the two bytes and put them back together
unsigned adcval = RX() << 8;
adcval |= RX();
Upvotes: 0