The Potentiometer (R6) and the temperature sensor (U4) on Explorer 16 board will be read, converted and processed. And the values (pot voltage and temperature in centrigrade) will be sent out through UART2 and will be displayed on a terminal program (Putty/TeraTerm, running in your PC). The UART2 will be running at 9600 baud rate.

Temperature is display 0 even I change the pot value.

#include <xc.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

#define _XTAL_FREQ 8000000UL

// CONFIG2
#pragma config POSCMOD = XT
#pragma config OSCIOFNC = OFF
#pragma config FCKSM = CSDCMD
#pragma config FNOSC = PRI
#pragma config IESO = ON

// CONFIG1
#pragma config WDTPS = PS32768
#pragma config FWPSA = PR128
#pragma config WINDIS = ON
#pragma config FWDTEN = OFF
#pragma config ICS = PGx2
#pragma config BKBUG = OFF
#pragma config GWRP = OFF
#pragma config GCP = OFF
#pragma config JTAGEN = OFF
// Global Variables

volatile bool timer1Flag = false;
unsigned int count1 = 240;
unsigned int count2 = 240;

volatile int potValue = 0;
volatile int tempValue = 0;

void SYSTEM_Initialize(void);
void OSCILLATOR_Initialize(void);
void PIN_MANAGER_Initialize(void);
void INTERRUPT_Initialize(void);
void initializeTimer1(void);
void delayFunc(void);
void ADC_Initialize(void);
void UART2_Initialize(void);
void UART2_Transmit_ADC_Values(void);
int ADC_Read_Potentiometer(void);
int ADC_Read_Temperature(void);
void U2_TxByte(char value);

int main(void) {
SYSTEM_Initialize();
INTERRUPT_Initialize();
// Comment out the following line temporarily to disable interrupts globally
// IEC0 = 0xFFFF;

SRbits.IPL = 0; // Set CPU interrupt priority to 0
initializeTimer1();

int i;
while(1) {
potValue = ADC_Read_Potentiometer();
tempValue = ADC_Read_Temperature();
UART2_Transmit_ADC_Values();
if (PORTDbits.RD6 == 0) { // Switch is CLOSED
// Pattern: Right to Left
LATA = 0; // Clear all LEDs first
for(i = 6; i >= 0; i--) {
LATA |= (1 << i);
delayFunc();
if (PORTDbits.RD6 == 1) break; // Check if switch is OPEN
}
LATA = 0; // Reset LEDs after pattern

// Pattern: Left to Right
for(i = 0; i <= 6; i++) {
LATA |= (1 << i);
delayFunc(); // Reset the flag
if (PORTDbits.RD6 == 1) break; // Check if switch is OPEN
}
LATA = 0; // Reset LEDs after pattern
} else { // Switch is OPEN
// Pattern: Left to Right
LATA = 0; // Clear all LEDs first
for(i = 0; i <= 6; i++) {
LATA |= (1 << i);
delayFunc(); // Reset the flag
if (PORTDbits.RD6 == 0) break; // Check if switch is CLOSED
}
LATA = 0; // Reset LEDs after pattern

// Pattern: Right to Left
for(i = 6; i >= 0; i--) {
LATA |= (1 << i);
delayFunc(); // Reset the flag
if (PORTDbits.RD6 == 0) break; // Check if switch is CLOSED
}
LATA = 0; // Reset LEDs after pattern
}
}

return 0;
}

void initializeTimer1(void) {
T1CON = 0x00; // Stop Timer1 and clear control register
TMR1 = 0; // Clear timer1 value
T1CONbits.TCKPS = 0b11; // Set prescaler to 1:256
PR1 = 65535; // Set period register to achieve close to 1.45 seconds
IPC0bits.T1IP = 1; // Set Timer1 Interrupt Priority Level
IFS0bits.T1IF = 0; // Clear Timer1 Interrupt Flag
IEC0bits.T1IE = 1; // Enable Timer1 interrupt
T1CONbits.TON = 1; // Start Timer1
}

void SYSTEM_Initialize(void) {
PIN_MANAGER_Initialize();
OSCILLATOR_Initialize();
INTERRUPT_Initialize();
ADC_Initialize();
UART2_Initialize();
}

void OSCILLATOR_Initialize(void) {
__builtin_write_OSCCONL((uint8_t) (0x0200 & 0x00FF));
CLKDIV = 0x3100;
OSCTUN = 0x0000;
RCON = 0x0000;

}


void PIN_MANAGER_Initialize(void) {
LATA = 0x0000;
LATB = 0x0000;
LATC = 0x0000;
LATD = 0x0000;
LATE = 0x0000;
LATF = 0x0000;
LATG = 0x0000;

TRISA = 0x0000;
LATAbits.LATA7 = 0; // Initial state of LED D10
TRISB = 0xFFFF;
TRISC = 0xF01E;
TRISD = 0xFFFF;
TRISE = 0x03FF;
TRISF = 0x31FF;
TRISG = 0xF3CF;

CNPU1 = 0x0000;
CNPU2 = 0x0000;
ODCA = 0x0000;
ODCB = 0x0000;
ODCC = 0x0000;
ODCD = 0x0000;
ODCE = 0x0000;
ODCF = 0x0000;
ODCG = 0x0000;
AD1PCFG = 0x00C0;
}

