SilverWingz
New Member
I am working on a PIC 16F877A Kit.
The objective is to drive a motor using a pwm and to receive and display the feedback from the quadrature encoder on the LDC module.
Here is the code for feedback display:
This,by itself works just fine
The problem i ran into,was when i tried integrating a PWM generation along with this code.
The kit i own has RC1 & RC2 Hardwired as the LCD module's RS and Enable Pins respectively.Which,ofcourse,happen to be my CCP1 & CCP2 pins(Talk about inconvenient)
Hence,Generating a PWM while trying to display the dynamic change of the encoder feedback goes out the window.
I was wondering if there was any soft way to work around this hard impediment.
Time multiplexing the display with the pwm maybe?I dont mind if pwm gets jittery due to it,its just for demonstration purpose(i tried,but display was still not agreeable.)
Any suggestions?
The objective is to drive a motor using a pwm and to receive and display the feedback from the quadrature encoder on the LDC module.
Here is the code for feedback display:
Code:
//Program accepts feedback from Rotary encoder at PORTB,translates to "Count" and displays at LCD
#include<htc.h>
#define _XTAL_FREQ 20000000
#define RGSL RC1 /* LCD register select */
#define RW RC0 /* LCD read/write mode select */
#define EN RC2 /* LCD read/write enable */
/* function definitions */
void LCD_INIT(void);/* LCD initialistion */
void LCD_COMM(char COMM);
void main()
{
LCD_INIT(); // lcd initialization
LCD_COMM(0xC0); // second row selection for display
int old_val=0;
int new_val=0;
int out=0;
int count=0;
int t_cnt=0,o_cnt=0,h_cnt=0;
TRISB=0b11111111; // configure PORTB pins as input
PORTB=0b00000000; //initialise PORTB as zero
while(1)
{
old_val=new_val; //storing previous state for comparison
new_val=(2*RB1)+RB0; //getting decimal from encoder binary o/p
switch(new_val)
{
case 0:
if (old_val==1) //increase count for clockwise turn
out=-1;
else //decrease count for anti-clock turn
out=1; //count++,count=count+1 etc not working inside switch case
break;
case 1:
if (old_val==3)
out=-1;
else
out=1;
break;
case 2:
if (old_val==0)
out=-1;
else
out=1;
break;
case 3:
if (old_val==2)
out=-1;
else
out=1;
break;
}
if(old_val!=new_val) //do nothing if no change
{
o_cnt=o_cnt+out;
count=count+out;
if(count<0)
{
o_cnt=0;
t_cnt=0;
h_cnt=0;
}
if(o_cnt>9)
{
o_cnt=0;
t_cnt=t_cnt+1;
if(t_cnt>9)
{
t_cnt=0;
h_cnt=h_cnt+1;
if(h_cnt>9)
{
h_cnt=0;
}
}
}
if(o_cnt<0)
{
o_cnt=9;
t_cnt=t_cnt-1;
if(t_cnt<0)
{
t_cnt=9;
h_cnt=h_cnt-1;
if(h_cnt<0)
{
h_cnt=9;
}
}
}
//DISPLAY HUNDREDS COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=h_cnt|0x30;
__delay_us(30); /* delay for write */
EN=0; /* disable write */
//DISPLAY TENS COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=t_cnt|0x30;
__delay_us(30); /* delay for write */
EN=0; /* disable write */
//DISPLAY ONES COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=o_cnt|0x30;
__delay_us(30); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(30); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(30); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(30); /* delay for write */
EN=0; /* disable write */
}
}
}
//Initialises LCD
void LCD_INIT(void)
{
TRISC=0x00; /* set PORTC pins as output */
TRISD=0x00; /* set PORTD pins as output */
LCD_COMM(0X38); /* 8-bit two line display selection */
LCD_COMM(0X0C); /* display on cursor off */
LCD_COMM(0X06); /* auto-address increment */
LCD_COMM(0X01); /* clear display */
}
//Initalise command transfer
void LCD_COMM(char COMM)
{
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=COMM; /* move command to LCD port */
__delay_us(30); /* delay for write */
EN=0; /* disable write */
}
The problem i ran into,was when i tried integrating a PWM generation along with this code.
Code:
void PWM_INIT(void)
{
PR2 = 0b10011011 ;
T2CON = 0b00000111 ;
CCPR1L = 0b00001111 ;
CCP1CON = 0b00101100 ;
}
The kit i own has RC1 & RC2 Hardwired as the LCD module's RS and Enable Pins respectively.Which,ofcourse,happen to be my CCP1 & CCP2 pins(Talk about inconvenient)
Hence,Generating a PWM while trying to display the dynamic change of the encoder feedback goes out the window.
I was wondering if there was any soft way to work around this hard impediment.
Time multiplexing the display with the pwm maybe?I dont mind if pwm gets jittery due to it,its just for demonstration purpose(i tried,but display was still not agreeable.)
Any suggestions?