Hi all,
I have the program below, i have trying to use the AD in 18F2550. I searched many samples and tips, but not work.
My idea is read position in a touch screen. The circuit (hardware) is ok, tested. The voltage is changing correctly, but the 18F2550 dont convert to digital.
How work:
- CPU (Z80) generate INT to INT2 in 18f2550, and send the byte 0x01 which indicates to read the touch;
- 18f2550 go to read touch. First I configure all necessary, OUT_TFFT indicate what was read (x- or y-), in this case, 18f2550 only leave the loop if read anything in x- first;
- When AD finish, it generate a interrupt low priority, and verify if any was read, if "0x00", it generate a delay and start new conversion (in interruption yet).
- If was read a valid number (padlido <> 0x00), the system go to next positon (y-) and do same operations;
- When was read a valid number in x- and y-, he compare if is equal to previous ppox and ppoxy, if is, start all process again, until read a valid number;
- if valid number is read an diferente from previous, he generate a interrupt in cpu Z80, and wait cpu returna to get the positons.
My problem is that the 18f2550 is not reading any valor correct, he is only reading the same valor, 0x00, and not leave from process.
Ty for help.
below, my code:
I have the program below, i have trying to use the AD in 18F2550. I searched many samples and tips, but not work.
My idea is read position in a touch screen. The circuit (hardware) is ok, tested. The voltage is changing correctly, but the 18F2550 dont convert to digital.
How work:
- CPU (Z80) generate INT to INT2 in 18f2550, and send the byte 0x01 which indicates to read the touch;
- 18f2550 go to read touch. First I configure all necessary, OUT_TFFT indicate what was read (x- or y-), in this case, 18f2550 only leave the loop if read anything in x- first;
- When AD finish, it generate a interrupt low priority, and verify if any was read, if "0x00", it generate a delay and start new conversion (in interruption yet).
- If was read a valid number (padlido <> 0x00), the system go to next positon (y-) and do same operations;
- When was read a valid number in x- and y-, he compare if is equal to previous ppox and ppoxy, if is, start all process again, until read a valid number;
- if valid number is read an diferente from previous, he generate a interrupt in cpu Z80, and wait cpu returna to get the positons.
My problem is that the 18f2550 is not reading any valor correct, he is only reading the same valor, 0x00, and not leave from process.
Ty for help.
below, my code:
Rich (BB code):
#include <pic18f2550.h>
static __code char __at(__CONFIG1H) conf1H = _OSC_INTOSC__USB_HS_1H;
//static __code char __at(__CONFIG1L) conf1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L;
static __code char __at(__CONFIG2H) conf2H = _WDT_DISABLED_CONTROLLED_2H;
static __code char __at(__CONFIG3H) conf3H = _MCLRE_MCLR_OFF_RE3_ON_3H;
static __code char __at(__CONFIG4L) conf4 = _LVP_OFF_4L & _ENHCPU_OFF_4L; // & _BACKBUG_OFF_4L & _STVR_OFF_4L;
#define OUT_TFFT LATAbits.LATA2
#define OUT_CTRLWAIT LATAbits.LATA4
#define OUT_INTZ80 LATAbits.LATA5
#define OUT_CPU0 LATCbits.LATC0
#define OUT_CPU1 LATCbits.LATC1
#define OUT_CPU2 LATCbits.LATC2
#define OUT_CPU3 LATBbits.LATB3
#define OUT_CPU4 LATBbits.LATB4
#define OUT_CPU5 LATBbits.LATB5
#define OUT_CPU6 LATBbits.LATB6
#define OUT_CPU7 LATBbits.LATB7
#define IN_CPU0 PORTCbits.RC0
#define IN_CPU1 PORTCbits.RC1
#define IN_CPU2 PORTCbits.RC2
#define IN_CPU3 PORTBbits.RB3
#define IN_CPU4 PORTBbits.RB4
#define IN_CPU5 PORTBbits.RB5
#define IN_CPU6 PORTBbits.RB6
#define IN_CPU7 PORTBbits.RB7
#define IN_PC5 PORTEbits.RE3
#define IN_PC6 PORTAbits.RA3
//#define IN_CS2 PORTBbits.RB2
// PC6 | PC5 | Result
// 0 | 0 | Ok
// 0 | 1 | WR Data Z80 -> PIC
// 1 | 0 | RD Data PIC -> Z80
// 1 | 1 | RD CTRL PIC -> Z80
//#define debug 1
volatile unsigned char pbyte;
volatile unsigned char pbytectrl;
volatile unsigned char pposx;
volatile unsigned char pposy;
volatile unsigned char padlido;
volatile unsigned char pbyteler[64];
volatile unsigned char ploop;
void EnviaByte();
unsigned char RecebeByte();
void ProcessaAD();
void ProcessaUSB();
void LerTouch();
void ComunicarUSB();
void ComunicarSerial();
void main()
{
// CONFIGURAR PORTAS
OSCCON = 0x70;
ADCON1 = 0x0D; // RA0=AN0, RA1=AN1, TODAS AS DEMAIS ANx = DIGITAIS
PORTA = 0x30;
PORTB = 0x00;
PORTC = 0x00;
TRISA = 0x0B; // RA7-X, RA6-X, RA5-INTZ80, RA4-CTRWAIT, RA3-PC6, RA2-X+/Y+, RA1-AN1, RA0-AN0
TRISB = 0xFC; // RB7 A RB3 - D7 A D3, RB2-INT2/CS2, RB1-SCL, RB0-SCA
TRISC = 0x97; // RC7-RX, RC6-TX, RC5-D+, DC4-D-, RC3-X, RC2 A RC0 - D2 A D0, RE3-PC5
RCON = RCON | 0x80;
PIR1 = 0x00;
PIR2 = 0x00;
PIE1 = 0x00;
PIE2 = 0x00;
IPR1 = 0x00;
IPR2 = 0x00;
INTCON = 0xC0; // 0xC0
INTCON2 = 0xE0; // 0xE0
INTCON3 = 0x90; // 0x90
ADCON2bits.ADFM = 0x01; // right justied
ADCON2bits.ACQT2 = 0x00;
ADCON2bits.ACQT1 = 0x00;
ADCON2bits.ACQT0 = 0x00; // 0 TAD
ADCON2bits.ADCS2 = 0x01;
ADCON2bits.ADCS1 = 0x01;
ADCON2bits.ADCS0 = 0x01; // FRC
ADCON0bits.ADON = 0x01; // ADC ON
pbyte = 0x00;
pbytectrl = 0x00;
OUT_TFFT = 0;
INTCON3bits.INT2IE = 0x01;
PIE1bits.ADIE = 0x01;
while(1)
{
switch (pbyte)
{
case 0x01:
LerTouch();
break;
case 0x02:
ComunicarUSB();
break;
case 0x03:
ComunicarSerial();
break;
}
}
}
void isr_reset(void) __interrupt 0
{
INTCON3bits.INT2IE = 0x00;
PIE1bits.ADIE = 0x00;
INTCON3bits.INT2IF = 0x00;
PIR1bits.ADIF = 0x00;
PIR2bits.USBIF = 0x00;
main();
}
void isr_int2(void) __interrupt 1
{
// DESLIGA INTERRUPCAO PARA EVITAR NOVAS SOLICITACOES
OUT_INTZ80 = 0x01;
INTCON3bits.INT2IE = 0x00;
PIE1bits.ADIE = 0x00;
if (INTCON3bits.INT2IF == 0x01) // INTERRUPCAO SOLICITADA PELO Z80
{
// DESLIGA FLAG DE INT2
INTCON3bits.INT2IF = 0x00;
#ifndef debug
if (IN_PC6 == 0 && IN_PC5 == 1) // WR DADOS
pbyte = RecebeByte();
if (IN_PC6 == 1 && IN_PC5 == 0) // RD DADOS
EnviaByte;
if (IN_PC6 == 1 && IN_PC5 == 1) // RD CTRL
EnviaByte;
#endif
}
// LIGA INTERRUPCAO
INTCON3bits.INT2IE = 0x01;
PIE1bits.ADIE = 0x01;
}
void isr_AD_USB(void) __interrupt 2
{
// DESLIGA INTERRUPCOES PARA EVITAR NOVAS SOLICITACOES
PIE1bits.ADIE = 0x00;
if (PIR1bits.ADIF == 0x01) // INTERRUPCAO SOLICITADA PELO CANAL DE A/D
{
PIR1bits.ADIF = 0x00;
ProcessaAD();
}
else if (PIR2bits.USBIF == 0x01) // INTERRUPCAO SOLICITADA PELO CANAL USB
{
PIR2bits.USBIF = 0x00;
ProcessaUSB();
}
// LIGA INTERRUPCOES
PIE1bits.ADIE = 0x01;
}
void EnviaByte()
{
unsigned char oldTRISB, oldTRISC, vbyte;
// SALVA VALORES ATUAIS DO STATUS DAS PORTAS
oldTRISB = TRISB;
oldTRISC = TRISC;
// DEFINE NOVOS VALORES
TRISB = 0x04;
TRISC = 0x90;
vbyte = 0x00;
if (IN_PC6 == 1 && IN_PC5 == 0) // RD DADOS
vbyte = pbyteler[ploop];
else if (IN_PC6 == 1 && IN_PC5 == 1) // RD CTRL
vbyte = pbytectrl;
if (pbytectrl != 0x00)
{
ploop++;
if (ploop >= (pbytectrl & 0x3F))
pbytectrl = 0x00;
}
// ENVIA BYTE PELA PORTA
OUT_CPU0 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU1 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU2 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU3 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU4 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU5 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU6 = vbyte & 0x01;
vbyte = vbyte >> 1;
OUT_CPU7 = vbyte & 0x01;
// RETIRA Z80 DO WAIT
OUT_CTRLWAIT = 0x00;
// AGUARDA ATE A CPU SAIR DA LEITURA
while (IN_PC6 != 0x00 || IN_PC5 != 0x00);
// RECOLOCA SINAL WAIT PARA PROXIMO ACESSO Z80
OUT_CTRLWAIT = 0x01;
// VOLTA VALORES ATUAIS DAS PORTAS
PORTB = 0x00;
PORTC = 0x00;
TRISB = oldTRISB;
TRISC = oldTRISC;
}
unsigned char RecebeByte()
{
unsigned char oldTRISB, oldTRISC;
unsigned int vbyte, vbyte1;
// SALVA VALORES ATUAIS DO STATUS DAS PORTAS
oldTRISB = TRISB;
oldTRISC = TRISC;
// DEFINE NOVOS VALORES
TRISB = 0xFC;
TRISC = 0x97;
// RECEBER VALOR PELAS 2 PORTAS
vbyte = PORTB & 0xF8;
vbyte1 = PORTC & 0x07;
vbyte = vbyte + vbyte1;
// RETIRA Z80 DO WAIT
OUT_CTRLWAIT = 0x00;
// AGUARDA ATE A CPU SAIR DA GRAVAÇÃO
while (IN_PC6 != 0x00 || IN_PC5 != 0x00);
// RECOLOCA SINAL WAIT PARA PROXIMO ACESSO Z80
OUT_CTRLWAIT = 0x01;
// VOLTA VALORES ATUAIS DAS PORTAS
PORTB = 0x00;
PORTC = 0x00;
TRISB = oldTRISB;
TRISC = oldTRISC;
return vbyte;
}
void ProcessaAD()
{
unsigned int cc;
padlido = ADRESL;
padlido += (ADRESH << 6);
if (padlido == 0x00)
{
for (cc = 0; cc <= 0x1FF; cc++);
ADCON0bits.GO = 0x01;
}
}
void ProcessaUSB()
{
pbytectrl = 0x20; // Indica USB (0b10) e 1 byte de informacao (0b000000) (valor + 1)
}
void LerTouch()
{
unsigned char vloop;
unsigned char pposantx, pposanty;
unsigned int cc;
pbyte = 0x00;
vloop = 0x01;
pposantx = 0x00;
pposanty = 0x00;
pposantx = pposx;
pposanty = pposy;
OUT_TFFT = 0x01;
ADCON0bits.CHS0 = 0x00;
ADCON0bits.CHS1 = 0x00;
ADCON0bits.CHS2 = 0x00;
ADCON0bits.CHS3 = 0x00;
// Primeiro Espera Um Touch no LCD pelo Canal X+
while (vloop == 0x01)
{
// Inicia Conversao
padlido = 0x00;
PIR1bits.ADIF = 0x00;
for (cc = 0; cc <= 0x0FF; cc++);
ADCON0bits.GO = 0x01;
// Aguarda a Interrupção do AD com o Valor
while (padlido == 0x00);
if (OUT_TFFT == 0x01)
{
pposx = padlido;
// MUDA PARA O CANAL Y+
OUT_TFFT = 0x00;
ADCON0bits.CHS0 = 0x01;
}
else
{
pposy = padlido;
if (pposx != pposantx || pposy != pposanty)
vloop = 0x00;
}
}
// Finaliza, envia bytes pro Z80
pbyteler[0] = pposx;
pbyteler[1] = pposy;
ploop = 0x00;
pbytectrl = 0x41; // Indica AD (0b01) e 2 bytes de informacao (0b000001) (valor + 1)
OUT_INTZ80 = 0x00;
}
void ComunicarUSB()
{
pbyte = 0x00;
}
void ComunicarSerial()
{
pbyte = 0x00;
}
Last edited by a moderator: