Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using the ADC in the 16F877A to measure short signals from a Piezo

Status
Not open for further replies.
1. Get light to blink
2. Send a test byte out serial port
3. Read A/D, send out serial port
 
Part of the problem has been fixed. There were 3 major problems in total:

1: I had forgotten to connect the MCLR pin to a positive supply (with a pull up resistor and capacitor combination of course). So the chip was in constant reset.

2: I had the clock set to RC, instead of HS. I am using a 4 MHz external oscillator.

3: The PIC chip I was using was broken anyway. Hooray for wasting my time.

===

Otherwise the code's still not working properly; nothing's coming out the serial port, HOWEVER, there is a confirmation that the chip is doing what it's supposed to be doing.

From the readings:

It takes around 0.16 ms to sample a pin.
It takes around 1.31 ms to sample 8 pins (1 loop)
It takes 335 ms to loop around 255 times - way too long (The amount of time PORTB 0:3 have high values.)

On the other hand it takes 0.5 ms to get out of the transmission loop. (The amount of time PORTB 4:7 have high values.)

This is the code so far:

===

#include <htc.h>

void main()
{
// AC activate flag
// The PCFG bit will setup all PORTA inputs available to Analogue inputs
// AD result needs to be left justified
// 0000 AN0 - AN7 Analogue inputs
// External Crystal Clock Oscillator works at 4.000 MHz

ADCON0 = 0x81;
ADCON1 = 0x00;

TRISA = 0x2F; // Set AN0 - AN4 on PORTA to be inputs
TRISB = 0x00;
TRISC = 0xC0; // Setting up USART for transmission from Tx PIN Asynchronous Mode
TRISD = 0x00;
TRISE = 0x17; // PSPMODE bit set to turn PORTE into I/O ports - AN5 - AN7 on PORTE to be inputs
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

INTCON = 0x00; // Interrupt Registers
// PIR1 = 0x00; // Don't touch this register - Bit 4 is the TXREG clear bit
RCSTA = 0x80; // Serial Port ENABLE bit
// PIE1 = 0x00; // Bit 5 TXIE controls the interrupt function for TXREG
TXSTA = 0x36; // Setting up USART for Tx
SPBRG = 0x00; // Baud Rate Generator

unsigned char timerStart;
unsigned int timerCount;
unsigned int timerEnd;
unsigned char i; // general index counter
unsigned char pLabel; // general storage
unsigned char pData[8]; // storage for A/D values from analogue inputs
unsigned char pTimer[8]; // storage for timer values
unsigned char acquire0; // Acquisition Time Delay counter
// adc_on = 1;
// Activate AD module
timerStart = 0;
timerCount = 0;
timerEnd = 255; // Ending value for when information is sent to USART

while (1)
{
{

PORTB = 0x0F; // Output TEST

// Channel 0 AN0 PIN 2
ADCON0 = 0x81;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}


if (ADRESH > pData[0])
{
timerStart = 1;
pData[0] = ADRESH; // Send value to pData[0];
pTimer[0] = timerCount; // Send timer value to pTimer[0];
}

}

{
asm ("clrwdt");
}

{
// Channel 1 AN1 PIN 3
ADCON0 = 0x89;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}


if (ADRESH > pData[1])
{
timerStart = 1;
pData[1] = ADRESH; // Send value to pData[1];
pTimer[1] = timerCount; // Send timer value to pTimer[1];
}
}

{
asm ("clrwdt");
}

{
// Channel 2 AN2 PIN 4
ADCON0 = 0x91;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}

if (ADRESH > pData[2])
{
timerStart = 1;
pData[2] = ADRESH; // Send value to pData[2]
pTimer[2] = timerCount; // Send timer value to pTimer[2];
}
}

{
asm ("clrwdt");
}

{
// Channel 3 AN3 PIN 5
ADCON0 = 0x99;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}



if (ADRESH > pData[3])
{
timerStart = 1;
pData[3] = ADRESH; // Send value to pData[3]
pTimer[3] = timerCount; // Send timer value to pTimer[3];
}

}

{
asm ("clrwdt");
}

{
// Channel 4 AN4 PIN 7
ADCON0 = 0xA1;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}

if (ADRESH > pData[4])
{
timerStart = 1;
pData[4] = ADRESH; // Send value to pData[4]
pTimer[4] = timerCount; // Send timer value to pTimer[4];
}

}

{
asm ("clrwdt");
}

{
// Channel 5 AN5 PIN 8
ADCON0 = 0xA9;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}



if (ADRESH > pData[5])
{
timerStart = 1;
pData[5] = ADRESH; // Send value to pData[5]
pTimer[5] = timerCount; // Send timer value to pTimer[5];
}

}

{
asm ("clrwdt");
}

{
// Channel 6 AN6 PIN 9
ADCON0 = 0xB1;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}

if (ADRESH > pData[6])
{
timerStart = 1;
pData[6] = ADRESH; // Send value to pData[6]
pTimer[6] = timerCount; // Send timer value to pTimer[6];
}

}

{
asm ("clrwdt");
}

{
// Channel 7 AN7 PIN 10
ADCON0 = 0xB9;

acquire0=4;
for (i=1;i<acquire0;i++) //acquisiton time delay

{
asm("clrwdt");
}

ADGO=1; // Start conversion

while(ADGO==1)

{
asm("clrwdt");
}

if (ADRESH > pData[7])
{
timerStart = 1;
pData[7] = ADRESH; // Send value to pData[7]
pTimer[7] = timerCount; // Send timer value to pTimer[7];
}

}

{
asm ("clrwdt");
}

/* This should be the code to send stored in the general purpose registers to the Tx*/

if (timerCount >= timerEnd)
{
PORTB = 0xF0; // Data Output TEST
TXREG = 0X55; // Send Data Send Byte

pLabel = 0xA0;

for (i = 0; i<8; i++)
{
TXREG = pLabel; // Send data i Byte 1 - Label A0
TXREG = pTimer; // Send data i Byte 2 - Timer Value
TXREG = pData; // Send data i Byte 3 - A/D result
pLabel++;
}

for(i = 0; i<8; i++) // clear A/D data and timer arrays
{
pData = 0;
pTimer = 0;
}


timerCount = 0; // Reset Timer
timerStart = 0; // Cycle complete - Turn timer off

{
asm ("clrwdt");
}
}

if (timerStart == 1)
{
timerCount++;
}

{
asm ("clrwdt");
}
} // End while(1)
} // End main

===

What I need to find out is why the TXREG isn't sending anything whatsoever.
 
1: I had forgotten to connect the MCLR pin to a positive supply (with a pull up resistor and capacitor combination of course). So the chip was in constant reset.

2: I had the clock set to RC, instead of HS. I am using a 4 MHz external oscillator.

3: The PIC chip I was using was broken anyway. Hooray for wasting my time.

This is why I tell people to get a light to blink first.

Otherwise the code's still not working properly; nothing's coming out the serial port, HOWEVER, there is a confirmation that the chip is doing what it's supposed to be doing.

From the readings:

WHAT readings?
 
If you look at the code, it's split into two parts:

The first part involves sampling and and polling the 8 ADC ports 255 times.
During this time the values on PORTB 4:7 is high, whilst the other outputs on PORTB are low. This lasts for around 330 ms


The 2nd part involves sending the data by TXREG to the TX pin.
During this time the values on PORTB0:3 is high, whilst the other outputs on PORTB are low. This lasts for around 0.5 ms
 
"Readings" != "If you look at the code"
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top