Hello Folks
Got myself stuck on a problem.
I'm trying to use the TM4C123GH launch pad as a timer and the ADC to sample the size of the object.
basically I'm trying to measure the size of a drop of water using the ADC then start a timer for specified delay.
I got the timer to work, but I cannot figure out how to get the ADC to sample when the Timer has activated the ADC function.
I like to use direct access approach as opposed to API utilities, as this gives me greater flexibility, and speed, plus I learn more in depth function of the processor.
I got the timer working, but now need the timer to trigger an ADC read and interrupt to know when it's completed the conversion.
Plus my next project is to use the timer at 4kHz then read the ADC audio time to make a spectrum analyzer.
I appreciate any help I receive
Regards
Roman
Code Composer Studio
Version: 5.4.0.00091
// ***************************************************************************
// PF1 = RED led
// PF2 = BLUE led
// PF3 = GREEN led
// PF0 = SW2
// PF4 = SW1
//
// PE 0 ~ 5 available
// ****************************************************************************
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
extern void Timer0IntHandler(void);
void delay_sec(void);
void ADC_Int_Handler(void);
void Flash(void);
volatile uint32_t ui32Loop;
volatile uint32_t ui32Loop2;
volatile uint32_t nope;
volatile uint32_t ADC_cnt = 0;
volatile uint32_t ADC_flash = 511;
#define SYSDIV 2
#define LSB 0
#define timer_int 0x00080000
#define timer0_cnt_dwn 0x000F0000 // TIMER COUNT VALUE
#define red 0x0002
#define blue 0x0004
#define green 0x0008
#define SYSCTL_PERIPH_ADC0 0xf0003800 // ADC 0
#define SYSCTL_RCGCBASE 0x400fe600
//*****************************************************************************
//
// Blink the on-board LED.
//
//*****************************************************************************
int
main(void)
{
// Memory Map p88
// System Control Registers p228
// Flash Register Map p535
// GPIO Register Map p654
SYSCTL_RCC2_R |= SYSCTL_RCC2_USERCC2;
SYSCTL_RCC2_R |= SYSCTL_RCC2_BYPASS2;
SYSCTL_RCC_R &= ~SYSCTL_RCC_XTAL_M; // clear XTAL field
SYSCTL_RCC_R += SYSCTL_RCC_XTAL_16MHZ; // configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~SYSCTL_RCC2_OSCSRC2_M; // clear oscillator source field
SYSCTL_RCC2_R += SYSCTL_RCC2_OSCSRC2_MO; // configure for main oscillator source
SYSCTL_RCC2_R &= ~SYSCTL_RCC2_PWRDN2;
SYSCTL_RCC2_R |= SYSCTL_RCC2_DIV400;
SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2_M; // clear system clock divider field
SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2LSB; // clear bit SYSDIV2LSB
SYSCTL_RCC2_R += (SYSDIV<<23)|(LSB<<22); // divide by (2*SYSDIV+1+LSB)
while((SYSCTL_RIS_R&SYSCTL_RIS_PLLLRIS)==0){};
SYSCTL_RCC2_R &= ~SYSCTL_RCC2_BYPASS2;
SYSCTL_RCGCGPIO_R = SYSCTL_RCGCGPIO_R4 + SYSCTL_RCGCGPIO_R5; // enable GPIO E & F
SYSCTL_RCGCTIMER_R = SYSCTL_RCGCTIMER_R0 + SYSCTL_RCGCTIMER_R1; // enable clock for timer 0, p334
// Do a dummy read to insert a few cycles after enabling the peripheral.
ui32Loop = SYSCTL_RCGC2_R;
// Enable the GPIO pin for the LED (PF3). Set the direction as output, and
// enable the GPIO pin for digital function.
GPIO_PORTF_DIR_R = 0x0E;
GPIO_PORTF_DEN_R = 0x0E;
ui32Loop = SYSCTL_RCGC2_R;
GPIO_PORTF_DATA_R &= ~(0x0E);
delay_sec();
// *************************************************************************
// timer 698
// *************************************************************************
TIMER0_CFG_R = TIMER_CFG_32_BIT_TIMER; // 00000000 p721
TIMER0_TAILR_R = timer0_cnt_dwn; // load timer value 750
TIMER0_TAMR_R |= TIMER_TAMR_TAMR_PERIOD + TIMER_TAMR_TAMIE; // 0x2 723
TIMER0_IMR_R = TIMER_IMR_TATOIM; // set interupt 739
TIMER0_CTL_R |= TIMER_CTL_TAEN + TIMER_CTL_TAOTE; // enable the timer and start counting 731
// *************************************************************************
// ADC port E page 812 configuration 811
// *************************************************************************
SYSCTL_RCGCADC_R |= SYSCTL_RCGCADC_R0 | SYSCTL_RCGCADC_R1; // OK ADC Module 0 Run Mode Clock p348
ADC0_PC_R |= SYSCTL_RCGC0_ADC0SPD_500K;
GPIO_PORTE_AFSEL_R |= GPIO_Port3; // AIN0 PE3 analog page 666
GPIO_PORTE_DEN_R &= ~GPIO_Port3; // make as input p677 (GPIODEN)
ADC0_EMUX_R |= ADC_EMUX_EM0_TIMER; // use timer for ADC sample
ADC0_ACTSS_R &= ~ADC_ACTSS_ASEN0; // disable Sequencer
ADC0_SSMUX0_R |= ADC_SSMUX0_MUX0_S;
ADC0_SSCTL0_R |= ADC_SSCTL0_END0 + ADC_SSCTL0_IE0;
ADC0_ACTSS_R |= ADC_ACTSS_ASEN0 + ADC_ACTSS_ASEN1 + ADC_ACTSS_ASEN2 + ADC_ACTSS_ASEN3;
ADC0_IM_R |= ADC_IM_MASK0; //ADC Interrupt Mask
// *************************************************************************
// interrupt
// *************************************************************************
NVIC_EN0_R = timer_int;
NVIC_ST_CTRL_R |= NVIC_ST_CTRL_INTEN;
ADC0_IM_R = ADC_IM_MASK0; // SS0 Interrupt Mask
ADC0_ACTSS_R = ADC_ACTSS_ASEN0; // enable Sequencer
while(1) // loop forever
{
// delay_sec();
// GPIO_PORTF_DATA_R |= red;
GPIO_PORTF_DATA_R &= ~(red); // reset off LEDS
GPIO_PORTF_DATA_R &= ~(green);
GPIO_PORTF_DATA_R &= ~(blue);
delay_sec();
}
}
void delay_sec(void) // used to see the LEDs flash for testing
{
for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
{
}
}
void Timer0IntHandler(void)
{
GPIO_PORTF_DATA_R |= green; // proves I've been here this works
TIMER0_ICR_R = TIMER_ICR_TATOCINT; // clear interrupt
}
void ADC_Int_Handler(void)
{
ADC0_PSSI_R |= ADC_PSSI_SS0;
GPIO_PORTF_DATA_R |= red; // Flash red doesn't flash INT not occurring
if (ADC0_SSFIFO0_R > ADC_flash) // check if the right size
{
Flash(); //trigger the flash
}
ADC0_ISC_R |= ADC_ISC_IN0 +ADC_ISC_IN1 + ADC_ISC_IN2 + ADC_ISC_IN3; // clear int flag
}
void Flash(void) // right size detected
{
GPIO_PORTF_DATA_R |= blue; // Flash Blue led Proves I've been here
// trigger the flash a variable resistor to vary the delay time after the trigger
// first have to get ADC 0 working
for(ui32Loop2 = 0; ui32Loop2 < 200; ui32Loop2++)
{
}
GPIO_PORTF_DATA_R &= ~blue;
}