这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » Ai8051U的ADC处理程序示例3

共1条 1/1 1 跳转至

Ai8051U的ADC处理程序示例3

菜鸟
2025-11-25 19:23:30     打赏

在前面中断例程的基础上,为了验证内部1.19V的ADC测量,在启动ADC采集、转换之前设定通道为第15通道,追加一行代码:

ADC_CONTR = (ADC_CONTR & 0xf0) | 15; //设置ADC转换通道为第15通道,1.19V

整体代码如下:


view plaincopy to clipboardprint?
  1. //测试工作频率为 11.0592MHz  

  2. // 测试使用Timer2作为串口1的波特率发生器  

  3. // 串口1:P3.6(RXD),P3.7(TXD)  

  4. #include "Ai8051U.H"   

  5. #include "intrins.h"  

  6. #include "stdio.h"  

  7. typedef unsigned char   u8;     //  8 bits   

  8. typedef unsigned int    u16;    // 16 bits   

  9. typedef unsigned long   u32;    // 32 bits   

  10. #define FOSC 11059200UL //定义为无符号长整型,避免计算溢出  

  11. #define BRT (65536 - (FOSC / 115200+2) / 4)   //加 2 操作是为了让 Keil 编译器,自动实现四舍五入运算  

  12. bit busy1;  

  13. char wptr1;  

  14. char rptr1;  

  15. char buffer1[64];  

  16. // 初始化定时器2  

  17. void Timer2Init(void) {  

  18.     T2L = BRT;  

  19.     T2H = BRT >> 8;  

  20.     S1BRT = 1;  // S1BRT:串口 1 波特率发生器选择位, 0:选择定时器 1 作为波特率发生器, 1:选择定时器 2 作为波特率发生器(默认值)  

  21.     T2x12 = 1;  

  22.     T2R = 1;      

  23. }  

  24. // 串口1  

  25. //---------------------------------------------------------------  

  26. // 串口1的中断处理  

  27. void Uart1Isr() interrupt 4 {  

  28.     if (TI) {  

  29.         TI = 0;  

  30.         busy1 = 0;  

  31.     }  

  32.     if (RI) {  

  33.         RI = 0;  

  34.         buffer1[wptr1++] = SBUF;  

  35.         wptr1 &= 0x0f;  

  36.     }  

  37. }  

  38. // 初始化串口1  

  39. void Uart1Init() {  

  40.     SCON = 0x50;  //  

  41.     wptr1 = 0x00;  

  42.     rptr1 = 0x00;  

  43.     busy1 = 0;  

  44.       

  45.     P_SW1 |= 0x40;   // 选择P3.6,P3.7,因为擎天柱开发板上不提供P3.0,P3.1引脚  

  46. }  

  47. // 向串口1输出一个字符  

  48. void Uart1Send(char dat) {  

  49.     while (busy1);  

  50.     busy1 = 1;  

  51.     SBUF = dat;  

  52. }  

  53. // 向串口1输出一个字符串  

  54. void Uart1SendStr(char *p) {  

  55.     while (*p) {  

  56.         Uart1Send(*p++);  

  57.     }  

  58. }  

  59. // 初始化ADC  

  60. void AdcInit(void) {  

  61.     // 设置ADC, P1.0:高阻输入  

  62.     P1M0 = 0x00; //设置 P1.0 为 ADC 口  

  63.     P1M1 = 0x01;  

  64.     ADCTIM = 0x3f; //设置 通道选择时间、保持时间、采样时间  

  65.     ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16/16; 转换结果右对齐  

  66.     ADC_POWER = 1; //使能 ADC 模块  

  67.       

  68. }  

  69. // 延时  

  70. void delay_ms(u16 ms) {  

  71.     u16 i;  

  72.     do {  

  73.         i = FOSC/3000;  

  74.         while(--i);  

  75.     } while(--ms);  

  76. }  

  77. //========================================================================  

  78. // 函数: u16 Get_ADC12bitResult(u8 channel))//channel = 0~15  

  79. // 描述: 查询法读一次ADC结果.  

  80. // 参数: channel: 选择要转换的ADC, 0~15.  

  81. // 返回: 12位ADC结果.  

  82. // 版本: V1.0, 2016-4-28  

  83. //========================================================================  

  84. u16Get_ADC12bitResult(u8 channel) {  

  85.       

  86. ADC_RES = 0;  

  87. ADC_RESL = 0;  

  88.     ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道  

  89.       

  90.     ADC_START = 1;   // 启动ADC转换  

  91.       

  92.     _nop_();  

  93.     _nop_();  

  94.     _nop_();  

  95.     while (!ADC_FLAG); //查询 ADC 完成标志  

  96.     ADC_FLAG = 0;  

  97.       

  98.     return (((u16)ADC_RES << 8) | ADC_RESL);  

  99. }  

  100. /*********************************** 

  101. 查询方式做一次ADC, chn为通道号, chn=0~7对应P1.0~P1.7, chn=8~14对应P0.0~P0.6, chn=15对应BandGap电压. 

  102. ***********************************/  

  103. u16 ADC_convert(u8 chn) {  

  104. u16val;  

  105. Get_ADC12bitResult(chn);//参数i=0~15,查询方式做一次ADC, 切换通道后第一次转换结果丢弃. 避免采样电容的残存电压影响.  

  106.     Get_ADC12bitResult(chn);//参数i=0~15,查询方式做一次ADC, 切换通道后第二次转换结果丢弃. 避免采样电容的残存电压影响.  

  107.     val = Get_ADC12bitResult(chn);  

  108.     return val;  

  109. }  

  110. u16 adc_val = 0;  

  111. bit adc_ok_flag = 0;  

  112. void ADC_Isr() interrupt 5  {  

  113.     ADC_FLAG = 0; //清中断标志  

  114.     adc_val = ((u16)ADC_RES << 8) | ADC_RESL;  

  115.       

  116.     adc_ok_flag = 1;     // ADC完成标志  

  117.       

  118.     ADC_START = 1; //继续 AD 转换  

  119. }  

  120. void main() {  

  121.     unsigned int val = 0;               // ADC转换值  

  122.     float v1=0.0;                // 电压值  

  123.     unsigned char str[32]={0};  

  124.       

  125.     EAXFR = 1; //允许访问扩展的特殊寄存器,XFR  

  126.     //(32 位模式请使用这句,注释下一句)  

  127.     // P_SW2 |= 0x80; //允许访问扩展的特殊寄存器,XFR  

  128.     //(8 位模式请使用这句,注释上一句)  

  129.     WTST = 0; //设置取程序代码等待时间,  

  130.     //赋值为 0 表示不等待,程序以最快速度运行  

  131.     CKCON = 0; //设置访问片内的 xdata 速度,  

  132.       

  133.     //赋值为 0 表示用最快速度访问,不增加额外的等待时间  

  134.     P0M0 = 0x00;    P0M1 = 0x00;  

  135.     P1M0 = 0x00;    P1M1 = 0x00;  

  136.     P2M0 = 0x00;    P2M1 = 0x00;  

  137.     P3M0 = 0x00;    P3M1 = 0x00;  

  138.     P4M0 = 0x00;    P4M1 = 0x00;  

  139.     P5M0 = 0x00;    P5M1 = 0x00;  

  140.       

  141.     Timer2Init();  

  142.       

  143.     Uart1Init();  

  144.    

  145.     AdcInit();  

  146.       

  147.     delay_ms(10);  

  148.       

  149.     ES = 1;  

  150.     EADC = 1; //使能 ADC 中断  

  151.       

  152.     EA = 1;  

  153.       

  154.     Uart1SendStr("Start Test !\r\n");  

  155.       

  156.     ADC_CONTR = (ADC_CONTR & 0xf0) | 15; //设置ADC转换通道为第15通道,1.19V  

  157.       

  158.     ADC_START = 1; //继续 AD 转换  

  159.       

  160.     while (1) {  

  161.         if (adc_ok_flag) {  

  162.             val = adc_val;  

  163.             sprintf(str, "ADC Val = %d ", val);  

  164.             Uart1SendStr(str);  

  165.               

  166.             v1 = (float)5 * val / 4096;  

  167.             sprintf(str, ", Input Vol = %f \r\n", v1);  

  168.             Uart1SendStr(str);  

  169.             delay_ms(500);          

  170.         }  

  171.     }  

  172. }  



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]