#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
int ADCvalue;
float Voltage;
void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}
void ADC0_InitSWTriggerSeq3_Ch9(void){ volatile unsigned long delay;
SYSCTL_RCGC2_R |= 0x00000010; // 1) activate clock for Port E
delay = SYSCTL_RCGC2_R; // allow time for clock to stabilize
GPIO_PORTE_DIR_R &= ~0x04; // 2) make PE4 input
GPIO_PORTE_AFSEL_R |= 0x04; // 3) enable alternate function on PE2
GPIO_PORTE_DEN_R &= ~0x04; // 4) disable digital I/O on PE2
GPIO_PORTE_AMSEL_R |= 0x04; // 5) enable analog function on PE2
SYSCTL_RCGC0_R |= 0x00010000; // 6) activate ADC0
delay = SYSCTL_RCGC2_R;
SYSCTL_RCGC0_R &= ~0x00000300; // 7) configure for 125K
ADC0_SSPRI_R = 0x0123; // 8) Sequencer 3 is highest priority
ADC0_ACTSS_R &= ~0x0008; // 9) disable sample sequencer 3
ADC0_EMUX_R &= ~0xF000; // 10) seq3 is software trigger
ADC0_SSMUX3_R &= ~0x000F; // 11) clear SS3 field
ADC0_SSMUX3_R += 9; // set channel Ain9 (PE4)
ADC0_SSCTL3_R = 0x0006; // 12) no TS0 D0, yes IE0 END0
ADC0_ACTSS_R |= 0x0008; // 13) enable sample sequencer 3
}
unsigned long ADC0_InSeq3(void){ unsigned long result;
ADC0_PSSI_R = 0x0008; // 1) initiate SS3
while((ADC0_RIS_R&0x08)==0){}; // 2) wait for conversion done
result = ADC0_SSFIFO3_R&0xFFF; // 3) read result
ADC0_ISC_R = 0x0008; // 4) acknowledge completion
return result;
}
void UART_Init(void){ // should be called only once
SYSCTL_RCGC1_R |= 0x00000002; // activate UART1
SYSCTL_RCGC2_R |= 0x00000004; // activate port C
UART1_CTL_R &= ~0x00000001; // disable UART
UART1_IBRD_R = 43; // IBRD = int(80,000,000/(16*115,200)) = int(43.40278)
UART1_FBRD_R = 26; // FBRD = round(0.40278 * 64) = 26
UART1_LCRH_R = 0x00000070; // 8 bit, no parity bits, one stop, FIFOs
UART1_CTL_R |= 0x00000001; // enable UART
GPIO_PORTC_AFSEL_R |= 0x30; // enable alt funct on PC5-4
GPIO_PORTC_DEN_R |= 0x30; // configure PC5-4 as UART1
GPIO_PORTC_PCTL_R = (GPIO_PORTC_PCTL_R&0xFF00FFFF)+0x00220000;
GPIO_PORTC_AMSEL_R &= ~0x30; // disable analog on PC5-4
}
void UART_OutChar(unsigned int data){
while((UART1_FR_R&0x0020) != 0); // wait until TXFF is 0
UART1_DR_R = data;
}
void OutVolt(unsigned long n){ // each integer means 0.01V
UART_OutChar(0x30�+n/100); // digit to the left of the decimal
n = n%100; // 0 to 99
UART_OutChar('.'); // decimal point
UART_OutChar(0x30�+n/10); // tenths digit
n = n%10; // 0 to 9
UART_OutChar(0x30�+n); // hundredths digit
UART_OutChar('V');} // units
int main(void){
PLL_Init(); //Set up system clock
ADC0_InitSWTriggerSeq3_Ch9(); // Initialize ADC
UART_Init(); // Initialize UART
while(1){
ADCvalue= ADC0_InSeq3(); //Store ADC conversion into ADCvalue
Voltage= ADCvalue*3.3/4096; //Convert to voltage
UART_OutChar(ADCvalue);
//OutVolt(Voltage);
}
}