Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

UARTt 16f887 configuration reception and transmission

Status
Not open for further replies.
It should not cause errors if you are using the correct register and bit names. What do the errors say?

Brian.

when i rmove the #byte and #bit,all the register that i use the compiler tell me "undefined identificator" or something like that !!
 

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.
 

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.

thanks a lot hemnath :))
i'll try to use it and i'll tell you if i find problems ;)

just one thing,if you can briefly comment each line of your code and post it again so that I can better understand how it works that will help me to use it :)
 
Last edited:

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;
   }
 
}

 

Attachments

  • pic16f887.rar
    66.6 KB · Views: 65
  • adc_w.jpg
    adc_w.jpg
    326.7 KB · Views: 72

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**

thanx alot for tutorials hemnath,i'll take my time reading it ;)

- - - Updated - - -

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;
   }
 
}


thanks alot jayanth for your time,i'll try your code and i'll tell you if i find a problem
ijust if you can post the isis simulation file for me.
thank you an other time ;))
 
Last edited:

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.
 

Attachments

  • pic16f887 v2.rar
    92.3 KB · Views: 67
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.

thaaaaaaaaaaaaaaaanks jayanth it works normally, just one thing, the number "0.196078431372549" I did not understand what it represent?
pleaaaaaaaaase if you can sit comment with each line i'll be thankfull :))
 

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.

////////////////////////////////////////////////////////////
 
Last edited:

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.

////////////////////////////////////////////////////////////

thaaaaaanx jayanth but i work widh "pt100" not "LM35"
with pt100, 0 deg C= 100 ohm (resistance)
or read_adc() gives me a tension in volt,so to have temperature value we have to use the relation between temperature,resistance and tension:
v=read_adc()
R=v/I (I=1mA )
Temp=(R-1)/25974.025
thats my idea,but when i try to use this mathematic it gives anything in sumilation (always zero),i do know what's the problem !!
 
Last edited:

thanx alot jayanth for your help,it's work successfully with one input,
now i need your help to make it work with 14 input channel(all the adc input) and gives 14 temperature value because i have 14 pt100.
i'll be thankfull if you help me :)
 
Last edited:

If you use 14 adc channels then you can't use Vref for adc. Is that ok?

am not understand :(

anyway,i'll post the code who work with one input channel (your code) and if you can modify it to make it work with 14 input i'll be thankfull

the code:

#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;
}

}
 

See if this is ok.

it's work but i have 2 problems:
1- it's give 12 temperature value but i need 14 temperature value
2- when i simulate with my isis file the température value of channel 4,5,6 and 7 is wrong
anyway i'll post the code and my ISIS file,if you can simulate it and find solution for this 2 problems cause i'm tryed but i'm not succed

another thing, I use potentiometers (POT-HG) to replace the pt100 in simulation, I ask you if you can replace them with "RTD-pt100" because I failed to do it by myself .But if you can't, no problem .
and thank you an other time ;)

that's my prog and my ISIS file:
 

Attachments

  • edboard.rar
    71.5 KB · Views: 64

See if this works. In Simulation it takes some time for pt100 value to get stabilized.

89068d1365514038-pt100ccsc.jpg
 

Attachments

  • edboard.rar
    112.9 KB · Views: 61
  • pt100ccsc.jpg
    pt100ccsc.jpg
    341.7 KB · Views: 118
  • edboard v2.rar
    113 KB · Views: 61
Last edited:

i just want to ask
when using the uart
is there need to use microcontroller like MAX3222
i want to develop visible light communication
computer --> uart --> transistor --> LED
so is there need to use microcontroller between uart and transistor to make LED blinking?
or uart alone can do the task?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top