lipming
Newbie level 5
I get this error when i was running the Proteus simulation for a 16f886 seven segment thermometer
"PC=0x00A0 ADC conversion started before” wait “time has expired following previous conversion or channel change"
PC=0x016C ADC conversion started before” wait “time has expired following previous conversion or channel change
and the output on the 7 segment can't be read. It just show very random. The error kept repeating with the same 0x00A0 and 0x016C
I've change one of the transistor but i think that is not the cause of the problem.
Below is the code that i am using.
Anyone has any idea how to solve this?
#include <pic.h>
/* PIC Configuration Bit:
** INTIO - Using Internal RC No Clock
** WDTDIS - Wacthdog Timer Disable
** PWRTEN - Power Up Timer Enable
** MCLRDIS - MCLR functions as IO
** UNPROTECT - Code Un-Protect
** DUNPROTECT - Do not read protect EEPROM data
** BORDIS - Brown Out Detect Disable
** IESODIS - Internal External Switch Over Mode Disable
** FCMDIS - Monitor Clock Fail Safe Disable
** BORV21 - Brown Out Reset 2.1 Volt
*/
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & \
BORDIS & IESOEN & FCMDIS & LVPDIS & DEBUGEN); // Address 0x2007
__CONFIG(BORV21); // Address 0x2008
// Using Internal Clock of 8 MHz
#define FOSC 8000000L
// Variable Used for Thermometer
#define LDR_THRESHOLD 50
#define MAX_DCYCLE 255
const char SSEG[] = {
0b11000000, // 0, LED Segment: A,B,C,D,E,F
0b11111001, // 1, LED Segment: B,C
0b10100100, // 2, LED Segment: A,B,D,E,G
0b10110000, // 3, LED Segment: A,B,C,D,G
0b10011001, // 4, LED Segment: B,C,F,G
0b10010010, // 5, LED Segment: A,C,D,F,G
0b10000010, // 6, LED Segment: A,C,D,E,F,G
0b11111000, // 7, LED Segment: A,B,C
0b10000000, // 8, LED Segment: A,B,C,D,E,F,G
0b10010000, // 9, LED Segment: A,B,C,D,F,G
0b11000110, // C, LED Segment: A,D,E,F
0b10001110 // F, LED Segment: A,E,F,G
};
unsigned char DispDigit[4];
unsigned char DigitCount;
unsigned char TempType;
static void interrupt isr(void)
{
if(T0IF) { // TIMER0 Interrupt Flag
/* Pull Low the Segment */
PORTC = DispDigit[DigitCount];
/* Activate the Digit and Advanced to next Digit */
PORTB = ~(1 << DigitCount++);
/* Reset the Digit Count */
if (DigitCount > 3)
DigitCount=0;
TMR0 = 156; // Initial Value for 3.2 ms Interrupt
T0IF = 0; // Clear TIMER0 interrupt flag
}
}
// Delay Function
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }
void _delay_ms(unsigned int ms)
{
unsigned char i;
do {
i = 4;
do {
_delay_us(164);
} while(--i);
} while(--ms);
}
/* Seven Segment Put Number: Implementing floating value from 0 to 99.9 */
void SSEG_putnum(float number)
{
unsigned char iDigit,iDigit1,iDecimal;
if (number > 99.9) return;
/* Global interrupt disable */
GIE = 0;
iDigit=number; // Convert float to Integer
iDecimal=(number - iDigit) * 10; // Get The Decimal Digit
DispDigit[1]=SSEG[iDecimal]; // First Decimal Digit
if (iDigit >= 10) {
iDigit1=iDigit / 10;
DispDigit[3]=SSEG[iDigit1]; // Second Digit
iDigit=iDigit - (iDigit1 * 10);
} else {
DispDigit[3]=SSEG[0]; // Zero Sign Second Digit
}
DispDigit[2]=SSEG[iDigit] & 0x7F; // First Digit with Decimal Point
/* Global interrupt enable */
GIE = 1;
}
void main(void)
{
unsigned int iValue,iCTemp;
unsigned char ldr_value;
float CentTemp;
OSCCON=0x70; /* Select 8 MHz internal clock */
TRISA = 0xFF; // Input for RA0 to RA7
TRISB = 0x00; // Output for RB0 to RB7
TRISC = 0x00; // Output for RC0 to RC7
ANSEL = 0b00000011; // Set PORT AN0 and AN1 to analog input AN2 to AN7 digital I/O
ANSELH = 0b00000000; // Set Other as Digital I/O
/* Initial Output Port */
PORTC=0xFF;
PORTB=0xFF;
/* Init TIMER0: Period: 1/(Fosc/4) x Prescale x TMR0
0.0005 ms x 64 * 100 = 3.2 ms */
OPTION = 0b00000101; // 1:64 Prescale
TMR0=156; // Interupt every 3.2 ms
T0IE = 1; // Enable interrupt on TMR0 overflow
GIE = 1; // Global interrupt enable
/* Init PWM for Single Output */
CCP1CON=0b00001100; // Single PWM mode; P1A, P1C active-high; P1B, P1D active-high
CCPR1L=MAX_DCYCLE; // Start with Max Duty Cycle
T2CON=0b00000101; // Postscale: 1:1, Timer2=On, Prescale = 1:4
PR2=0x65; // Frequency: 4.90 kHz
TMR2=0; // Start with zero Counter
PSTRCON=0b00001000; // Enable Pulse Steering on P1D (RB4)
/* Initial variables used */
DigitCount=0;
TempType=0; // Centigrade Type
DispDigit[0]=SSEG[10]; // Centigrade Sign
DispDigit[1]=SSEG[0]; // Zero Digit
DispDigit[2]=SSEG[0]; // Zero Digit
DispDigit[3]=SSEG[0]; // Zero Digit
for(;Wink {
/* Get First Sample */
ADCON0=0b11000001; // Select the FRC for 8 MHz. ADC port channel 0, Turn On A2D
ADCON1=0b10110000; // Right Justified, Vref: VCFG1 and VCFG0 (1 Volt Reference)
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp = iValue;
_delay_ms(50);
/* Get Second Sample */
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp += iValue;
_delay_ms(50);
/* Get Third Sample */
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp += iValue;
/* Calculate the Average Centigrade Value */
/* (ADC Value/10.24) / Vref, LM35DZ Out=10mV/C, Vref = 1 Volt */
CentTemp=(iCTemp/3.0)/ 10.24;
/* Read the Light Sensor */
ADCON0=0b11000101; // Select the FRC for 8 MHz. ADC port channel 1, Turn On A2D
ADCON1=0b00000000; // Left Justified, Vref: Vss and Vdd
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
ldr_value = ADRESH; // Get the LDR Value, Ignore the LSB on ADRESL
if (ldr_value > LDR_THRESHOLD)
ldr_value = LDR_THRESHOLD;
CCPR1L=MAX_DCYCLE - (5 * ldr_value); // Set the PWM Duty Cycle
/* Read the RA4 Switch */
if (RA4 == 0) { // Change the Thermometer Type when pressed
_delay_ms(1);
if (RA4 == 0) { // Read again for Simple Debounce
TempType=~TempType; // Change Type Flag
}
}
/* Set the Temperature Type */
if (TempType) {
/* Farenheight = 9/5 x Centigrade + 32 */
CentTemp=((9/5) * CentTemp) + 32;
DispDigit[0]=SSEG[11]; // Fahrenheit Sign
} else {
DispDigit[0]=SSEG[10]; // Centigrade Sign
}
/* Now Display The Result */
SSEG_putnum(CentTemp);
_delay_ms(200);
}
}
/* EOF: pictemp.c */
"PC=0x00A0 ADC conversion started before” wait “time has expired following previous conversion or channel change"
PC=0x016C ADC conversion started before” wait “time has expired following previous conversion or channel change
and the output on the 7 segment can't be read. It just show very random. The error kept repeating with the same 0x00A0 and 0x016C
I've change one of the transistor but i think that is not the cause of the problem.
Below is the code that i am using.
Anyone has any idea how to solve this?
#include <pic.h>
/* PIC Configuration Bit:
** INTIO - Using Internal RC No Clock
** WDTDIS - Wacthdog Timer Disable
** PWRTEN - Power Up Timer Enable
** MCLRDIS - MCLR functions as IO
** UNPROTECT - Code Un-Protect
** DUNPROTECT - Do not read protect EEPROM data
** BORDIS - Brown Out Detect Disable
** IESODIS - Internal External Switch Over Mode Disable
** FCMDIS - Monitor Clock Fail Safe Disable
** BORV21 - Brown Out Reset 2.1 Volt
*/
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & \
BORDIS & IESOEN & FCMDIS & LVPDIS & DEBUGEN); // Address 0x2007
__CONFIG(BORV21); // Address 0x2008
// Using Internal Clock of 8 MHz
#define FOSC 8000000L
// Variable Used for Thermometer
#define LDR_THRESHOLD 50
#define MAX_DCYCLE 255
const char SSEG[] = {
0b11000000, // 0, LED Segment: A,B,C,D,E,F
0b11111001, // 1, LED Segment: B,C
0b10100100, // 2, LED Segment: A,B,D,E,G
0b10110000, // 3, LED Segment: A,B,C,D,G
0b10011001, // 4, LED Segment: B,C,F,G
0b10010010, // 5, LED Segment: A,C,D,F,G
0b10000010, // 6, LED Segment: A,C,D,E,F,G
0b11111000, // 7, LED Segment: A,B,C
0b10000000, // 8, LED Segment: A,B,C,D,E,F,G
0b10010000, // 9, LED Segment: A,B,C,D,F,G
0b11000110, // C, LED Segment: A,D,E,F
0b10001110 // F, LED Segment: A,E,F,G
};
unsigned char DispDigit[4];
unsigned char DigitCount;
unsigned char TempType;
static void interrupt isr(void)
{
if(T0IF) { // TIMER0 Interrupt Flag
/* Pull Low the Segment */
PORTC = DispDigit[DigitCount];
/* Activate the Digit and Advanced to next Digit */
PORTB = ~(1 << DigitCount++);
/* Reset the Digit Count */
if (DigitCount > 3)
DigitCount=0;
TMR0 = 156; // Initial Value for 3.2 ms Interrupt
T0IF = 0; // Clear TIMER0 interrupt flag
}
}
// Delay Function
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }
void _delay_ms(unsigned int ms)
{
unsigned char i;
do {
i = 4;
do {
_delay_us(164);
} while(--i);
} while(--ms);
}
/* Seven Segment Put Number: Implementing floating value from 0 to 99.9 */
void SSEG_putnum(float number)
{
unsigned char iDigit,iDigit1,iDecimal;
if (number > 99.9) return;
/* Global interrupt disable */
GIE = 0;
iDigit=number; // Convert float to Integer
iDecimal=(number - iDigit) * 10; // Get The Decimal Digit
DispDigit[1]=SSEG[iDecimal]; // First Decimal Digit
if (iDigit >= 10) {
iDigit1=iDigit / 10;
DispDigit[3]=SSEG[iDigit1]; // Second Digit
iDigit=iDigit - (iDigit1 * 10);
} else {
DispDigit[3]=SSEG[0]; // Zero Sign Second Digit
}
DispDigit[2]=SSEG[iDigit] & 0x7F; // First Digit with Decimal Point
/* Global interrupt enable */
GIE = 1;
}
void main(void)
{
unsigned int iValue,iCTemp;
unsigned char ldr_value;
float CentTemp;
OSCCON=0x70; /* Select 8 MHz internal clock */
TRISA = 0xFF; // Input for RA0 to RA7
TRISB = 0x00; // Output for RB0 to RB7
TRISC = 0x00; // Output for RC0 to RC7
ANSEL = 0b00000011; // Set PORT AN0 and AN1 to analog input AN2 to AN7 digital I/O
ANSELH = 0b00000000; // Set Other as Digital I/O
/* Initial Output Port */
PORTC=0xFF;
PORTB=0xFF;
/* Init TIMER0: Period: 1/(Fosc/4) x Prescale x TMR0
0.0005 ms x 64 * 100 = 3.2 ms */
OPTION = 0b00000101; // 1:64 Prescale
TMR0=156; // Interupt every 3.2 ms
T0IE = 1; // Enable interrupt on TMR0 overflow
GIE = 1; // Global interrupt enable
/* Init PWM for Single Output */
CCP1CON=0b00001100; // Single PWM mode; P1A, P1C active-high; P1B, P1D active-high
CCPR1L=MAX_DCYCLE; // Start with Max Duty Cycle
T2CON=0b00000101; // Postscale: 1:1, Timer2=On, Prescale = 1:4
PR2=0x65; // Frequency: 4.90 kHz
TMR2=0; // Start with zero Counter
PSTRCON=0b00001000; // Enable Pulse Steering on P1D (RB4)
/* Initial variables used */
DigitCount=0;
TempType=0; // Centigrade Type
DispDigit[0]=SSEG[10]; // Centigrade Sign
DispDigit[1]=SSEG[0]; // Zero Digit
DispDigit[2]=SSEG[0]; // Zero Digit
DispDigit[3]=SSEG[0]; // Zero Digit
for(;Wink {
/* Get First Sample */
ADCON0=0b11000001; // Select the FRC for 8 MHz. ADC port channel 0, Turn On A2D
ADCON1=0b10110000; // Right Justified, Vref: VCFG1 and VCFG0 (1 Volt Reference)
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp = iValue;
_delay_ms(50);
/* Get Second Sample */
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp += iValue;
_delay_ms(50);
/* Get Third Sample */
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
iValue=ADRESL; // Get the 8 bit LSB result
iValue += (ADRESH << Cool; // Get the 2 bit MSB result
iCTemp += iValue;
/* Calculate the Average Centigrade Value */
/* (ADC Value/10.24) / Vref, LM35DZ Out=10mV/C, Vref = 1 Volt */
CentTemp=(iCTemp/3.0)/ 10.24;
/* Read the Light Sensor */
ADCON0=0b11000101; // Select the FRC for 8 MHz. ADC port channel 1, Turn On A2D
ADCON1=0b00000000; // Left Justified, Vref: Vss and Vdd
GODONE=1; // initiate conversion on the channel 0
while(GODONE) continue; // Wait conversion done
ldr_value = ADRESH; // Get the LDR Value, Ignore the LSB on ADRESL
if (ldr_value > LDR_THRESHOLD)
ldr_value = LDR_THRESHOLD;
CCPR1L=MAX_DCYCLE - (5 * ldr_value); // Set the PWM Duty Cycle
/* Read the RA4 Switch */
if (RA4 == 0) { // Change the Thermometer Type when pressed
_delay_ms(1);
if (RA4 == 0) { // Read again for Simple Debounce
TempType=~TempType; // Change Type Flag
}
}
/* Set the Temperature Type */
if (TempType) {
/* Farenheight = 9/5 x Centigrade + 32 */
CentTemp=((9/5) * CentTemp) + 32;
DispDigit[0]=SSEG[11]; // Fahrenheit Sign
} else {
DispDigit[0]=SSEG[10]; // Centigrade Sign
}
/* Now Display The Result */
SSEG_putnum(CentTemp);
_delay_ms(200);
}
}
/* EOF: pictemp.c */