In this project, you are going to add UART, and ADC interface to your project 2.
Working principle of Application:
1. 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.
2. The Knight Rider pattern and the RUN led is running as before.
Knight rider program:
//Project_1 Template
#include <xc.h>
#include <stdint.h>
#include <stdbool.h>
#define _XTAL_FREQ 8000000UL
// CONFIG2
#pragma config POSCMOD = XT // Primary Oscillator Select->XT Oscillator mode selected
#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function->OSC2/CLKO/RC15 functions as CLKO (FOSC/2)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor->Clock switching and Fail-Safe Clock Monitor are disabled
#pragma config FNOSC = PRI // Oscillator Select->Primary Oscillator (XT, HS, EC)
#pragma config IESO = ON // Internal External Switch Over Mode->IESO mode (Two-Speed Start-up) enabled
// CONFIG1
#pragma config WDTPS = PS32768 // Watchdog Timer Postscaler->1:32768
#pragma config FWPSA = PR128 // WDT Prescaler->Prescaler ratio of 1:128
#pragma config WINDIS = ON // Watchdog Timer Window->Standard Watchdog Timer enabled,(Windowed-mode is disabled)
#pragma config FWDTEN = OFF // Watchdog Timer Enable->Watchdog Timer is disabled
#pragma config ICS = PGx2 // Comm Channel Select->Emulator/debugger uses EMUC2/EMUD2
//#pragma config COE = OFF // Set Clip On Emulation Mode->Reset Into Operational Mode
#pragma config BKBUG = OFF // Background Debug->Device resets into Operational mode
#pragma config GWRP = OFF // General Code Segment Write Protect->Writes to program memory are allowed
#pragma config GCP = OFF // General Code Segment Code Protect->Code protection is disabled
#pragma config JTAGEN = OFF // JTAG Port Enable->JTAG port is disabled
////////////////////////////////////////////////////////////////////////////////
//Function Proto type
void SYSTEM_Initialize(void);
void OSCILLATOR_Initialize(void);
void PIN_MANAGER_Initialize(void);
void INTERRUPT_Initialize (void);
void TMR1_Initialize (void);
void delayFunc(void);
////////////////////////////////////////////////////////////////////////////////
//Global variables
unsigned int count1 = 500;
unsigned int count2 = 500;
///////////////////////////////////////////////////////////////////////////////
int main(void)
{
// initialize the device
SYSTEM_Initialize();
while (1)
{
patternOne:
PORTA &= ~0x7F;
delayFunc();
PORTAbits.RA6 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA5 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA4 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA3 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA2 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA1 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA0 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
LATA &= ~0x7F;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA0 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA1 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA2 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA3 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA4 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA5 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
PORTAbits.RA6 = 1;
if(PORTDbits.RD6 == 0) goto patternTwo;
delayFunc();
patternTwo:
LATA &= ~0x7F;
delayFunc();
PORTAbits.RA0 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA1 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA2 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA3 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA4 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA5 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA6 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
LATA &= ~0x7F;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA6 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA5 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA4 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA3 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA2 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA1 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
PORTAbits.RA0 = 1;
if(PORTDbits.RD6 == 1) goto patternOne;
delayFunc();
}
return -1;
}
////////////////////////////////////////////////////////////////////////////////
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize();
OSCILLATOR_Initialize();
INTERRUPT_Initialize();
TMR1_Initialize();
}
////////////////////////////////////////////////////////////////////////////////
void OSCILLATOR_Initialize(void)
{
// NOSC PRI; SOSCEN disabled; OSWEN Switch is Complete;
__builtin_write_OSCCONL((uint8_t) (0x0200 & 0x00FF));
// RCDIV FRC/2; DOZE 1:8; DOZEN disabled; ROI disabled;
CLKDIV = 0x3100;
// TUN Center frequency;
OSCTUN = 0x0000;
// WDTO disabled; TRAPR disabled; SWDTEN disabled; EXTR disabled; POR disabled; SLEEP disabled; BOR disabled; IDLE disabled; IOPUWR disabled; VREGS disabled; CM disabled; SWR disabled;
RCON = 0x0000;
}
////////////////////////////////////////////////////////////////////////////////
void PIN_MANAGER_Initialize(void)
{
/****************************************************************************
* Setting the Output Latch SFR(s)
***************************************************************************/
LATA = 0x0000;
LATB = 0x0000;
LATC = 0x0000;
LATD = 0x0000;
LATE = 0x0000;
LATF = 0x0000;
LATG = 0x0000;
/****************************************************************************
* Setting the GPIO Direction SFR(s)
***************************************************************************/
TRISA = 0x0000;
TRISB = 0xFFFF;
TRISC = 0xF01E;
TRISD = 0xFFFF;
TRISE = 0x03FF;
TRISF = 0x31FF;
TRISG = 0xF3CF;
/****************************************************************************
* Setting the Weak Pull Up and Weak Pull Down SFR(s)
***************************************************************************/
CNPU1 = 0x0000;
CNPU2 = 0x0000;
/****************************************************************************
* Setting the Open Drain SFR(s)
***************************************************************************/
ODCA = 0x0000;
ODCB = 0x0000;
ODCC = 0x0000;
ODCD = 0x0000;
ODCE = 0x0000;
ODCF = 0x0000;
ODCG = 0x0000;
/****************************************************************************
* Setting the Analog/Digital Configuration SFR(s)
***************************************************************************/
AD1PCFG = 0x00C0;
}
////////////////////////////////////////////////////////////////////////////////
void INTERRUPT_Initialize (void)
{
}
void TMR1_Initialize (void)
{
TMR1 = 0x0000;
PR1 = 54688;
IFS0bits.T1IF = false;
IEC0bits.T1IE = true;
IPC0bits.T1IP = 4;
T1CON = 0x8030;
}
////////////////////////////////////////////////////////////////////////////////
void delayFunc(void)
{
int j,k;
int a;
for(j = 0; j < count1; j++)
{
for(k=0; k < count2; k++)
{
a = 0;
}
}
}
void __attribute__ (( interrupt, no_auto_psv))_T1Interrupt()
{
PORTA ^= 0x80;
IFS0bits.T1IF = false;
}
////////////////////////////////////////////////////////////////////////////////
/**
End of File
*/
3 answers
1. Add the necessary include files for UART and ADC:
```c
#include <uart.h>
#include <adc.h>
```
2. Initialize UART2 and ADC modules in the SYSTEM_Initialize() function:
```c
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize();
OSCILLATOR_Initialize();
INTERRUPT_Initialize();
TMR1_Initialize();
// Initialize UART2
UART2_Initialize();
// Initialize ADC
ADC_Initialize();
ADC_Enable();
}
```
3. Create a function to read the value of the potentiometer and temperature sensor using the ADC:
```c
float readPotentiometer()
{
// Read AN0 (potentiometer) value
ADC_ChannelSelect(0x00);
ADC_StartConversion();
while(!ADC_IsConversionDone());
uint16_t potValue = ADC_ReadResult();
// Convert ADC value to voltage
float voltage = (potValue / 1023.0) * 3.3;
return voltage;
}
float readTemperature()
{
// Read AN1 (temperature sensor) value
ADC_ChannelSelect(0x01);
ADC_StartConversion();
while(!ADC_IsConversionDone());
uint16_t tempValue = ADC_ReadResult();
// Convert ADC value to temperature in centigrade
float temperature = (tempValue / 1023.0) * 100;
return temperature;
}
```
4. Modify the main loop to read the potentiometer and temperature values, and send them out through UART2:
```c
while (1)
{
// Read potentiometer and temperature values
float potVoltage = readPotentiometer();
float temperature = readTemperature();
// Convert values to strings
char potVoltageStr[10], temperatureStr[10];
sprintf(potVoltageStr, "%.2f", potVoltage);
sprintf(temperatureStr, "%.2f", temperature);
// Send potentiometer voltage and temperature values through UART2
UART2_WriteString("Potentiometer Voltage: ");
UART2_WriteString(potVoltageStr);
UART2_WriteString("V\r\n");
UART2_WriteString("Temperature: ");
UART2_WriteString(temperatureStr);
UART2_WriteString("C\r\n");
// Refresh the knight rider pattern
patternOne:
// ...
}
```
5. Finally, make sure to configure UART2 for a baud rate of 9600 in the UART_Initialize() function:
```c
void UART2_Initialize(void)
{
U2BRG = 51;
U2MODE = 0x8000; // Enable UART2 using U2MODE Register
U2STA = 0x0400; // Enable Transmit (UTXEN)
U2MODEbits.PDSEL = 0; // 8-bit data, no parity
U2MODEbits.STSEL = 0; // 1 stop bit
}
```
Note: This code assumes that you are using the UART2 module and AN0 (potentiometer) and AN1 (temperature sensor) channels of the ADC on the Explorer 16 board. Make sure to adjust the code accordingly if you are using different modules or channels.