![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Hoselupf
Joined: 22 May 2017 Posts: 2 Location: Switzerland
|
odd problem with set_pwmX_duty and lcd driver... |
Posted: Mon May 22, 2017 9:26 am |
|
|
Hello together,
For the last four hours I'm sitting in front of my code, almost losing my mind.
I'm using a PIC18F25K22.
Now in my functions.c file
functions.c
Code: | void runEngineControl(deviceState* devState){
if(devState->engineRegOn){
//calculate setPoint;
int16 calEnImpCount = readEeprom16(CALENCODER);
signed int16 setPointms = ((((1000000/(devState->speedkmh/100))*60*60)/calEnImpCount)/100);
signed int16 encoderMs = g_impCounterEncoderms;
unsigned int8 dutyValue = runPid(setPointms, encoderMs);
set_pwm2_duty(dutyValue);
lcd_gotoxy(1,1);
}
} |
this works:
Code: | unsigned int8 dutyValue = runPid(setPointms, encoderMs);
set_pwm2_duty(dutyValue);
lcd_gotoxy(1,1);
}
} |
this also:
Code: | unsigned int8 dutyValue = runPid(setPointms, encoderMs);
set_pwm2_duty(61);
}
} |
BUT this:
Code: | unsigned int8 dutyValue = runPid(setPointms, encoderMs);
set_pwm2_duty(dutyValue);
}
} |
won't work(?!?). If I'm measuring on pin c1, nothing happens.
I'm running out of ideas why the heck it will work with a lcd_gotoxy(1,1)
underneath but without nothing happens. I checked out the lcduniversal.h
lcd driver but couldn't see anything special. Also I don't understand what
this two things (lcd driver and ccp2 for pwm) could have in common.
The output of the runPid(setPointms, encoderMs) function is valid.
(needless to say that this is also working)
Code: | unsigned int8 dutyValue = runPid(setPointms, encoderMs);
set_pwm2_duty(dutyValue);
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",dutyValue);
}
} |
I'd be very happy if someone could give me a hint or even the solution of this problem...
the rest of the important code:
init_pic.c / init ccp2 module for pwm
Code: | output_low(PIN_C1);
setup_timer_2(T2_DIV_BY_1,152,1);
setup_ccp2(CCP_PWM|CCP_USE_TIMER1_AND_TIMER2);
set_pwm2_duty(0); |
pid.c
Code: | unsigned int16 runPid(signed int16 setPoint, signed int16 encoderValue){
signed int16 error,pTerm,dTerm;
signed int32 iTerm, out, temp;
error = setPoint-encoderValue;
//calc pTerm
if(error > pid.eMax)
pTerm = pid.eMax;
else if(error < -pid.eMax)
pTerm = pid.eMax;
else
pTerm = pid.kP * error;
//calc iTerm
temp = pid.eSum + error;
if(temp > pid.integralMax){
iTerm = pid.integralMax;
pid.eSum = pid.integralMax;
}
else if(temp < pid.integralMin){
iTerm = pid.integralMin;
pid.eSum = pid.integralMin;
}
else{
pid.eSum = temp;
iTerm = pid.kI * pid.eSum;
}
//calc dTerm
dTerm = pid.kD *(pid.lastEncoderValue - encoderValue);
pid.lastEncoderValue = encoderValue;
out = (pTerm + iTerm + dTerm);
if(out>pid.outMax)
out = pid.outMax;
else if(out < pid.outMin)
out = pid.outMin;
return (unsigned int16)out;
}
|
lcduniversal.h / lcd driver
Code: | int data;
//byte nocon=0;
#byte PORTA = 0xf80
#byte PORTB = 0xf81
#byte PORTC = 0xf82
#bit enable = PORTB.5
#bit lcd_RS = PORTC.5
#bit lcd_RW = PORTC.4 // NOCON.0 // nicht benutzt, auf minus
#bit data0 = data.0
#bit data1 = data.1
#bit data2 = data.2
#bit data3 = data.3
struct lcd_pin_map {
int data: 4 ;
// int unused0 ;
// byte enable ;
// int unused1 ;
// int unused2 ;
} lcd;
#byte lcd = portb //port B Daten
//#byte lcd = 7 // This puts the entire structure
// on to port C (at address 7)
STRUCT lcd_pin_map const LCD_WRITE = {0};
// For write mode all pins are out
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
void lcd_send_nibble( byte n ) {
data = n;
output_bit(pin_B4,data3); //A3
output_bit(pin_B3,data2); //A2
output_bit(pin_B2,data1); //A1
output_bit(pin_B1,data0); //B2
// lcd.data = n;
delay_cycles(1); //1
enable = 1;
delay_us(2); //2
enable = 0;
}
#SEPARATE
void lcd_send_byte( byte address, byte n ) {
lcd_rs = 0;
delay_ms(2); //2
lcd_rs = address;
delay_cycles(1); //1
//lcd_rw = 0;
delay_cycles(1); //1
enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
#SEPARATE
void lcd_init() {
byte i;
lcd_rs = 0;
enable = 0;
delay_ms(15); //init 4 bit mode
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i) //3
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
#SEPARATE
void lcd_gotoxy( byte x, byte y) {
byte address;
if (y==1) address=0; // max 4 Zeilen LCD
if (y==2) address=0x40;
if (y==3) address=0x10;
if (y==4) address=0x50;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1); //display clear
delay_ms(2);
break;
case '\1' : lcd_gotoxy(1,1); break; //goto 1.linie
case '\2' : lcd_gotoxy(1,2); break; //goto 2.linie
case '\b' : lcd_send_byte(0,0x10); break; //cursor 1 zurück
default : lcd_send_byte(1,c); break;
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 22, 2017 10:07 am |
|
|
If a program behaves differently when lines of code are moved around,
the two most common reasons would be improper variable declarations or
usage, or a compiler bug.
You have posted a lot of code fragments.
You need to post a small, but complete test program that shows the
problem. We should be able to copy and paste your program into MPLAB
and compile it with no errors. If you do this, then we can look at your
variable declarations. Make the program be as small as possible, but
still showing the problem.
Also, post your CCS compiler version. The version consists of a 4-digit
number (only), in the format 5.xxx or 4.xxx, etc. It's given at the top
of the .LST file after a successful compilation. The .LST file will be in your
project directory. Examples of compiler version numbers:
http://www.ccsinfo.com/devices.php?page=versioninfo
Also, lcduniversal.h is clearly invented by you. Google shows no hits n
when I search for it. The line addresses in it for a 4x20 lcd are
non-standard:
Quote: | if (y==1) address=0; // max 4 Zeilen LCD
if (y==2) address=0x40;
if (y==3) address=0x10;
if (y==4) address=0x50; |
A standard 4x20 lcd will have line addresses of:
Maybe you have a non-standard lcd. You should post the manufacturer
and part number of it. |
|
![](templates/subSilver/images/spacer.gif) |
Hoselupf
Joined: 22 May 2017 Posts: 2 Location: Switzerland
|
|
Posted: Tue May 23, 2017 3:14 am |
|
|
Thx for your response!
I'm also using the ccp3 and ccp1 moudle.
PIN B5 is used as enable pin for the lcd module.
B5 could also be used for the enhanced pwm or the ccp3 module.
I added
Code: | #FUSES CCP3C6 //CCP3 on PIN C6 |
and now everything is ok! |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|