📄 adc.c
字号:
//====================================================================
// File Name : Adc.c
// Function : S3C2410 ADC Test
// Program : Kang, Weon Tark
// Date : May 22, 2002
// Version : 0.0
// History
// 0.0 : Programming start (March 29,2002) -> KWT
// ADC Test -> May 15, 2002 SOP
//====================================================================
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"
#include "adc.h"
#define REQCNT 100 //May 08, 2002 SOP
#define ADC_FREQ 2500000
//#define ADC_FREQ 1250000
//#define LOOP 1
#define LOOP 10000
void __irq DMA0_Done(void); //Declare Prototype function
int ReadAdc(int ch); //Return type is int, Declare Prototype function
volatile U32 preScaler;
//==================================================================================
void Test_Adc(void)
{
int a0=0; //Initialize variables
U32 rADCCON_save = rADCCON;
printf( "ADC INPUT Test, press ESC key to exit !\n" ) ;
preScaler = ADC_FREQ;
printf("ADC conv. freq. = %dHz\n",preScaler);
preScaler = GetMasterClock()/ADC_FREQ -1; //PCLK:50.7MHz
printf("PCLK/ADC_FREQ - 1 = %d\n",preScaler);
while( getkey() != ESC_KEY )
{
a0=ReadAdc(0);
printf( "AIN0: %04d\n", a0 );
Delay( 80 ) ;
}
//rADCCON=(0<<14)|(19<<6)|(7<<3)|(1<<2); //stand by mode to reduce power consumption
rADCCON = rADCCON_save;
printf("\nrADCCON = 0x%x\n", rADCCON);
}
//==================================================================================
int ReadAdc(int ch)
{
int i;
static int prevCh=-1;
rADCCON = (1<<14)|(preScaler<<6)|(ch<<3); //setup channel
if(prevCh!=ch)
{
rADCCON = (1<<14)|(preScaler<<6)|(ch<<3); //setup channel
for(i=0;i<LOOP;i++); //delay to set up the next channel
prevCh=ch;
}
rADCCON|=0x1; //start ADC
while(rADCCON & 0x1); //check if Enable_start is low
while(!(rADCCON & 0x8000)); //check if EC(End of Conversion) flag is high
return ( (int)rADCDAT0 & 0x3ff );
}
//==================================================================================
volatile char end_test;
void Test_DMA_Adc(void)
{
unsigned int *dst,*tmp,i;
//int key;
U32 rADCCON_save = rADCCON;
U32 rTCFG0_save = rTCFG0;
U32 rTCFG1_save = rTCFG1;
U32 rTCON_save = rTCON;
end_test=0;
pISR_DMA0=(unsigned)DMA0_Done; //Regist interrupt service routine
rINTMSK &= ~(BIT_DMA0); //Clear int mask bit.
printf("Test of the 'Start by read' in ADC block.\n");
printf("Change the voltage of AIN0..(Sampling 100)\n");
dst = (unsigned int *)0x31000000; //Non-cacheable Area
tmp = dst;
for(i=0;i<REQCNT;i++)
*tmp++=i;
/***ADC init***/
preScaler = GetMasterClock()/ADC_FREQ -1;
rADCCON=(1<<14)|(preScaler<<6)|(0<<3)|0x2; //normal,ADCPRS,AIN0,enable start by read
/***DMA0 init***/
rDISRC0=0x5800000c; // rADCDAT0
rDISRCC0=(1<<1)|(1<<0); // APB,Fixed
rDIDST0=(int)dst; // dst
rDIDSTC0=(0<<1)|(0<<0); // AHB,++
rDCON0=(1U<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(2<<20)|REQCNT;
//handshake, sync PCLK, TC int, single tx, single service, Timer, Timer(H/W) request,
//auto-reload off, word, REQCNT
rDMASKTRIG0=(0<<2)|(1<<1)+0; //no-stop, DMA0 channel on, no-SW trigger
/*
for(i=0;i<5;i++)
printf("%d:0x%x\n",i, *(int *)(0x4b000000+i*4) );
*/
/***Timer0 init***/
rTCON &= ~0x1f;
rTCFG0 &= ~0xff;
rTCFG1 &= ~((0xf<<20)|(0xf));
rTCFG0 |= 255; //prescaler0=255
// rTCFG0=0; //prescaler0=0
rTCFG1 |= (1<<20) | 3; //Timer0 DMA, div=16
// rTCNTB0=4900; //(1/(50MHz/255/16))*4900=(1/(12254.9) * 4900)=0.0000816 * 4900 = 0.401 sec
rTCNTB0=1226; //0.0000816 * 1226 = 0.1 sec
// rTCNTB0=2452; //0.0000816 * 2452 = 0.2 sec
// rTCNTB0=1716; //0.0000816 * 1716 = 0.14 sec
// rTCNTB0=10; //(1/(50MHz/1/16))*10=(1/(3125000)*10)=0.0000003*10 = 0.000003 sec
// rTCNTB0=100; //0.0000003*100 = 0.00003 sec
// rTCNTB0=2000; //(1/(50MHz/1/16))*2000=(1/(3125000)*2000)=0.0000003*2000 = 0.0006 sec
rTCON &= ~0x1f;
rTCON |= 0xa; //auto reload, manual update
rTCON &= ~0x1f;
rTCON |= 0x9; //Start Timer0
i = rADCDAT0; //Read out dummy data and start first ADC operation
while(!end_test);
rINTMSK |= BIT_DMA0;
rTCON = rTCON_save;
rTCFG1 = rTCFG1_save;
rTCFG0 = rTCFG0_save;
rADCCON = rADCCON_save;
tmp=dst;
for(i=0;i<REQCNT;i++)
{
*tmp = (*tmp) & 0x3ff;
tmp++;
}
for(i=0;i<REQCNT;i++)
printf("%04d\n",*dst++); //May 08, 2002 SOP
// printf("%02d=%04d\n",i,*dst++);
// printf("%02d=0x%x\n",i,*dst++);
//printf("0x%08x,0x%08x,0x%08x\n", rTCON, rTCFG0, rTCFG1);
puts("press any key to continue...\n");
getch();
}
//==================================================================================
void __irq DMA0_Done(void)
{
ClearPending(BIT_DMA0);
//rDMASKTRIG0 = 4;
rTCON &= ~0x1f; //Stop Timer0
end_test=1; //set end flag
}
static char title[] = "ADC实验";
static char tip[] = "实验ADC模数转换,按ESC键返回";
//Test_Adc_Item 在 prog_entry.c 里被引用
TEST_PROGRAM_ITEM Test_Adc_Item = {
(TEST_PROGRAM)Test_Adc, //入口地址
title, //显示名称
tip, //帮助或提示信息,可为NULL
1}; //使用printf,puts,putch等函数时在LCD上也显示输出字符(串)
static char title1[] = "DMA方式的ADC实验";
static char tip1[] = "通过DMA方式读取ADC转换的数据,按ESC键返回";
//Test_Adc_Item 在 prog_entry.c 里被引用
TEST_PROGRAM_ITEM Test_DMA_Adc_Item = {
(TEST_PROGRAM)Test_DMA_Adc, //入口地址
title1, //显示名称
tip1, //帮助或提示信息,可为NULL
1}; //使用printf,puts,putch等函数时在LCD上也显示输出字符(串)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -