|
|
View previous topic :: View next topic |
Author |
Message |
itsbasix
Joined: 23 May 2012 Posts: 8
|
PIC18F4550 failing enumeration |
Posted: Wed May 23, 2012 2:03 pm |
|
|
Hi guys.
I'm working on a project in order to control a stepper motor with MATLAB using a driver based on USB communication.
I chose PIC18F4550 to do this, making it act as a CDC device.
I wrote this code but enumeration always fails both on win7 64-bit (with correct drivers) and on Linux Mint 12 32-bit(which should not need any driver at all).
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN,PUT,NOMCLR,NOLVP
#use delay(clock=48000000)
#include <usb_cdc.h>
#include <math.h>
#include <stdlib.h>
#use fast_io(b)
void lampeggia_led(int ms,int n);
void motordriver(float theta,char segno,char mode,float step_angle,float rpm);
void read_message(char buffer[], float &theta,float& step_angle,float& rpm);
void wavemode(float theta,char segno,int n_step,float delay);
void twophase(float theta,char segno,int n_step,float delay);
void halfstep(float theta,char segno,int n_step,float delay);
int i;
char buffer[16],a;
float theta=0,step_angle=0,rpm=0;
char mode,segno;
void main(){
set_tris_b(0);
output_b(0); //setta porta B come uscita
output_bit(PIN_A0,0);
output_bit(PIN_A1,0);
output_bit(PIN_A1,1);
lampeggia_led(100,10);
delay_ms(1000);
usb_cdc_init();
usb_init();
delay_ms(5000);
if(usb_enumerated()){
usb_cdc_putc("Connessione USB avvenuta!");
}
output_bit(PIN_A1,0);
output_bit(PIN_A0,1);
delay_ms(500);
output_b(255);
delay_ms(6000);
output_b(0);
i=0;
while(1){
if(usb_enumerated()){
output_bit(PIN_A1,1);
if(usb_cdc_kbhit()){
a=usb_cdc_getc();
buffer[i]=a;
i++;
if(i==16&&buffer[0]=='P'&&buffer[1]=='='&&buffer[15]=='B')
{
read_message(buffer,theta,step_angle,rpm);
segno=buffer[5];
mode=buffer[6];
usb_cdc_putc("Arrivato");
motordriver(theta,segno,mode,step_angle,rpm);
output_b(0);
i=0;
}
}
}
}
}
void read_message(char buffer[], float &theta,float& step_angle,float& rpm)
{
char temp[8];
int i,c=0;
for(i=2;i<5;i++)
{
temp[c]=buffer[i];
c++;
}
temp[c]='\0';
theta=atof(temp);
c=0;
for(i=7;i<10;i++)
{
temp[c]=buffer[i];
c++;
}
temp[c]='\0';
step_angle=atof(temp);
c=0;
for(i=10;i<15;i++)
{
temp[c]=buffer[i];
c++;
}
temp[c]='\0';
rpm=atof(temp);
}
void lampeggia_led(int ms,int n)
{
int i;
for(i=0;i<n;i++)
{
delay_ms(ms);
output_bit(PIN_A1,0);
delay_ms(ms);
output_bit(PIN_A1,1);
}
}
void motordriver(float theta,char segno,char mode,float step_angle,float rpm)
{
float spr=0, rps=0, tpr=0,delay=0;
int n_step=0;
spr=360/step_angle;
rps=rpm/60;
tpr=1/rps;
delay=(tpr/spr)*1000;
n_step=abs(theta)/step_angle;
if(mode=='W')
wavemode(theta,segno,n_step,delay);
if(mode=='T')
twophase(theta,segno,n_step,delay);
if(mode=='H')
halfstep(theta,segno,2*n_step,delay/2);
}
void wavemode (float theta,char segno,int n_step,float delay)
{
int i, c=0, pattern[4];
if (segno=='+')
{
pattern[0]=1;
pattern[1]=2;
pattern[2]=4;
pattern[3]=8;
}
if(segno=='-')
{
pattern[3]=1;
pattern[2]=2;
pattern[1]=4;
pattern[0]=8;
}
for (i=0;i<n_step-1;i++)
{
output_b(pattern[c]);
delay_ms(ceil(delay));
c++;
if (c==4)
c=0;
}
}
void twophase (float theta,char segno,int n_step,float delay)
{
int i=0, c=0, pattern[4];
if (segno=='+')
{
pattern[0]=3;
pattern[1]=6;
pattern[2]=12;
pattern[3]=9;
}
if(segno=='-')
{
pattern[3]=3;
pattern[2]=6;
pattern[1]=12;
pattern[0]=9;
}
for (i=0;i<n_step-1;i++)
{
output_b(pattern[c]);
delay_ms(delay);
c++;
if (c==4)
c=0;
}
}
void halfstep (float theta,char segno,int n_step,float delay)
{
int i=0, c=0, pattern[8];
if (segno=='+')
{
pattern[0]=1;
pattern[1]=3;
pattern[2]=2;
pattern[3]=6;
pattern[4]=4;
pattern[5]=12;
pattern[6]=8;
pattern[7]=9;
}
if(segno=='-')
{
pattern[7]=1;
pattern[6]=3;
pattern[5]=2;
pattern[4]=6;
pattern[3]=4;
pattern[2]=12;
pattern[1]=8;
pattern[0]=9;
}
for (i=0;i<n_step-1;i++)
{
output_b(pattern[c]);
delay_ms(delay);
c++;
if (c==8)
c=0;
}
}
|
I use the standard hardware configuration (100nF capacitor between +VCC and GND, 470nF capacitor between VUSB and GND, 20Mhz oscillator, 4,7KOmh resistor on MCLR).
Also tried with 4Mhz,8Mhz oscillators (with proper fuses) and 200nF capacitor on VUSB.
I'm using CCS 4.093.
I'm getting mad at this please help!
(I'm sorry if my English is bad but I'm an Italian student)
Thanks.
[/code] |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Wed May 23, 2012 2:29 pm |
|
|
Hi,
You are missing some critical code in your application, which is undoubtedly causing your code to fail. Take a look at 'ex_usb_serial2.c' in the 'Examples' folder to see how you need to implement USB CDC. In particular, look at these lines:
Code: |
for(;;)
{
usb_task();
usb_debug_task();
if (usb_enumerated())
{
if (usb_cdc_kbhit())
{
i = toupper(usb_cdc_getc());
|
You need to be calling 'usb_task' and 'usb_debug_task' frequently in your program for the USB CDC implementation to work. I'd get this example programming running on your hardware first, and then make changes to create your application. The CCS USB CDC example codes does work, and I've used it as the basis for many USB designs!
John |
|
|
itsbasix
Joined: 23 May 2012 Posts: 8
|
|
Posted: Wed May 23, 2012 2:39 pm |
|
|
thank you for answer this quickly!
could you explain me why that calls are so important?
can this seriously effect enumeration?!?!
i guess this stuff is harder than i expected |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed May 23, 2012 6:40 pm |
|
|
USB..aka Useless Serial Bus...arrgh..
The 'bible' on it is over 500 pages and just covers what was the 'standard' a few years ago....
John's right, the CCS examples do work...so save yourself weeks of grief,install one in a PIC, get it 'up and running' and then copy/modify it to get it to do what you want...btdt
oh yeah....the USB 'driver' code chews up about 1/3 of the 4550 codespace....so if your application is large, consider using a USB<->serial interface module.Zero memory used and they work 'out of the box'.btdt2
Jay |
|
|
itsbasix
Joined: 23 May 2012 Posts: 8
|
|
Posted: Thu May 24, 2012 1:32 am |
|
|
It works! The breadboard was damaged somehow, I changed it and now it's ok. The only problem is that the program is slow, the delay instructions seem to take more time than expected. Any ideas? |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu May 24, 2012 7:05 am |
|
|
Hi,
Wait a minute! What works? Do you mean your board is doing *something*, or that you have USB functionality?? Your comment that "delays take longer than expected" is a huge red flag that something is amiss!! With some PICS, it's easy to have incorrect Fuse settings, and/or clock definitions cause your PIC to operate at an unintended speed. I recommend that you flash an LED at a known rate to see if your PIC is operating at the expected speed!!
Code: |
While(1){
output_high(LED);
delay_ms(1000);
output_low(LED);
delay_ms(1000);
}
|
If you run this code, the LED should be ON for 1 second, and OFF for 1 second. Time it with your watch!
John |
|
|
itsbasix
Joined: 23 May 2012 Posts: 8
|
|
Posted: Thu May 24, 2012 7:18 am |
|
|
i got usb functionality and all the instructions works, but the port b remains in a defined state (ex output_b(1)) for a time longer than the one set in the delay_ms instruction, and i do not know if this is caused by a wrong fuses config or a "not so quick" written code. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu May 24, 2012 7:34 am |
|
|
Hi,
Post your current program, and be sure to use proper indenting so that it's readable. If you don't know what I mean, have a look here: http://en.wikipedia.org/wiki/Indent_style Also, tell us how you are testing your code. Tell us what you expect to happen, and what you actually observe. Be as detailed as you can - if we have to dig too deeply to remotely troubleshoot your code, you probably won't get much help!
John |
|
|
|
|
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
|