AD电阻转换---那些年我们一起玩mini2440(arm9)裸机

ADC驱动程序设计

ADC:模/数转换器。

一种将模拟信号转换成数字信号的装置;

DAC:/模转换器。

一种将数字信号转换成模拟信号的装置。

模拟信号转换为数值信号的步骤:

1.     取值;

2.     量化;

3.     编码;

S3C2440ADC

S3C2440芯片内部共8A/D转换通道AIN0~AIN7,但是转换器只有一个。

转换精度为10位,故转换后的值最小时会接近0,最大时会接近1024.

 

 

最大的转换率在2.5MHZ转换时钟下能达到500KSPS(每秒采样5000千次)

 

在常见的设计中,如mini2440开发板一般AIN4AIN5AIN6AIN7被用作了四线电阻触摸的YMYPXMXP通道;剩余的AIN0~3被引出,其中AIN0直接和一个可调电阻W1连接。

 

师:AIN4AIN5AIN6AIN7给触摸屏用的;

AIN0用于可调电阻

(这样电压就可以作为一路模拟信号进行转换)

 

 

 

 ADC驱动流程:1.初始化à2.启动à3.转换结束à4.读取转换值

 

 

 

一.ADC初始化

 

A.选择转换通道-     B.设置转换频率

 

 

 怎么判断开始转换了?用一个whlie循环,查询ENABLE_START是否变成0

 

 怎么判断转换完成了?不断查询ECFLG是否为1

 

 读取转换值

 

 pasting

  1. #define GLOBAL_CLK      1  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include "def.h"  
  5. #include "option.h"  
  6. #include "2440addr.h"  
  7. #include "2440lib.h"  
  8. #include "2440slib.h"  
  9. #include "mmu.h"  
  10. #include "profile.h"  
  11. #include "memtest.h"  
  12.   
  13.   
  14. #define ADC_FREQ 2500000  
  15. //#define ADC_FREQ   1250000  
  16.   
  17.   
  18. volatile U32 preScaler;  
  19.   
  20. void adc_init(void);  
  21. int ReadAdc(int channel);  
  22. static void cal_cpu_bus_clk(void);  
  23. void Set_Clk(void);  
  24. void beep_init(void);  
  25. void beep_run(void);  
  26. /*************************************************  
  27. Function name: delay  
  28. Parameter    : times  
  29. Description  : 延时函数  
  30. Return       : void  
  31. Argument     : void  
  32. Autor & date : Daniel  
  33. **************************************************/  
  34. void delay(int times)  
  35. {  
  36.     int i,j;  
  37.     for(i=0;i<times;i++)  
  38.        for(j=0;j<400;j++);  
  39. }  
  40. /*************************************************  
  41. Function name: Main  
  42. Parameter    : void  
  43. Description  : 主功能函数  
  44. Return       : void  
  45. Argument     : void  
  46. Autor & date : Daniel  
  47. **************************************************/  
  48. void Main(void)  
  49. {     
  50.     int a0=0,tmp;  
  51.     int Scom=0;  
  52.     Set_Clk();  
  53.     Uart_Init(0,115200);  
  54.     Uart_Select(Scom);  
  55.         
  56.     adc_init();  
  57.        while(1)  
  58.     {  
  59.         a0=ReadAdc(0);  
  60.         Uart_Printf( "AIN0: %04d\n", a0);  
  61.         delay(1000) ;  
  62.     }  
  63.   
  64. }     
  65.   
  66. /*************************************************  
  67. Function name: adc_init()  
  68. Parameter    : int channel  
  69. Description  : adc初始化  
  70. Return       : void  
  71. Argument     : void  
  72. Autor & date : Daniel  
  73. **************************************************/   
  74. void adc_init(void)  
  75. {  
  76.     int channel=0; //AIN0,对应开发板上W1可调电阻  
  77.       
  78.     preScaler = ADC_FREQ;  
  79.     Uart_Printf("ADC conv,freq. = %dHz\n",preScaler);  
  80.     preScaler = 50000000/ADC_FREQ - 1; //PCLK=50M  我们要得到ADC_FREQ=2500000  
  81.       
  82.     Uart_Printf("PRSCVL=PCLK/ADC_FREQ - 1=%d\n",preScaler);  
  83.       
  84.     /*AD转换频率设置,最大频率为2.5MHz*/  
  85.     rADCCON = (1<<14)|(preScaler<<6)|(channel<<3);    //setup channel 1<<14使能预分频器 (preScaler<<6)预分频值  channel<<3模拟通道选择  
  86.     delay(1000);          
  87.   
  88. }  
  89.       
  90. /*************************************************  
  91. Function name: ReadAdc(int channel)  
  92. Parameter    : int channel  
  93. Description  : 获取AD 转换后的值  
  94. Return       : int  
  95. Argument     : void  
  96. Autor & date : Daniel  
  97. **************************************************/      
  98. int ReadAdc(int channel)  
  99. {  
  100.   
  101.     /*开启AD转换*/  
  102.     rADCCON |= 0x01; //start ADC  
  103.       
  104.       
  105.     while(rADCCON & 0x1);   //check if Enable_start is low  
  106.       
  107.     while(!(rADCCON & 0x8000)); //check if EC(End of Conversion) flag is high判断转换是否结束  
  108.           
  109.     return ( (int)rADCDAT0 & 0x3ff );//读取转换后的值  
  110. }   
  111. /*************************************************  
  112. Function name: Set_Clk()  
  113. Parameter    : void  
  114. Description  : 设置CPU的时钟频率  
  115. Return       : void  
  116. Argument     : void  
  117. Autor & date : Daniel  
  118. **************************************************/  
  119. void Set_Clk(void)  
  120. {  
  121.     int i;  
  122.     U8 key;  
  123.     U32 mpll_val = 0 ;  
  124.     i = 2 ;              //don't use 100M!  
  125.                          //boot_params.cpu_clk.val = 3;  
  126.     switch ( i ) {  
  127.     case 0: //200  
  128.         key = 12;  
  129.         mpll_val = (92<<12)|(4<<4)|(1);  
  130.         break;  
  131.     case 1: //300  
  132.         key = 13;  
  133.         mpll_val = (67<<12)|(1<<4)|(1);  
  134.         break;  
  135.     case 2: //400  
  136.         key = 14;  
  137.         mpll_val = (92<<12)|(1<<4)|(1);  
  138.         break;  
  139.     case 3: //440!!!  
  140.         key = 14;  
  141.         mpll_val = (102<<12)|(1<<4)|(1);  
  142.         break;  
  143.     default:  
  144.         key = 14;  
  145.         mpll_val = (92<<12)|(1<<4)|(1);  
  146.         break;  
  147.     }  
  148.       
  149.     //init FCLK=400M, so change MPLL first  
  150.     ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //set the register--rMPLLCON  
  151.     ChangeClockDivider(key, 12);    //the result of rCLKDIVN [0:1:0:1] 3-0 bit  
  152.     cal_cpu_bus_clk();    //HCLK=100M   PCLK=50M  
  153. }  
  154. /*************************************************  
  155. Function name: cal_cpu_bus_clk  
  156. Parameter    : void  
  157. Description  : 设置PCLK\HCLK\FCLK的频率  
  158. Return       : void  
  159. Argument     : void  
  160. Autor & date : Daniel  
  161. **************************************************/  
  162. static void cal_cpu_bus_clk(void)  
  163. {  
  164.     static U32 cpu_freq;  
  165.     static U32 UPLL;  
  166.       
  167.     U32 val;  
  168.     U8 m, p, s;  
  169.       
  170.     val = rMPLLCON;  
  171.     m = (val>>12)&0xff;  
  172.     p = (val>>4)&0x3f;  
  173.     s = val&3;  
  174.   
  175.     //(m+8)*FIN*2 不要超出32位数!  
  176.     FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;     //FCLK=400M  FIN=12000000  
  177.       
  178.     val = rCLKDIVN;  
  179.     m = (val>>1)&3;  
  180.     p = val&1;    
  181.     val = rCAMDIVN;  
  182.     s = val>>8;  
  183.       
  184.     switch (m) {  
  185.     case 0:  
  186.         HCLK = FCLK;  
  187.         break;  
  188.     case 1:  
  189.         HCLK = FCLK>>1;  
  190.         break;  
  191.     case 2:  
  192.         if(s&2)  
  193.             HCLK = FCLK>>3;  
  194.         else  
  195.             HCLK = FCLK>>2;  
  196.         break;  
  197.     case 3:  
  198.         if(s&1)  
  199.             HCLK = FCLK/6;  
  200.         else  
  201.             HCLK = FCLK/3;  
  202.         break;  
  203.     }  
  204.       
  205.     if(p)  
  206.         PCLK = HCLK>>1;  
  207.     else  
  208.         PCLK = HCLK;  
  209.       
  210.     if(s&0x10)  
  211.         cpu_freq = HCLK;  
  212.     else  
  213.         cpu_freq = FCLK;  
  214.           
  215.     val = rUPLLCON;  
  216.     m = (val>>12)&0xff;  
  217.     p = (val>>4)&0x3f;  
  218.     s = val&3;  
  219.     UPLL = ((m+8)*FIN)/((p+2)*(1<<s));  
  220.     UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;  
  221. }  

 

posted @ 2014-12-08 11:09  来杯绿茶  阅读(636)  评论(0编辑  收藏  举报