void INTERRUPT_Initialize(void) {}
void ADC_Initialize(void) {
AD1PCFG = 0xFFDF;
AD1CON1 = 0x00E0;
AD1CON2 = 0x0000;
AD1CON3 = 0x1F3F;
AD1CSSL = 0x0000;
AD1CHS = 0x0005;
AD1CON1bits.ADON = 1;
}

void UART2_Initialize(void) {
U2MODE = 0x8000;
U2STA = 0x0000;
U2BRG = 0x0019;
IEC1bits.U2RXIE = 1;
U2STAbits.UTXEN = 1;
IEC1bits.U2TXIE = 0;
IFS1bits.U2RXIF = 0;
IFS1bits.U2TXIF = 0;
IPC7bits.U2RXIP = 1;
IPC7bits.U2TXIP = 0;
U2MODEbits.UARTEN = 1;
U2STAbits.UTXEN = 1;
}

int ADC_Read_Potentiometer(void) {
AD1CHS = 0x0005;
AD1CON1bits.SAMP = 1;
while (!AD1CON1bits.DONE);
return ADC1BUF0;
}

int ADC_Read_Temperature(void) {
// Configure the ADC to sample the correct channel for the temperature sensor
AD1CHS = 0x0004; // Assuming the temperature sensor is connected to AN4
AD1CON1bits.SAMP = 1; // Start sampling
while (!AD1CON1bits.DONE); // Wait for the conversion to complete
return ADC1BUF0; // Read the buffer with the result
}
void U2_TxByte(char value) {
while (!U2STAbits.TRMT); // Wait until the transmit buffer is empty
U2TXREG = value; // Transmit the character
}

void UART2_Transmit_ADC_Values(void) {
char buffer[30]; // Adjust the size as needed for your messages
int i; // Declare 'i' outside the for loops

// Format the potentiometer value and transmit
sprintf(buffer, "Potentiometer: %d\r\n", potValue);
for(i = 0; buffer[i] != '\0'; i++) {
U2_TxByte(buffer[i]);
}

// Format the temperature value and transmit
sprintf(buffer, "Temperature: %d\r\n", tempValue);
for(i = 0; buffer[i] != '\0'; i++) {
U2_TxByte(buffer[i]);
}
// You might want to add code to transmit a line feed or carriage return if necessary
}

void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void) {
IFS0bits.T1IF = 0;
LATAbits.LATA7 ^= 1;
timer1Flag = true;
potValue = ADC_Read_Potentiometer();
tempValue = ADC_Read_Temperature();
UART2_Transmit_ADC_Values();
}

void delayFunc(void) {
int j, k;
for(j = 0; j < count1; j++) {
for(k = 0; k < count2; k++) {
// Busy-wait loop
}
}
}

/**
End of File
*/

User Icon for Bot GPT 3.5 Bot GPT 3.5 answered
11 months ago
The issue with the code could be related to the ADC conversion process. The function `ADC_Read_Potentiometer()` and `ADC_Read_Temperature()` are used to read the values from the potentiometer and temperature sensor, respectively. However, we need to ensure that the ADC module is properly configured and enabled before attempting to read values from it.

To fix the issue, we can add the necessary steps to initialize and enable the ADC module before using it to read values. We can modify the `ADC_Initialize()` function to configure and enable the ADC module. Additionally, we can call this function in the `SYSTEM_Initialize()` function to ensure that the ADC module is initialized before using it.

Here is the updated code:

```c
void ADC_Initialize(void) {
AD1PCFGbits.PCFG4 = 0; // Set AN4 as analog input
AD1CON1bits.FORM = 0b00; // Output format: Integer
AD1CON1bits.SSRC = 0b010; // Sample clock source: Timer3
AD1CON1bits.ASAM = 1; // Auto-sampling
AD1CON2bits.VCFG = 0b000; // Reference voltage: AVDD and AVSS
AD1CON2bits.CSCNA = 0; // Disable scanning
AD1CON2bits.SMPI = 0; // Interrupts at the completion of conversion for each sample/convert sequence
AD1CON2bits.BUFM = 0; // Single buffer mode
AD1CON3bits.ADRC = 0; // Clock derived from system clock
AD1CON3bits.SAMC = 0b11111; // Auto-sample time
AD1CON3bits.ADCS = 0b00000001; // Conversion clock select: Tcy
AD1CHSbits.CH0NA = 0; // Negative input for Channel 0: Vref-
AD1CHSbits.CH0SA = 0b00011; // Positive input for Channel 0: AN4
AD1CON1bits.ADON = 1; // Enable ADC module
}

void SYSTEM_Initialize(void) {
PIN_MANAGER_Initialize();
OSCILLATOR_Initialize();
INTERRUPT_Initialize();
ADC_Initialize();
UART2_Initialize();
}
```

Additionally, make sure that the potentiometer and temperature sensor are connected to the correct analog input pins (AN3 and AN4) on the microcontroller. Double-check the connections to ensure they are correctly wired.

With these modifications, the ADC module should be properly initialized and enabled before reading values from the potentiometer and temperature sensor.