|
|
View previous topic :: View next topic |
Author |
Message |
Sinister Guest
|
USB versus Timer interrupt on 18F4550 |
Posted: Tue Jun 24, 2008 9:01 pm |
|
|
Hi everybody,
In first place, sorry for my English. If you don´t understand something that i wrote, please tell me.
I´m working with the 18F4550, and i try to read some digital bits on ports A and B and send this as a integer by the USB to the computer.
So, i wrote a main function to manage the commands sent by computer, and a timer0 interruption to read digital ports and put the data in a buffer.
Then, the computer send a command to start acquisition and then, sends a sequence of commands make PIC send data until it reaches the number of samples desired.
The problem is when PIC receives a "send data" command and it coincides with a interrupt. The pic does not respond to the computer and _MPUSBRead return me an error from this point.
The only way that i founded to inhibit this behaviour is disable interrupts if usb_kbhit(1) returns true. But the problem on this is the low sampling rate generated (around 1,5 ms), because of the break to process usb messages.
Some one has some idea to fix it without disable interrupts?
Thanks,
Rodrigo
My code:
Code: |
#include <18F4550.h>
#fuses USBDIV,CPUDIV1
#FUSES NOWDT //No Watch Dog Timer
#FUSES HSPLL //Internal Oscillator, HS used by USB
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOPUT //No Power Up Timer
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //ALTERADO Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOPBADEN //ALTERADO PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES WRTB //ALTERADO Boot block not write protected
#FUSES EBTRB //ALTERADO Boot block not protected from table reads
#FUSES CPB //ALTERADO No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES VREGEN // ALTERADO
#FUSES PLL5 //ALTERADO PLL PreScaler
// Reservando espaço pro Bootloader:
// OBS: Se for gravar sem ser via bootloader, comentar essas linhas!
#build(reset=0x800, interrupt=0x808)
#org 0x000, 0x7ff { }
/////////////////////////////////////
#use delay(clock=48M)
#use fast_io(ALL) //tem q definir o tris para o sentido das portas!
/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS Library
// for your application several defines need to be made. See the comments
// at usb.h for more information
//
/////////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 64 //2 //size to allocate for the tx endpoint 1 buffer // mudar para 2
#define USB_EP1_RX_SIZE 64 //33 //size to allocate for the rx endpoint 1 buffer // mudar para 33
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h> //Configuración del USB y los descriptores para este dispositivo
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <fifo.h>
#define modo entrada[0]
#define param1 entrada[1]
#define param2 entrada[2]
#define param3 entrada[3]
#define param4 entrada[4]
#define param5 entrada[5]
#define DELAYELETRONICO 5 // delay em us
#define TEMPO 100
#priority timer0
//variáveis globais:
int16 dados;
int32 amostrasaquisitadas;
int32 amostrasenviadas;
int8 byterecebe;
int32 totalamostras;
int1 aquisitando;
#int_timer0
void Aquisitadados()
{
int1 gravoubuffer;
set_timer0(250-get_timer0());
//recebe os dados:
// 8 bits mais significativos
dados = input_b();
dados >>= 8;
byterecebe = input_a();
// ignora os dados de b4-7
byterecebe >>= 4;
byterecebe <<= 4;
dados += byterecebe;
//coloca os dados no buffer:
if (insere(dados) && gravoubuffer) { //insere: put data in buffer
amostrasaquisitadas++;
} else {
output_high(pin_D0);
aquisitando = 0;
disable_interrupts(int_timer0); //termina a aquisição
set_tris_a(0b00000000); //Todos os pinos da porta 'A' como saídas. (porta B do PG-29)
set_tris_b(0b00000000); //Todos os pinos da porta 'B' como saídas. (porta A do Pg-29)
}
if (totalamostras <= amostrasaquisitadas) {
aquisitando = 0;
disable_interrupts(int_timer0); //termina a aquisição
set_tris_a(0b00000000); //Todos os pinos da porta 'A' como saídas. (porta B do PG-29)
set_tris_b(0b00000000); //Todos os pinos da porta 'B' como saídas. (porta A do Pg-29)
output_high(Pin_A3);
}
}
void main(void) {
int8 entrada[6];
int8 envia[64];
int8 i;
int8 numamostras;
set_tris_a(0b00000000);
set_tris_b(0b00000000);
set_tris_d(0b00000000);
OUTPUT_A(0x00);
OUTPUT_B(0x00);
OUTPUT_D(0x00);
aquisitando = 0;
amostrasaquisitadas = 0;
amostrasenviadas = 0;
SETUP_TIMER_1(T1_DISABLED);
SETUP_TIMER_2(T2_DISABLED,255,5);
SETUP_TIMER_3(T3_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
set_timer0(250);
disable_interrupts(global);
// Inicialização da USB e enumeração
usb_init(); //inicializamos a USB
usb_task(); //habilita periferico usb e interrupciones
usb_wait_for_enumeration(); //esperamos hasta que el PicUSB sea configurado por el host
while (TRUE)
{
if(usb_enumerated())
{
if (usb_kbhit(1))
{
if (aquisitando == 1) {
disable_interrupts(int_timer0);
}
usb_get_packet(1, entrada, 6);
if (modo == 4) //Starts acquisition
{
set_tris_a(0b11111111);
set_tris_b(0b11111111);
// start acquisition:
output_high(pin_D4);
amostrasaquisitadas = 0;
amostrasenviadas = 0;
aquisitando = 1;
totalamostras = (param1*256) + param2;
enable_interrupts(int_timer0);
}
if (modo == 6) // send samples
{
numamostras = (amostrasaquisitadas*2)-amostrasenviadas;
envia[1] = 0; //amostras excedentes
if (numamostras > 60) {
numamostras = 60;
envia[1] = 1;
}
envia[0] = numamostras;
envia[2] = param1;
for (i=3;i<=63;i++){
// amostra de tensão
if (i <= numamostras+3){
envia[i] = remove(); //remove:removes data from buffer
} else {
envia[i] = 0;
}
}
amostrasenviadas = amostrasenviadas + numamostras;
disable_interrupts(int_timer0);
usb_put_packet(1, envia,64, USB_DTS_TOGGLE);
enable_interrupts(int_timer0);
}
if (aquisitando == 1) {
enable_interrupts(int_timer0);
}
}
}
}
}
|
|
|
|
stewart
Joined: 28 Nov 2005 Posts: 12
|
|
Posted: Tue Jun 24, 2008 11:41 pm |
|
|
Sinister,
I have looked over your code, not in great detail, but I can suggest that you do FAR LESS in the TMR0 interrupt routine.
There are many discussions related to trying to do too much in an interrupt service routine (ISR).
In your case, have the main code do the reading of the ports and then just use that data to respond within the ISR
Have fun
Stewart |
|
|
Guest
|
|
Posted: Wed Jun 25, 2008 10:01 am |
|
|
stewart wrote: | Sinister,
I have looked over your code, not in great detail, but I can suggest that you do FAR LESS in the TMR0 interrupt routine.
There are many discussions related to trying to do too much in an interrupt service routine (ISR).
In your case, have the main code do the reading of the ports and then just use that data to respond within the ISR
Have fun
Stewart |
Thank you for fast response Stewart!
I will try to do this. But i have only one question, can i use int_usb to manage data sended by computer via usb?
Rodrigo |
|
|
|
|
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
|