It should not cause errors if you are using the correct register and bit names. What do the errors say?
Brian.
// Programmer : Hemnath
// Compiler : CCS C compiler
// Controller : PIC18F2520
// Description : To print ADC value in PC(Hyperterminal) using USART
#include <18F2520.h> // change header
#include "f2520_regs.h" // In this header i have declared all the registers with their corresponding values.
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000) // 4Mhz
//======================================
#define spbrg_value 25 //for --> (4Mhz/(16*9600))-1
unsigned int16 low_byte,high_byte;
unsigned int16 full_value,i=0;
unsigned char data[] = "ADC Value is : ";
void usart_init();
void main()
{
TRISC = 0x00;
TRISA = 0b00100000; // RA5 -input, rest as output
ADCON0 = 0b00010000; // analog channel 4
ADCON1 = 0b00001010; // ref volt. VSS and VDD. AN4 to AN0 as analog
ADCON2 = 0b10111100;
ADON = 1;
usart_init();
PEIE = 1;
GIE = 1;
while(1)
{
delay_us(50);
GO = 1; // to start conversion
while(GO==1); // wait for bit to be cleared
low_byte = ADRESL;
high_byte = ADRESH;
full_value = ((high_byte<<8)|low_byte);
for(i=0;data[i]!='\0';i++)
{
TXREG = data[i];
while(TXIF==0);
delay_ms(10);
}
delay_ms(100);
TXREG = ((full_value/1000)+0x30);
while(TXIF==0);
delay_ms(10);
TXREG = (((full_value/100)%10)+0x30);
while(TXIF==0);
delay_ms(10);
TXREG = (((full_value/10)%10)+0x30);
while(TXIF==0);
delay_ms(10);
TXREG = (((full_value/1)%10)+0x30);
while(TXIF==0);
delay_ms(10);
TXREG = 0x0A; // new line ascii value
while(TXIF==0);
delay_ms(10);
TXREG = 0x0D; // carriage return // which is 1st position...used to reset a device's position to the beginning of a line of text.
while(TXIF==0);
delay_ms(1000);
}
}
void usart_init() // usart initialization
{
SPBRG = spbrg_value;
TXSTA = 0x26;
RCSTA = 0x80;
}
In CCS c compiler, if you are making use of registers for programming, first you have to define the registers as #byte. Then only it won't show errors.
- - - Updated - - -
As you did in 1st program is correct. In C18 compiler, you don't have to define all the registers. But in CCS, it is must to define the registers before using in the program.
Also, i have to tell you,
you are using #use rs232 line in the program. CCS will take care of all the registers with this line you have mentioned. So you don't have to initialize usart registers. Directly you can use printf statement to display the value in the hyperterminal.
If you still want to make use of registers, edit the below program and make use of it. It reads the adc value and displays in the hyperterminal. It's a working program i have checked it in my case.
HTML:// Programmer : Hemnath // Compiler : CCS C compiler // Controller : PIC18F2520 // Description : To print ADC value in PC(Hyperterminal) using USART #include <18F2520.h> // change header #include "f2520_regs.h" // In this header i have declared all the registers with their corresponding values. #fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP #use delay(clock=4000000) // 4Mhz //====================================== #define spbrg_value 25 //for --> (4Mhz/(16*9600))-1 unsigned int16 low_byte,high_byte; unsigned int16 full_value,i=0; unsigned char data[] = "ADC Value is : "; void usart_init(); void main() { TRISC = 0x00; TRISA = 0b00100000; // RA5 -input, rest as output ADCON0 = 0b00010000; // analog channel 4 ADCON1 = 0b00001010; // ref volt. VSS and VDD. AN4 to AN0 as analog ADCON2 = 0b10111100; ADON = 1; usart_init(); PEIE = 1; GIE = 1; while(1) { delay_us(50); GO = 1; // to start conversion while(GO==1); // wait for bit to be cleared low_byte = ADRESL; high_byte = ADRESH; full_value = ((high_byte<<8)|low_byte); for(i=0;data[i]!='\0';i++) { TXREG = data[i]; while(TXIF==0); delay_ms(10); } delay_ms(100); TXREG = ((full_value/1000)+0x30); while(TXIF==0); delay_ms(10); TXREG = (((full_value/100)%10)+0x30); while(TXIF==0); delay_ms(10); TXREG = (((full_value/10)%10)+0x30); while(TXIF==0); delay_ms(10); TXREG = (((full_value/1)%10)+0x30); while(TXIF==0); delay_ms(10); TXREG = 0x0A; // new line ascii value while(TXIF==0); delay_ms(10); TXREG = 0x0D; // carriage return // which is 1st position...used to reset a device's position to the beginning of a line of text. while(TXIF==0); delay_ms(1000); } } void usart_init() // usart initialization { SPBRG = spbrg_value; TXSTA = 0x26; RCSTA = 0x80; }
PS EDIT and change for your case.
Best wishes
- - - Updated - - -
In your case, you can't find this "f2520_regs.h" header file. So comment this line which is second line in the program. and after #use delay line which is 4th line,
declare #byte and #bit for the registers you are using in the program.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <16F887.h> #device adc=10 #include <ctype.h> #include <errno.h> #include <math.h> #include <stdlib.h> #include <string.h> #fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP #use delay(clock=8000000) //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) #define LCD_ENABLE_PIN PIN_D2 #define LCD_RS_PIN PIN_D0 #define LCD_RW_PIN PIN_D1 #define LCD_DATA4 PIN_D3 #define LCD_DATA5 PIN_D4 #define LCD_DATA6 PIN_D5 #define LCD_DATA7 PIN_D6 #include <lcd.c> void main() { int16 adc_val = 0; float temp = 0, old_val = 0; set_tris_a(0xFF); set_tris_b(0xFF); set_tris_d(0x00); output_a(0x00); output_b(0x00); output_d(0x00); setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|sAN8|sAN9|sAN10|sAN11|sAN12|sAN13); setup_adc(ADC_CLOCK_DIV_2); setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard delay_ms(250); lcd_init(); delay_ms(250); lcd_putc("\fADC Example...\n"); set_adc_channel(0); delay_us(20); while(TRUE) { adc_val = read_adc(); delay_ms(20); temp = (float)(adc_val * 0.487012987012987); if(old_val != temp){ printf(lcd_putc, "\f%3.4f", temp); printf("Temperature is: %3.4f\r\n", temp); } old_val = temp; } }
compare the value of the registers in the program with the datasheet. why it is used. Then you will come to know.
I dunno how much you know about ADC and usart. Simply explaining the code makes no sense now.
Please read this tutorials which are explained clearly how to use ADC and usart.
then I'm sure you can edit the program of your own. Spare some time to learn.
ADC : **broken link removed**
https://www.edaboard.com/blog/1569/
For usart : **broken link removed**
See my attached project. I wrote that in CCS C. I have used PIC16F887 at 8 MHz. I have enabled all ADC channels. I have shown how to read one adc channel. I am new to CCS and still haven't found how to setup Vref for ADC. When I find that I will modify the code so that Vref+ will be 2V so that you will get more resolution.
I have done both adc and uart.
This is the CCS C Code
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <16F887.h> #device adc=10 #include <ctype.h> #include <errno.h> #include <math.h> #include <stdlib.h> #include <string.h> #fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP #use delay(clock=8000000) //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) #define LCD_ENABLE_PIN PIN_D2 #define LCD_RS_PIN PIN_D0 #define LCD_RW_PIN PIN_D1 #define LCD_DATA4 PIN_D3 #define LCD_DATA5 PIN_D4 #define LCD_DATA6 PIN_D5 #define LCD_DATA7 PIN_D6 #include <lcd.c> void main() { int16 adc_val = 0; float temp = 0, old_val = 0; set_tris_a(0xFF); set_tris_b(0xFF); set_tris_d(0x00); output_a(0x00); output_b(0x00); output_d(0x00); setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|sAN8|sAN9|sAN10|sAN11|sAN12|sAN13); setup_adc(ADC_CLOCK_DIV_2); setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard delay_ms(250); lcd_init(); delay_ms(250); lcd_putc("\fADC Example...\n"); set_adc_channel(0); delay_us(20); while(TRUE) { adc_val = read_adc(); delay_ms(20); temp = (float)(adc_val * 0.487012987012987); if(old_val != temp){ printf(lcd_putc, "\f%3.4f", temp); printf("Temperature is: %3.4f\r\n", temp); } old_val = temp; } }
The Proteus file is in the attachment. Try this new version. I have used ADC reference voltage. Extract the files to desktop. The Proteus file is also included.
1023 = 2V (max adc raw value for 2V) (2V is Vref)
x = 1.5V = 150 deg C (max value of LM35 output)
x = 767.25 raw adc value
-----------------------------------------------
If temperature is 48 deg C
767.25 = 150 deg C
y = 48 deg C
y = 245.52
-----------------------------------------------
245.52 * z = 48 deg C or
767.25 * z = 150 deg C
z = 48 / 245.52 = 0.1955034213098729
z = 150 / 767.25 = 0.1955034213098729
-----------------------------------------------
adc raw value = (Vin/Vref) * 1023
temp = adc_val * ( vref / 1023)
but I don't know why value should be multiplied by 100. If multiplied by 100 it gives correct value.
temperature = (adc value/1023.0)*2*100
////////////////////////////////////////////////////////////
I am having problems to connect to websites. Does anybody else have the same problem? If I open any webpage the http:// is replaced by https:// and the pages doesn't load.
I am experiencing this problem only with edaboard site.
////////////////////////////////////////////////////////////
In this thread I have posted pt100 project done in mikroC. Use the Calculation of temperature from adc value as I have done in the code. https://www.edaboard.com/threads/251334/
If you use 14 adc channels then you can't use Vref for adc. Is that ok?
See if this is ok.
See if this works. In Simulation it takes some time for pt100 value to get stabilized.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?