Hi guys,
I am trying to detect voltage from the ADC and write it to an array of u16-s where
every record should be done in 100 microseconds (100 us between every sample).
void TIM2_IRQHandler(void)
{ // All the time ...
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
// If reached 100 us
// Clear interrupt flag
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if(TrendIndex < TREND_BUFFER_SIZE)
{
Trend[TrendIndex++] = GetADC();
TrendReady = 0x00;
}else{
TrendIndex = 0x00;
TrendReady = 0xff;
}
}
}
My timer init is:
void InitTimer()
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 1 MHz down to 1 KHz
TIM_TimeBaseStructure.TIM_Prescaler = 42 - 1; // 24 MHz Clock down to 1 MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
My ADC control is:
void InitADC(void)
{
ADC_InitTypeDef ADC_Init_structure; //Structure for ADC configuration
GPIO_InitTypeDef GPIO_InitStructre; //Structure for analog input pin
//Clock configuration
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);//The ADC3 is connected the APB2 peripheral bus thus we will use its clock source
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//Clock for the ADC port!!
//Analog pin configuration
GPIO_InitStructre.GPIO_Pin = GPIO_Pin_6;//The channel 4 is connected to PF6
GPIO_InitStructre.GPIO_Mode = GPIO_Mode_AN; //The PF6 pin is configured in analog mode
GPIO_InitStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //We don't need any pull up or pull down
GPIO_Init(GPIOF,&GPIO_InitStructre);//Affecting the port with the initialization structure configuration
//ADC structure configuration
ADC_DeInit();
ADC_Init_structure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
ADC_Init_structure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
ADC_Init_structure.ADC_ContinuousConvMode = ENABLE; //the conversion is continuous, the input data is converted more than once
ADC_Init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;// conversion is synchronous with TIM1 and CC1 (actually I'm not sure about this one :/)
ADC_Init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//no trigger for conversion
ADC_Init_structure.ADC_NbrOfConversion = 1;//I think this one is clear :p
ADC_Init_structure.ADC_ScanConvMode = DISABLE;//The scan is configured in one channel
ADC_Init(ADC3,&ADC_Init_structure);//Initialize ADC with the previous configuration
//Enable ADC conversion
ADC_Cmd(ADC3,ENABLE);
//Select the channel to be read from
ADC_RegularChannelConfig(ADC3,ADC_Channel_4,1,ADC_SampleTime_144Cycles);
return;
}
s32 GetADC(void)
{
ADC_SoftwareStartConv(ADC3);//Start the conversion
while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC));//Processing the conversion
return ADC_GetConversionValue(ADC3); //Return the converted data
}
After transmitting "Trend" to RS i get
595
3873
3874
3922
3871
3861
3873
3887
3866
3850
3871
3885
3882
3880
3850
3871
3877
3877
3875
3870
3863
3888
So i thing my timer interrupt is putting the values waaaay more slow than i thought ..
Is there any way for ADC to convert faster ?
Hi,
I am working on a project where I need to use the timer-1 interrupt of Olinuxino A13. I have successfully initialized the timer also enabled the timer-1 interrupt.
Can someone help me with writing the Interrupt Service Routine (ISR) for the timer-1 interrupt.
This is my C code so far,
/////////////////////////////////////////////////////////////
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
#define GPIO_BASE 0x01c20800
#define PWM_BASE 0x01c20C00
#define PortGConf1Offset 0xDC
#define PortGDataOffset 0xE8
#define PortBConf0Offset 0x24
#define PWMCtrlOffset 0x200
#define PWMPeriodOffset 0x204
#define TimerIRQEnOffset 0x00
#define TimerStatusOffset 0x04
#define Timer0ControlOffset 0x10
#define Timer0IntervalOffset 0x14
#define Timer0CurrentOffset 0x18
#define Timer1ControlOffset 0x20
#define Timer1IntervalOffset 0x24
#define Timer1CurrentOffset 0x28
unsigned int *portGConfig;
unsigned int *portGData;
unsigned int *portBConfig;
unsigned int *PWMCtrl;
unsigned int *PWMPeriod;
unsigned int *TimerIRQEn;
unsigned int *TimerStatus;
unsigned int *Timer0Control;
unsigned int *Timer0Interval;
unsigned int *Timer0Current;
unsigned int *Timer1Control;
unsigned int *Timer1Interval;
unsigned int *Timer1Current;
static unsigned int GPIO_MMAP = 0;
static unsigned int PWM_MMAP = 0;
static unsigned int TIMER_MMAP = 0;
int main(void)
{
/////////////////////////////////////////////////////////////
int fd;
unsigned int addr_start, addr_offset, pwm_offset;
unsigned int PageSize, PageMask;
void *pc;
fd = open("/dev/mem", O_RDWR);
if(fd < 0) { perror("Unable to open /dev/mem"); }
PageSize = sysconf(_SC_PAGESIZE);
PageMask = (~(PageSize-1));
addr_start = GPIO_BASE & PageMask;
addr_offset = GPIO_BASE & ~PageMask;
pwm_offset = PWM_BASE & ~PageMask;
pc = (void *)mmap(0, PageSize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr_start);
if(pc == MAP_FAILED) { perror("Unable to mmap file"); }
GPIO_MMAP = (unsigned int)pc;
GPIO_MMAP += addr_offset;
PWM_MMAP = (unsigned int)pc;
PWM_MMAP += pwm_offset;
TIMER_MMAP = PWM_MMAP;
close(fd);
//if(fd == -1) { perror("Unable to close file"); }
/////////////////////////////////////////////////////////////
portGConfig = (unsigned int *)(GPIO_MMAP + PortGConf1Offset);
portGData = (unsigned int *)(GPIO_MMAP + PortGDataOffset);
portBConfig = (unsigned int *)(GPIO_MMAP + PortBConf0Offset);
PWMCtrl = (unsigned int *)(PWM_MMAP + PWMCtrlOffset);
PWMPeriod = (unsigned int *)(PWM_MMAP + PWMPeriodOffset);
*portGConfig = 0x1110; //configure port G pin 9 to output
//*portGData = 0x0000; // *portGData&= ~(0x0200);
*portBConfig = 0x200; //Configure Port B pin 2 to PWM
*PWMCtrl = 0x00; //printf("PWM cleared\n");
*PWMCtrl |= 0x00000020; //printf("PWM High Level\n");
*PWMCtrl |= 0x00000002; //printf("PWM 24MHz/240 = 100kHz\n");
*PWMCtrl |= 0x00000040; //printf("PWM Gating = pass\n");
*PWMCtrl |= 0x00000010; //printf("PWM Enabled\n");
*PWMPeriod = 0x01F30064; //printf("PWM period 0x01F30064\n");
/////////////////////////////////////////////////////////////
TimerIRQEn = (unsigned int *)(TIMER_MMAP + TimerIRQEnOffset);
TimerStatus = (unsigned int *)(TIMER_MMAP + TimerStatusOffset);
Timer0Control = (unsigned int *)(TIMER_MMAP + Timer0ControlOffset);
Timer0Interval = (unsigned int *)(TIMER_MMAP + Timer0IntervalOffset);
Timer0Current = (unsigned int *)(TIMER_MMAP + Timer0CurrentOffset);
Timer1Control = (unsigned int *)(TIMER_MMAP + Timer1ControlOffset);
Timer1Interval = (unsigned int *)(TIMER_MMAP + Timer1IntervalOffset);
Timer1Current = (unsigned int *)(TIMER_MMAP + Timer1CurrentOffset);
*TimerIRQEn |= 0x02; //printf("*TimerIRQEn = 0x%x\n", *TimerIRQEn);
*Timer1Control = 0x04; //printf("*Timer1Control = 0x%x\n", *Timer1Control);
*TimerStatus = 0x02; //printf("*TimerStatus = 0x%x\n", *TimerStatus);
*Timer1Interval = 0x16E3600; //printf("*Timer1Interval = 0x%x\n", *Timer1Interval);
*Timer1Current = 0x16E3600; //printf("*Timer1Current = 0x%x\n", *Timer1Current);
*Timer1Control = 0x05; //printf("*Timer1Control = 0x%x\n", *Timer1Control);
for (;;)
{
while (*TimerStatus != 0x02);
*TimerStatus = 0x02;
if (*portGData == 0x6) {*portGData = 0x200;}
else {*portGData = 0x000;}
}
/////////////////////////////////////////////////////////////
}
In my code the timer-1 successfully works. Now I need to write a code to run when the timer-1 interrupt occurs.
I am new in interrupt code writing. I have once written an ISR for 8051. I am not sure how to write the code for Olinuxino A13 using the GCC compiler.
In other words, how do I link the timer-1 vector address, which is 0x005C, with the code I want to run.
say for example I want to Turn On and Off the on board LED (GPIO-2 Pin-9) when the timer-1 interrupt occurs.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
if (*portGData == 0x6) {*portGData = 0x200;}
else {*portGData = 0x000;}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Please help.
This is ST forum...
John