找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4225|回复: 0
收起左侧

湖南大学STC-B单片机学习板光照温度测量程序(AD转换)

[复制链接]
ID:427912 发表于 2018-11-16 21:07 | 显示全部楼层 |阅读模式
可以将光照值和温度值显示在数码管上(AD转换)

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. sfr P0M1 = 0x93;
  4. sfr P0M0 = 0x94;
  5. sfr P2M1 = 0x95;
  6. sfr P2M0 = 0x96;
  7. sfr CLK_DIV = 0x97;
  8. //sfr AUXR = 0x8E;

  9. sfr ADC_CONTR = 0xBC;                  //ADC控制寄存器
  10. sfr ADC_RES = 0xBD;                    //ADC高8位结果
  11. sfr ADC_LOW2 = 0xBE;                  //ADC低2位结果
  12. sfr P1ASF = 0x9D;                     //P1口模拟功能控制寄存器

  13. #define ADC_POWER 0x80                //ADC电源控制位
  14. #define ADC_FLAG 0x10                 //ADC完成标志
  15. #define ADC_START 0x08                //ADC起始控制位
  16. #define ADC_SPEEDLL 0x00              //540个时钟
  17. #define ADC_SPEEDL 0x20               //360个时钟
  18. #define ADC_SPEEDH 0x40               //180个时钟
  19. #define ADC_SPEEDHH 0x60              //90个时钟

  20. sbit LED_SEL = P2^3;
  21. sbit BEEP = P3^4;

  22. unsigned char code LedChar[] = {    //数码管显示字符转换表  0-F
  23.   0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
  24.         0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
  25. };

  26. unsigned char LedBuff[9] = {        //数码管显示缓冲区 + 独立LED缓冲区
  27.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  28. };

  29. int code TempData[]={
  30.         239,197,175,160,150,142,135,129,124,120,116,113,109,107,104,101,  //温度值对应表
  31.         99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76,
  32.         75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62,
  33.         61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52,
  34.         51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44,
  35.         43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37,
  36.         36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31,
  37.         30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,
  38.         24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19,
  39.         19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14,
  40.         13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7,
  41.         7, 7, 6, 6,5, 5, 54,4, 3, 3,3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1,
  42.         -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9,
  43.         -10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17,
  44.         -18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
  45.         30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361
  46. };

  47. unsigned char ch = 3;    //ADC通道号
  48. int temp = 0;
  49. unsigned int light = 0;
  50. unsigned char T0RH = 0;      //T0重载值的高字节
  51. unsigned char T0RL = 0;      //T0重载值的低字节
  52. bit beep_flag = 0;         //蜂鸣器运行控制位

  53. void InitADC();
  54. void Delay2ms();
  55. void ConfigTimer0(unsigned int ms);

  56. void main()
  57. {
  58.         P0M0 = 0xFF;
  59.         P0M1 = 0x00;
  60.         P2M0 = 0x08;
  61.         P2M1 = 0x00;
  62.        
  63.         LED_SEL = 0;
  64.        
  65.   InitADC();                //初始化ADC
  66.         IE = 0xA0;                //使能ADC中断
  67.                                   //开始AD转换
  68.         ConfigTimer0(1);       //配置T0定时1ms
  69.                                   
  70.         while(1)
  71.         {
  72.                 if (temp < 0)
  73.                 {
  74.                   LedBuff[0] = 0x40;
  75.                         LedBuff[1] = LedChar[-temp/10%10];
  76.                   LedBuff[2] = LedChar[-temp%10];
  77.                 }
  78.                 else
  79.                 {
  80.                   LedBuff[0] = LedChar[temp/100%10];
  81.                   LedBuff[1] = LedChar[temp/10%10];
  82.                   LedBuff[2] = LedChar[temp%10];
  83.                 }

  84.                
  85.                 LedBuff[5] = LedChar[light/100%10];
  86.                 LedBuff[6] = LedChar[light/10%10];
  87.                 LedBuff[7] = LedChar[light%10];
  88.                
  89.                 if (temp >= 28)
  90.                 {
  91.                   beep_flag = 1;
  92.                         LedBuff[8] = 0xFF;
  93.                 }
  94.                 else
  95.                 {
  96.                   LedBuff[8] = 0x01;
  97.                 }
  98.         }
  99. }

  100. /* ADC中断服务程序 */
  101. void adc_isr() interrupt 5 using 1
  102. {
  103.         static unsigned int cnt = 0;      //记录ADC中断次数
  104.         static unsigned long temp_sum = 0;   //温度AD值累加和
  105.         static unsigned long light_sum = 0;  //光照AD值累加和
  106.        
  107.         cnt++;            //中断次数+1
  108.   ADC_CONTR &= !ADC_FLAG;       //清除ADC中断标志
  109.        
  110.         if (ch == 3)
  111.         {
  112.           temp_sum += (ADC_RES*256+ADC_LOW2)/4;
  113.         }
  114.         if (ch == 4)
  115.         {
  116.           light_sum += ADC_RES*256+ADC_LOW2;
  117.         }
  118.        
  119.         if (cnt > 2000)
  120.         {
  121.           cnt = 0;
  122.                
  123.                 temp = TempData[(temp_sum+1000/2)/1000-1];
  124.                 light = (light_sum+1000/2)/1000;
  125.                 temp_sum = 0;
  126.                 light_sum = 0;
  127.         }
  128.        
  129.         ADC_RES = 0;               
  130.         ADC_LOW2 = 0;               //清除结果寄存器
  131.        
  132.         if (++ch == 5) ch=3;       //切换到下一个通道
  133.         ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
  134.         CLK_DIV = 0x20;
  135. }

  136. /* 初始化ADC */
  137. void InitADC()
  138. {
  139.   P1ASF = 0xFF;               //设置P1口为AD口
  140.         ADC_RES = 0;               
  141.         ADC_LOW2 = 0;               //清除结果寄存器
  142.         ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
  143.         CLK_DIV = 0x20;            //ADC_RES[1:0]存放高2位ADC结果,ADC_RESL[7:0]存放低8位ADC结果
  144.         Delay2ms();                         //ADC上电并延时
  145. }

  146. void Delay2ms()                //@11.0592MHz
  147. {
  148.         unsigned char i, j;

  149.         _nop_();
  150.         _nop_();
  151.         i = 22;
  152.         j = 128;
  153.         do
  154.         {
  155.                 while (--j);
  156.         } while (--i);
  157. }

  158. /* 配置并启动T0,ms为T0定时时间 */
  159. void ConfigTimer0(unsigned int ms)
  160. {
  161.   unsigned long tmp;            //临时变量
  162.        
  163.         tmp = 11059200 / 12;          //定时器计数频率
  164.         tmp = (tmp * ms) / 1000;      //计算所需的计数值
  165.         tmp = 65536 - tmp;            //计算定时器重载值
  166.         tmp = tmp + 13;               //补偿中断响应延时造成的误差
  167.         T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
  168.         T0RL = (unsigned char)tmp;
  169.         TMOD &= 0xF0;                 //清零T0的控制位
  170.         TMOD |= 0x01;                 //配置T0为模式1
  171.         TH0 = T0RH;                   //加载T0重载值
  172.         TL0 = T0RL;
  173.         ET0 = 1;                      //使能T0中断
  174.         TR0 = 1;                      //启动T0
  175. }

  176. /* LED动态扫描函数,需在定时中断中调用 */
  177. void LedScan()
  178. {
  179.   static unsigned char i = 0;       //动态扫描索引
  180.        
  181.         P0 = 0x00;                        //关闭所有段选位,显示消隐
  182.         P2 = (P2 & 0xF0) | i;             //位选索引值赋值到P2口低3位
  183.         P0 = LedBuff[i];                  //缓冲区中索引位置的数据送到P0口
  184.         if (i < sizeof(LedBuff)-1)        //索引递增循环,遍历整个缓冲区
  185.                 i++;
  186.         else
  187.                 i = 0;
  188. }

  189. /* T0中断服务函数,完成数码管扫描 */
  190. void InterruptTimer0() interrupt 1
  191. {
  192.         static unsigned int cnt = 0;
  193.   TH0 = T0RH;             //重新加载重载值
  194.         TL0 = T0RL;            
  195.         LedScan();             //LED扫描显示
  196.        
  197.         if (beep_flag)
  198.         {
  199.           BEEP = ~BEEP;          //反转蜂鸣器控制电平
  200.                 cnt++;
  201.                 if (cnt > 5000) {     //中断5000次后,即定时5ms
  202.                         cnt = 0;
  203.             beep_flag = 0;
  204.                 }
  205.         }
  206. }
复制代码

所有资料51hei提供下载:
lesson5.zip (39.54 KB, 下载次数: 11)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表