Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PWM from PIC16F877a....

Status
Not open for further replies.
The first bit of code... This receives a ascii string followed by a carriage return

Its converted to a decimal int and then sent to the PWM

C:
#include <htc.h>
#include <stdlib.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000
 
unsigned char inbuff[12];					// Transmision buffer
void  HSerinit(void), HserinString(unsigned char*);
unsigned char Hserin(void);					// transmission functions
int getInt(unsigned char* str);			// a sort of atoi
 
void main()
	{
	int rxdata;				// incomming data store
	PR2 = 0b11111001 ;
	T2CON = 0b00000100 ;   
	CCP1CON = 0b00111100;                  
	ADCON1 = 0x6;                 
	HSerinit();  
	while(1)
		{
		HserinString(inbuff);		// get incomming data
		rxdata = getInt(inbuff);	// turn to decimal
   		CCPR1L = (unsigned char)rxdata ;// set PWM
		}
	}

void HserinString(unsigned char* str)
	{
	int i = 0;
	while(str[i++] != 0x0D)	// wait for carriage return
		str[i] = Hserin();	// get next character
	
	}

int getInt(unsigned char* str) // sort of atoi
	{
	int result = 0;
	while(*str !=0x0D)		// until we see carriage return
		{
		if(*str >0x29 && *str < 0x3A)	// Is it a number
			{
			result*=10;
			result+= *str - 0x30;		// convert to int
			}
		str++;
		}
	return result;		// all done
	}

unsigned char Hserin(void)
	{
	while(!RCIF);
	return RCREG;	
	}

void HSerinit()
	{
    TRISC = 0x80;                    // TX was an input!
    SPBRG = 129;                    // 20Mhz xtal 9600 BAUD
    TXSTA = 0x24;                    // TXEN and BRGH
    RCSTA = 0x90;                    // SPEN and CREN
	}

Then we have the opposite... Turns the analogue value into ascii text and sends it..

C:
#include <htc.h>
#include	<stdio.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000
 
unsigned char outbuff[12];
void  HSerinit(void), HseroutString(unsigned char* str), Hserout(unsigned char ch);
int getADC(void);
 
void main(void)                        
    { 
	int txdata;		// data to transmit
	TRISA = 0xff ;                             
    HSerinit();
	__delay_ms(150);
    while(1)                
        {
		txdata = getADC();				// get analogue value on RA0
		sprintf(outbuff,"%d\r",txdata);	// convert to ascii text
		HseroutString(outbuff);			// send data
	    }
	}

void HseroutString(unsigned char* str)
	{
	while(*str != 0)			// while all transmitted
		Hserout(*str++);	
	}

void Hserout(unsigned char ch)
	{
	while(!TXIF);
	TXREG = ch;	
	}

int getADC()
	{
	ADCON1=0b00000000;
	ADCON0=0b10000001;	//000 = channel 0, (RA0/AN0)
	__delay_ms(10);
    GO_DONE=1;
	__delay_ms(10);
    while(GO_DONE);                 
	return ADRESH;              
	}

void HSerinit()
	{
    TRISC = 0x80;                    // TX was an input!
    SPBRG = 129;                    // 20Mhz xtal 9600 BAUD
    TXSTA = 0x24;                    // TXEN and BRGH
    RCSTA = 0x90;                    // SPEN and CREN
	}
 
Hi,

Can you explain me this??

Code:
void HserinString(unsigned char* str)
	{
	int i = 0;
	while(str[i++] != 0x0D)	// wait for carriage return
		str[i] = Hserin();	// get next character
 
	}
 
int getInt(unsigned char* str) // sort of atoi
	{
	int result = 0;
	while(*str !=0x0D)		// until we see carriage return
		{
		if(*str >0x29 && *str < 0x3A)	// Is it a number
			{
			result*=10;
			result+= *str - 0x30;		// convert to int
			}
		str++;
		}
	return result;		// all done
	}
 
hi Ritesh,

Exactly which part of that code do you not understand.??

I have never studied 'C' or ever used it , but even I can follow that code fragment OK.

Eric
 
Ritesh.... I'm converting the ADC value to a ASCII string for easy sending....

HserinString() will read a string from the serial port that is terminated with "0x0D" carriage return..

getInt().. changes the string back to a decimal number so you can load the CCPR1L register..

I have even commented the procedure..
 
I think you should give up!!!! Have you any idea about ASCII characters?? If you type ASCII into the google engine and look at the several ASCII references above...

If I asked you what ASCII character "0x35" represents.... Would you be able to tell me.
 
If I asked you what ASCII character "0x35" represents.... Would you be able to tell me.

it represent 5. OK, we do - 0x30 to get its decimal number/ASCII then why we multiply by *10?

i got this..
if(*str >0x29 && *str < 0x3A)

In ASCII why 0x0D is used here??for carriage return so, what it is doing here??
 
string "12345", 0x0D

value = 0

loop
If character is a digit ( 0x30 to 0x39)
multiply value by ten first ( as the value is 0 to start with the first multiply does nothing )
then add to your value by removing the ASCII content (0x30)
go back to the loop if we didn't get the end of string ASCII (0x0D)


value = 12345....

See not very difficult is it!!
 
multiply value by ten first ( as the value is 0 to start with the first multiply does nothing )
hi again,

but we need to multiply it by 10??

string "12345", 0x0D
from where string is coming because we are using only ADC result to send..

what is the use of CR here?? i am listing it first time..??
Often abbreviated CR, a carriage return is a special code that moves the cursor (or print head) to the beginning of the current line. In the ASCII character set, a carriage return has a decimal value of 13.
 
I send ASCII text rather than decimal... Its a lot more robust.... Just sending a binary number over RS232 isn't good enough.

Note in the other code I send the ADC value as a string terminated by 0x0D so I could test it in the terminal....
 
A string..... Ritesh... A string!!!

NOT 12345... It comes in in ASCII.... " 0x31,0x32,0x33,0x34,0x35,0x0D" 6 characters make the number 12345...

0*10+1 = 1
1*10 + 2 = 12
12*10+3 = 123
123*10+4 = 1234
1234*10+5 = 12345

It's not that hard to understand.....
 
Last edited:
I send ASCII text rather than decimal... Its a lot more robust.... Just sending a binary number over RS232 isn't good enough.

Note in the other code I send the ADC value as a string terminated by 0x0D so I could test it in the terminal....

POST #52

I really don't believe you don't understand this...


1st Pic reads ADC.
1st Pic converts ADC result to a string.
1st Pic sends string via RS232.

2nd Pic receives string via RS232.
2nd Pic converts string to a decimal number.
2nd Pic controls the PWM module with result.

Job done... How hard is that to understand...
 
[MODNOTE]Deleted Off Topic[/MODNOTE]
 
Last edited by a moderator:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top