Bootloader e pic18f2550, come funziona ???
11 Anni 1 Giorno fa #21
da Alex68
Risposta da Alex68 al topic Bootloader e pic18f2550, come funziona ???
AIUTO !!!!!
ono quasi 5 giorni che provo ad utilizzare il bootloader con gli interrupt sono finito in un vicolo cieco. Sostanzialmente non riesco a capire come fare ad impostare gli offset per gli interrupt. In breve, ho realizzato un programmino per far accendere il solito led che utilizza l'nterrupt da alta priorità sull'oerflow del Timer0 e che caricato sul pic con il Pickit2 funziona. L'ho adattato aggiungendo gli "appositi" offset per l'utilizzo del bootloader ma di lampeggia di lampeggiare non ne vuole sapere . questo è quello che ho scritto nel programma:
void New_High_Priority_ISR_Code();
void New_Low_Priority_ISR_Code();
//*************************************************************
// Definizione nuovi indirizzi
//*************************************************************
#define REMAPPED_RESET_VECTOR_ADDRESS 0x800
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
//Vedi il file c018i.c
extern void _startup (void);
//*************************************************************
// Rimappatura Interrupt Service Routine
//*************************************************************
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void){
_asm goto _startup _endasm
}
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void) {
_asm goto New_High_Priority_ISR_Code _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void) {
_asm goto New_Low_Priority_ISR_Code _endasm
}
#pragma code
//*************************************************************
// Nuovi Interrupt Service Routines
//*************************************************************
// Gestione Interrupt alta Priorita'
#pragma interrupt New_High_Priority_ISR_Code
void New_High_Priority_ISR_Code() {
// Variabile che conterrà i dati ricevuti
unsigned char data;
// Flag per controllare la ricezione del primo carattere
static char firstTime = 0;
// Controllo che l'interrupt sia stato generato dall'USART
if (INTCONbits.TMR0IF == 1 )
{
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
TMR0H=0x67;
TMR0L=0x69;
}
// Gestione Interrupt bassa Priorita'
#pragma interruptlow New_Low_Priority_ISR_Code
void New_Low_Priority_ISR_Code(){
}
//*************************************************
// Programma Principale
//*************************************************
void main (void){
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
// Imposto PORTA con RA0 come output
LATA = 0x00;
TRISA = 0b11111110;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0b11111101;
// Abilito modalita' compatibile (di default vale gia' 0)
RCONbits.IPEN = 0;
// Modalita' a 16 bit
T0CONbits.T08BIT = 0;
// Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 64
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 1;
// Abilito l'interrupt globale
INTCONbits.GIE = 1;
// Abilito il timer
T0CONbits.TMR0ON=1;
// Abilito interrupt sul Timer 0
INTCONbits.TMR0IE = 1 ;
// Carico il timer con i valori alto e basso di 0x6769
TMR0H=0x67;
TMR0L=0x69;
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
// Ciclo infinito
while (1)
{
}
}
Nell'immagine si vede che il bootloader termina prima della locazione 0x800:
allego anche il linker che utilizzo per compilare il prgramma:
ono quasi 5 giorni che provo ad utilizzare il bootloader con gli interrupt sono finito in un vicolo cieco. Sostanzialmente non riesco a capire come fare ad impostare gli offset per gli interrupt. In breve, ho realizzato un programmino per far accendere il solito led che utilizza l'nterrupt da alta priorità sull'oerflow del Timer0 e che caricato sul pic con il Pickit2 funziona. L'ho adattato aggiungendo gli "appositi" offset per l'utilizzo del bootloader ma di lampeggia di lampeggiare non ne vuole sapere . questo è quello che ho scritto nel programma:
void New_High_Priority_ISR_Code();
void New_Low_Priority_ISR_Code();
//*************************************************************
// Definizione nuovi indirizzi
//*************************************************************
#define REMAPPED_RESET_VECTOR_ADDRESS 0x800
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
//Vedi il file c018i.c
extern void _startup (void);
//*************************************************************
// Rimappatura Interrupt Service Routine
//*************************************************************
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void){
_asm goto _startup _endasm
}
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void) {
_asm goto New_High_Priority_ISR_Code _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void) {
_asm goto New_Low_Priority_ISR_Code _endasm
}
#pragma code
//*************************************************************
// Nuovi Interrupt Service Routines
//*************************************************************
// Gestione Interrupt alta Priorita'
#pragma interrupt New_High_Priority_ISR_Code
void New_High_Priority_ISR_Code() {
// Variabile che conterrà i dati ricevuti
unsigned char data;
// Flag per controllare la ricezione del primo carattere
static char firstTime = 0;
// Controllo che l'interrupt sia stato generato dall'USART
if (INTCONbits.TMR0IF == 1 )
{
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
TMR0H=0x67;
TMR0L=0x69;
}
// Gestione Interrupt bassa Priorita'
#pragma interruptlow New_Low_Priority_ISR_Code
void New_Low_Priority_ISR_Code(){
}
//*************************************************
// Programma Principale
//*************************************************
void main (void){
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
// Imposto PORTA con RA0 come output
LATA = 0x00;
TRISA = 0b11111110;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0b11111101;
// Abilito modalita' compatibile (di default vale gia' 0)
RCONbits.IPEN = 0;
// Modalita' a 16 bit
T0CONbits.T08BIT = 0;
// Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 64
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 1;
// Abilito l'interrupt globale
INTCONbits.GIE = 1;
// Abilito il timer
T0CONbits.TMR0ON=1;
// Abilito interrupt sul Timer 0
INTCONbits.TMR0IE = 1 ;
// Carico il timer con i valori alto e basso di 0x6769
TMR0H=0x67;
TMR0L=0x69;
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
// Ciclo infinito
while (1)
{
}
}
Nell'immagine si vede che il bootloader termina prima della locazione 0x800:
allego anche il linker che utilizzo per compilare il prgramma:
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Alex68
- Autore della discussione
- Visitatori
11 Anni 1 Giorno fa #22
da Alex68
Risposta da Alex68 al topic Bootloader e pic18f2550, come funziona ???
Scusate, mancava il linker:
//***************************************
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f2550.lib
CODEPAGE NAME=boot START=0x0 END=0x7FF PROTECTED
CODEPAGE NAME=vectors START=0x800 END=0x829 PROTECTED
CODEPAGE NAME=page START=0x82A END=0x7FFF
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
ACCESSBANK NAME=accessram START=0x0 END=0x5F
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=usb4 START=0x400 END=0x4FF PROTECTED
DATABANK NAME=usb5 START=0x500 END=0x5FF PROTECTED
DATABANK NAME=usb6 START=0x600 END=0x6FF PROTECTED
DATABANK NAME=usb7 START=0x700 END=0x7FF PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
STACK SIZE=0x100 RAM=gpr3
//***************************************
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f2550.lib
CODEPAGE NAME=boot START=0x0 END=0x7FF PROTECTED
CODEPAGE NAME=vectors START=0x800 END=0x829 PROTECTED
CODEPAGE NAME=page START=0x82A END=0x7FFF
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
ACCESSBANK NAME=accessram START=0x0 END=0x5F
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=usb4 START=0x400 END=0x4FF PROTECTED
DATABANK NAME=usb5 START=0x500 END=0x5FF PROTECTED
DATABANK NAME=usb6 START=0x600 END=0x6FF PROTECTED
DATABANK NAME=usb7 START=0x700 END=0x7FF PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
STACK SIZE=0x100 RAM=gpr3
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Alex68
- Autore della discussione
- Visitatori
10 Anni 11 Mesi fa #23
da Mauro Laurenti
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Risposta da Mauro Laurenti al topic Bootloader e pic18f2550, come funziona ???
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Mauro Laurenti
- Moderator
Riduci
Di più
10 Anni 11 Mesi fa #24
da Alex68
Risposta da Alex68 al topic Bootloader e pic18f2550, come funziona ???
Ciao Mauro
Allora nel bootloader c'è iserito quanto segue:
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "typedefs.h" // Required
#include "usb.h" // Required
#include "io_cfg.h" // Required
#include "usb_compile_time_validation.h" // Optional
/** C O N F I G U R A T I O N ************************************************/
#if defined(__18F4550)||defined(__18F4455)|| \
defined(__18F2550)||defined(__18F2455)|| \
defined(__18F4553)||defined(__18F4458)|| \
defined(__18F2553)||defined(__18F2458)
// Note: Some of the below configuration bits are commented out
// to prevent build errors with some of the above listed devices.
// For example, on the PIC18F4458 CP3, WRT3, and EBTR3 don't exist.
#pragma config PLLDIV = 5 // (20 MHz input)
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = ON
#pragma config BORV = 3
#pragma config VREGEN = ON
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config MCLRE = ON
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
#pragma config CCP2MX = ON
#pragma config STVREN = ON
#pragma config LVP = OFF
//#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
#pragma config XINST = OFF // Extended Instruction Set
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
//#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
//#pragma config WRT3 = OFF
#pragma config WRTB = ON // Boot Block Write Protection
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
//#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
#endif
/** V A R I A B L E S ********************************************************/
#pragma udata
/** P R I V A T E P R O T O T Y P E S ***************************************/
/** V E C T O R R E M A P P I N G *******************************************/
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
void _high_ISR (void)
{
_asm goto 0x808 _endasm
}
#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
void _low_ISR (void)
{
_asm goto 0x818 _endasm
}
#pragma code
/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
* Function: void main(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Main program entry point.
*
* Note: None
*****************************************************************************/
void main(void)
{
byte temp;
temp = ADCON1;
ADCON1 |= 0x0F;
//TRISBbits.TRISB4 = 1; // Reset value is already '1'
//Check Bootload Mode Entry Condition
//Qui si può impostare il pin che si vuole per effettuare il boot
if(PORTCbits.RC0 == 1) // If not pressed, User Mode
{
ADCON1 = temp; // Restore reset value
_asm goto RM_RESET_VECTOR _endasm
}//end if
//Bootload Mode
//mInitAllLEDs();
mInitializeUSBDriver(); // See usbdrv.h
USBCheckBusStatus(); // Modified to always enable USB module
while(1)
{
USBDriverService(); // See usbdrv.c
BootService(); // See boot.c
}//end while
}//end main
#pragma code user = RM_RESET_VECTOR
/** EOF main.c ***************************************************************/
mentre nel progetto che utilizza gli interrupt ho inserito quanto segue:
#include <p18f2550.h>
#include <timers.h>
#include <delays.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config MCLRE = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config PLLDIV = 1
#pragma config DEBUG = OFF
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config VREGEN = OFF
#pragma config CCP2MX = OFF
#pragma config LPT1OSC = OFF
#pragma config STVREN = OFF
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
//*************************************************************
// Definizione nuovi indirizzi
//*************************************************************
#if defined(__18CXX)
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
//the reset, high priority interrupt, and low priority interrupt
//vectors. However, the current Microchip USB bootloader
//examples are intended to occupy addresses 0x00-0x7FF or
//0x00-0xFFF depending on which bootloader is used. Therefore,
//the bootloader code remaps these vectors to new locations
//as indicated below. This remapping is only necessary if you
//wish to program the hex file generated from this project with
//the USB bootloader. If no bootloader is used, edit the
//usb_config.h file and comment out the following defines:
//#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
//#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
//***********************************************************
//---- I think, this is your case, since you wrote 0x00800 Reset adderess
#define PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER
//#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
//***********************************************************
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
#elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS 0x800
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
#else
#define REMAPPED_RESET_VECTOR_ADDRESS 0x00
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18
#endif
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
extern void _startup (void); // See c018i.c in your C18 compiler dir
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void)
{
_asm goto _startup _endasm
}
#endif
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void)
{
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void)
{
_asm goto YourLowPriorityISRCode _endasm
}
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
//Note: If this project is built while one of the bootloaders has
//been defined, but then the output hex file is not programmed with
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
//As a result, if an actual interrupt was enabled and occured, the PC would jump
//to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space). This
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
//(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup". This
//would effective reset the application.
//To fix this situation, we should always deliberately place a
//"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
//"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18. When the output
//hex file of this project is programmed with the bootloader, these sections do not
//get bootloaded (as they overlap the bootloader space). If the output hex file is not
//programmed using the bootloader, then the below goto instructions do get programmed,
//and the hex file still works like normal. The below section is only required to fix this
//scenario.
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void High_ISR (void)
{
_asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void)
{
_asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
}
#endif //end of "#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER)"
#pragma code
//These are your actual interrupt handling routines.
// #pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode (void) {
// Variabile che conterrà i dati ricevuti
unsigned char data;
// Flag per controllare la ricezione del primo carattere
static char firstTime = 0;
// Controllo che l'interrupt sia stato generato dall'USART
if (INTCONbits.TMR0IF == 1 )
{
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
TMR0H=0x67;
TMR0L=0x69;
}
// #pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode()
{
//Check which interrupt flag caused the interrupt.
//Service the interrupt
//Clear the interrupt flag
//Etc.
} //This return will be a "retfie", since this is in a #pragma interruptlow section
#endif
//*************************************************
// Programma Principale
//*************************************************
void main (void){
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
// Imposto PORTA con RA0 come output
LATA = 0x00;
TRISA = 0x00;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0b11111101;
// Abilito modalita' compatibile (di default vale gia' 0)
RCONbits.IPEN = 0;
// Modalita' a 16 bit
T0CONbits.T08BIT = 0;
// Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 64
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 1;
// Abilito l'interrupt globale
INTCONbits.GIE = 1;
// Abilito il timer
T0CONbits.TMR0ON=1;
// Abilito interrupt sul Timer 0
INTCONbits.TMR0IE = 1 ;
// Calcolo il timer per avviare un interrupt gni 0.5 sec
// dati per il calcolo:
// Fosc = 20MHz => 20.000.000Hz
// Prescaler = 64
// Periodo del clock => Tosc=1/(20.000.000)=0.05 us
// Il timer si incrementa dopo 4 cicli di clock => Ttimer=Tosc*4=0.05*4=0.2us
// Il prescaler rallenta il timer di 64 volte Tprescaler=Ttimer*64=0.2*64=12.8us
// Avendo attivato il timer a 16 bit l'overflow avviene dopo 2^16 scillazioni = 65535
// Quindi avremo un interrupt ogni 12.8*65535=0.8338sec ( troppo )
// Per conoscere il valore da caricare nel timer, dobbiamo conoscere il valore in uscita da prescaler
// Conteggi= 0.5/((0.05*4*64)/1000000)=39062
// Il valore da caricarenel Timer è 65535-39032=26473 in Hex=>0x6769
// Carico il timer con i valori alto e basso di 0x6769
TMR0H=0x67;
TMR0L=0x69;
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
// Ciclo infinito
while (1)
{
/* LATA=0xFF;
Delay10KTCYx(25);
LATA=0x00;
Delay10KTCYx(25);
*/
}
}
Dove sbaglio??
grazie
PS: allego l'intero progetto. Per caricare con il bootloader il pin da mettere a massa è RC0
Allora nel bootloader c'è iserito quanto segue:
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "typedefs.h" // Required
#include "usb.h" // Required
#include "io_cfg.h" // Required
#include "usb_compile_time_validation.h" // Optional
/** C O N F I G U R A T I O N ************************************************/
#if defined(__18F4550)||defined(__18F4455)|| \
defined(__18F2550)||defined(__18F2455)|| \
defined(__18F4553)||defined(__18F4458)|| \
defined(__18F2553)||defined(__18F2458)
// Note: Some of the below configuration bits are commented out
// to prevent build errors with some of the above listed devices.
// For example, on the PIC18F4458 CP3, WRT3, and EBTR3 don't exist.
#pragma config PLLDIV = 5 // (20 MHz input)
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = ON
#pragma config BORV = 3
#pragma config VREGEN = ON
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config MCLRE = ON
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
#pragma config CCP2MX = ON
#pragma config STVREN = ON
#pragma config LVP = OFF
//#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
#pragma config XINST = OFF // Extended Instruction Set
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
//#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
//#pragma config WRT3 = OFF
#pragma config WRTB = ON // Boot Block Write Protection
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
//#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
#endif
/** V A R I A B L E S ********************************************************/
#pragma udata
/** P R I V A T E P R O T O T Y P E S ***************************************/
/** V E C T O R R E M A P P I N G *******************************************/
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
void _high_ISR (void)
{
_asm goto 0x808 _endasm
}
#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
void _low_ISR (void)
{
_asm goto 0x818 _endasm
}
#pragma code
/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
* Function: void main(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Main program entry point.
*
* Note: None
*****************************************************************************/
void main(void)
{
byte temp;
temp = ADCON1;
ADCON1 |= 0x0F;
//TRISBbits.TRISB4 = 1; // Reset value is already '1'
//Check Bootload Mode Entry Condition
//Qui si può impostare il pin che si vuole per effettuare il boot
if(PORTCbits.RC0 == 1) // If not pressed, User Mode
{
ADCON1 = temp; // Restore reset value
_asm goto RM_RESET_VECTOR _endasm
}//end if
//Bootload Mode
//mInitAllLEDs();
mInitializeUSBDriver(); // See usbdrv.h
USBCheckBusStatus(); // Modified to always enable USB module
while(1)
{
USBDriverService(); // See usbdrv.c
BootService(); // See boot.c
}//end while
}//end main
#pragma code user = RM_RESET_VECTOR
/** EOF main.c ***************************************************************/
mentre nel progetto che utilizza gli interrupt ho inserito quanto segue:
#include <p18f2550.h>
#include <timers.h>
#include <delays.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config MCLRE = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config PLLDIV = 1
#pragma config DEBUG = OFF
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config VREGEN = OFF
#pragma config CCP2MX = OFF
#pragma config LPT1OSC = OFF
#pragma config STVREN = OFF
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
//*************************************************************
// Definizione nuovi indirizzi
//*************************************************************
#if defined(__18CXX)
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
//the reset, high priority interrupt, and low priority interrupt
//vectors. However, the current Microchip USB bootloader
//examples are intended to occupy addresses 0x00-0x7FF or
//0x00-0xFFF depending on which bootloader is used. Therefore,
//the bootloader code remaps these vectors to new locations
//as indicated below. This remapping is only necessary if you
//wish to program the hex file generated from this project with
//the USB bootloader. If no bootloader is used, edit the
//usb_config.h file and comment out the following defines:
//#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
//#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
//***********************************************************
//---- I think, this is your case, since you wrote 0x00800 Reset adderess
#define PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER
//#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
//***********************************************************
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
#elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS 0x800
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
#else
#define REMAPPED_RESET_VECTOR_ADDRESS 0x00
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18
#endif
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
extern void _startup (void); // See c018i.c in your C18 compiler dir
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void)
{
_asm goto _startup _endasm
}
#endif
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void)
{
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void)
{
_asm goto YourLowPriorityISRCode _endasm
}
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
//Note: If this project is built while one of the bootloaders has
//been defined, but then the output hex file is not programmed with
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
//As a result, if an actual interrupt was enabled and occured, the PC would jump
//to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space). This
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
//(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup". This
//would effective reset the application.
//To fix this situation, we should always deliberately place a
//"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
//"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18. When the output
//hex file of this project is programmed with the bootloader, these sections do not
//get bootloaded (as they overlap the bootloader space). If the output hex file is not
//programmed using the bootloader, then the below goto instructions do get programmed,
//and the hex file still works like normal. The below section is only required to fix this
//scenario.
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void High_ISR (void)
{
_asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void)
{
_asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
}
#endif //end of "#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER)"
#pragma code
//These are your actual interrupt handling routines.
// #pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode (void) {
// Variabile che conterrà i dati ricevuti
unsigned char data;
// Flag per controllare la ricezione del primo carattere
static char firstTime = 0;
// Controllo che l'interrupt sia stato generato dall'USART
if (INTCONbits.TMR0IF == 1 )
{
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
TMR0H=0x67;
TMR0L=0x69;
}
// #pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode()
{
//Check which interrupt flag caused the interrupt.
//Service the interrupt
//Clear the interrupt flag
//Etc.
} //This return will be a "retfie", since this is in a #pragma interruptlow section
#endif
//*************************************************
// Programma Principale
//*************************************************
void main (void){
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
// Imposto PORTA con RA0 come output
LATA = 0x00;
TRISA = 0x00;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0b11111101;
// Abilito modalita' compatibile (di default vale gia' 0)
RCONbits.IPEN = 0;
// Modalita' a 16 bit
T0CONbits.T08BIT = 0;
// Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 64
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 1;
// Abilito l'interrupt globale
INTCONbits.GIE = 1;
// Abilito il timer
T0CONbits.TMR0ON=1;
// Abilito interrupt sul Timer 0
INTCONbits.TMR0IE = 1 ;
// Calcolo il timer per avviare un interrupt gni 0.5 sec
// dati per il calcolo:
// Fosc = 20MHz => 20.000.000Hz
// Prescaler = 64
// Periodo del clock => Tosc=1/(20.000.000)=0.05 us
// Il timer si incrementa dopo 4 cicli di clock => Ttimer=Tosc*4=0.05*4=0.2us
// Il prescaler rallenta il timer di 64 volte Tprescaler=Ttimer*64=0.2*64=12.8us
// Avendo attivato il timer a 16 bit l'overflow avviene dopo 2^16 scillazioni = 65535
// Quindi avremo un interrupt ogni 12.8*65535=0.8338sec ( troppo )
// Per conoscere il valore da caricare nel timer, dobbiamo conoscere il valore in uscita da prescaler
// Conteggi= 0.5/((0.05*4*64)/1000000)=39062
// Il valore da caricarenel Timer è 65535-39032=26473 in Hex=>0x6769
// Carico il timer con i valori alto e basso di 0x6769
TMR0H=0x67;
TMR0L=0x69;
LATA=0xFF;
Delay1KTCYx(250);
LATA=0x00;
Delay1KTCYx(250);
// Ciclo infinito
while (1)
{
/* LATA=0xFF;
Delay10KTCYx(25);
LATA=0x00;
Delay10KTCYx(25);
*/
}
}
Dove sbaglio??
grazie
PS: allego l'intero progetto. Per caricare con il bootloader il pin da mettere a massa è RC0
Allegato BOOTLOADER18F2550.rar non trovato
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Alex68
- Autore della discussione
- Visitatori
10 Anni 11 Mesi fa #25
da Alex68
Risposta da Alex68 al topic Bootloader e pic18f2550, come funziona ???
Non c'è nessuno che mi possa aiutare???
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Alex68
- Autore della discussione
- Visitatori
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Login
© LaurTec 2006 - 2024