模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

[单片机课堂] 第十三课:扩展课!电压变成数字

  [复制链接]
发表于 2016-12-1 07:55:11 | 显示全部楼层
坐等更新
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-1 08:30:21 | 显示全部楼层
今天早上再次打开还没有更新,有点失望啊。。
回复 支持 0 反对 1

使用道具 举报

发表于 2016-12-1 09:05:16 | 显示全部楼层
顶顶更健康
回复 支持 0 反对 1

使用道具 举报

发表于 2016-12-1 09:24:36 | 显示全部楼层
看看老师来了没?准备上课。
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-1 13:33:01 | 显示全部楼层
再学习,理解透了往下学
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-1 19:52:09 | 显示全部楼层
模块化 库 教程 会有吗?
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2016-12-2 01:30:37 | 显示全部楼层
haiyanglin280 发表于 2016-12-1 19:52
模块化 库 教程 会有吗?

课程多了以后可以整理一个库
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-12-2 04:12:20 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-12-2 04:18 编辑

1.1 模数转换原理

首先要知道的一点是:模数转换并不能直接告诉你电压是多少,只会告诉你一个分数。简单的模数转换,精度是255个等级,如果单片机电源电压是5V,相当于5V是满分255。如果你的引脚上电压是1V,你只能得51分。
当然,相反的,如果你得了51分,说明引脚上是1V。

AD转换的流程很简单,三步走:
1、设置相应的引脚为模拟输入功能 ;
2、启动一次转换;
3、等待转换完成,读取转换结果。

学习新的功能必然会学到新的寄存器。先说一个最简单的:

知识点(47) sfr ADC_RES=0xBD;  声明 转换结果寄存器
转换出来的分数保存在这个寄存器里,范围0~255。
假如写程序 a=ADC_RES; a就获得转换结果了。


如果你已经熟练掌握了之前学的引脚模式寄存器设置,那么设置引脚的模拟功能也是非常轻松的了:
STC单片机的P1口引脚有模拟功能,本次实验用的电位器接在了P1.7引脚上。因此需先设置P1.7引脚为模拟输入:

知识点(48) sfr P1ASF=0x9D 声明 P1口模拟功能寄存器
第十三课:扩展课!电压变成数字  作者:我爱萝丽爱萝丽 5831
设置P1.7引脚对应的程序是: P1ASF=0x80;


本节的难点在于最后这个寄存器,稍微复杂:

知识点(49) sfr ADC_CONTR=0xBC  声明 模数转换寄存器
第十三课:扩展课!电压变成数字  作者:我爱萝丽爱萝丽 8145 .
这个寄存器里面参数较多,不过我们只需要用该用到的就行了,别的暂时不用理会。
寄存器的后三位是引脚选择,000~111,0到7代表P1.0~P1.7引脚。
开始P1.7引脚AD转换,你可以直接设置为 1000 1111,也可以分开再相加 1000 1000+111
对应程序,可以写作 ADC_CONTR=0x8F; 也可以写作 ADC_CONTR=0x88+7;


知识点(50) AD转换例程
P1ASF=0x80;  //设置P1.7引脚
ADC_CONTR=0x88+7;  //开始P1.7引脚转换
Delay50us();   //等待AD转换完成
a=ADC_RES;  //读取转换结果
单片机时钟为12M时,一次AD转换最慢也是45us,所以等待50us即可保证转换完成。




回复 支持 0 反对 1

使用道具 举报

发表于 2016-12-2 05:58:37 | 显示全部楼层
我爱萝丽爱萝丽 发表于 2016-12-2 04:12 第十三课:扩展课!电压变成数字  作者:xiao小菜鸟 4491
1.1 模数转换原理

首先要知道的一点是:模数转换并不能直接告诉你电压是多少,只会告诉你一个分数。简单的 ...

楼主辛苦
回复 支持 0 反对 1

使用道具 举报

发表于 2016-12-2 11:13:48 | 显示全部楼层
终于看明白AD转换怎么回事了!还是萝丽老师讲的明白!
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-2 20:51:15 | 显示全部楼层
知识点应该是 46开始
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-2 21:58:39 | 显示全部楼层
我爱萝丽爱萝丽 发表于 2016-12-2 04:12
1.1 模数转换原理

首先要知道的一点是:模数转换并不能直接告诉你电压是多少,只会告诉你一个分数。简单的 ...

萝莉大神你好;感谢一直以来为我们传道授业解惑  老师辛苦了  
能着重讲讲  滤波算法和量程转换  吗?
比如我要测量超过5v的电压  要怎么去切换  
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-2 21:59:08 | 显示全部楼层
我爱萝丽爱萝丽 发表于 2016-12-2 04:12
1.1 模数转换原理

首先要知道的一点是:模数转换并不能直接告诉你电压是多少,只会告诉你一个分数。简单的 ...

萝莉大神你好;感谢一直以来为我们传道授业解惑  老师辛苦了  
能着重讲讲  滤波算法和量程转换  吗?
比如我要测量超过5v的电压  要怎么去切换  
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-12-3 03:34:19 | 显示全部楼层
枫飞秋语 发表于 2016-12-2 20:51
知识点应该是 46开始

46 在十二章

点评

收到,马上补上~!  详情 回复 发表于 2016-12-3 22:43
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-12-3 03:35:08 | 显示全部楼层
ldy7474 发表于 2016-12-2 21:59
萝莉大神你好;感谢一直以来为我们传道授业解惑  老师辛苦了  
能着重讲讲  滤波算法和量程转换  吗?
比 ...

大于5v用电阻分压,滤波用平均值
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-12-3 04:59:43 | 显示全部楼层
1.2 显示测量结果


上一课学了数码管的显示,加上这节课的AD转换,你就能测量出电位器上的电压啦。
不过每个数码管都只能独立的显示0~9,假如你有一个数据是123,你需要写个小程序把它拆开成百位、十位、个位才行。
用我们小学数学的知识来解答:
123/100=1余数23,百位显示1;23/10=2余数3,十位显示2,个位显示3。


单片机由于没有小数点,它的除法跟小学生的水平是差不多的,你可千万别嫌它笨哈哈:


知识点(51) 单片机的除法和余数
/:整除符号。单片机里面,29除以10结果不是2.9,真正的结果没有小数也没有四舍五入,是2;
%:求余数符号。29除10的余数自然是9。
求123的十位的例程:a=123%100/10; //先求100的余数是23,再除以10得2。




显示电位器ADC结果的程序,试着思考下怎么把AD结果换算成电压?
  1. #include<reg51.h>

  2. sfr P2M0=0x96;     //声明 P2引脚模式寄存器
  3. sfr P3M0=0xb2;     //声明 P3引脚模式寄存器
  4. sfr P1ASF=0x9D;    //声明 P1口模拟功能寄存器
  5. sfr ADC_RES=0xBD;  //声明 ADC转换结果寄存器
  6. sfr ADC_CONTR=0xBC;//声明 ADC控制寄存器


  7. sbit DA=P2^4;                        //数码管每个引脚
  8. sbit DB=P3^2;
  9. sbit DC=P3^6;
  10. sbit DD=P2^0;
  11. sbit DE=P2^1;
  12. sbit DF=P2^3;
  13. sbit DG=P3^5;
  14. sbit DP=P3^7;

  15. sbit B1=P2^5;                        //四个数码管的引脚定义
  16. sbit B2=P2^2;
  17. sbit B3=P3^3;
  18. sbit B4=P3^4;


  19. unsigned char display_time;        //定义变量用于显示次数

  20. unsigned char Data1;        //第一个数码管要显示的数据
  21. unsigned char Data2;        //第二个数码管要显示的数据
  22. unsigned char Data3;        //第三个数码管要显示的数据
  23. unsigned char Data4;        //第四个数码管要显示的数据

  24. unsigned char adc;          //保存AD转换结果

  25. void Delay1ms()                //@12.000MHz
  26. {
  27.         unsigned char i, j;

  28.         i = 12;
  29.         j = 169;
  30.         do
  31.         {
  32.                 while (--j);
  33.         } while (--i);
  34. }

  35. void delay_n_ms(unsigned int n) //延时n毫秒函数
  36. {
  37.         while(n)         
  38.         {
  39.                 Delay1ms();
  40.                 n=n-1;//每循环一次n减小1
  41.         }   
  42. }

  43. void Delay50us()                //@12.000MHz
  44. {
  45.         unsigned char i, j;

  46.         i = 1;
  47.         j = 146;
  48.         do
  49.         {
  50.                 while (--j);
  51.         } while (--i);
  52. }

  53. void display(unsigned char x)//控制数码管显示内容的函数
  54. {
  55.         //判断x的值来决定显示什么
  56.         if(x==0){DA=1;DB=1;DC=1;DD=1;DE=1;DF=1;DG=0;DP=0;} //显示“0”
  57.        
  58.         if(x==1){DA=0;DB=1;DC=1;DD=0;DE=0;DF=0;DG=0;DP=0;} //显示“1”
  59.        
  60.         if(x==2){DA=1;DB=1;DC=0;DD=1;DE=1;DF=0;DG=1;DP=0;} //显示“2”
  61.        
  62.         if(x==3){DA=1;DB=1;DC=1;DD=1;DE=0;DF=0;DG=1;DP=0;} //显示“3”

  63.         if(x==4){DA=0;DB=1;DC=1;DD=0;DE=0;DF=1;DG=1;DP=0;} //显示“4”
  64.        
  65.         if(x==5){DA=1;DB=0;DC=1;DD=1;DE=0;DF=1;DG=1;DP=0;} //显示“5”
  66.        
  67.         if(x==6){DA=1;DB=0;DC=1;DD=1;DE=1;DF=1;DG=1;DP=0;} //显示“6”
  68.        
  69.         if(x==7){DA=1;DB=1;DC=1;DD=0;DE=0;DF=0;DG=0;DP=0;} //显示“7”
  70.        
  71.         if(x==8){DA=1;DB=1;DC=1;DD=1;DE=1;DF=1;DG=1;DP=0;} //显示“8”
  72.        
  73.         if(x==9){DA=1;DB=1;DC=1;DD=1;DE=0;DF=1;DG=1;DP=0;} //显示“9”
  74.        
  75. }


  76. main()
  77. {
  78.         P2M0=0x1B;                //需要高电平大电流的引脚 2.4、2.3、2.1、2.0,填入数值0001 1011
  79.         P3M0=0xE4;                //需要高电平大电流的引脚 3.7、3.6、3.5、3.2,填入数值1110 0100
  80.        
  81.        
  82.         while(1)
  83.         {
  84.                 delay_n_ms(4);//系统周期4ms
  85.                
  86.                 P1ASF=0x80;  //设置P1.7引脚
  87.                 ADC_CONTR=0x88+7;  //开始P1.7引脚转换
  88.                 Delay50us();   //等待AD转换完成
  89.                 adc=ADC_RES;  //读取转换结果
  90.                
  91.                 Data1=0;
  92.                 Data2=adc/100;          //百位数据
  93.                 Data3=adc%100/10; //十位数据
  94.                 Data4=adc%10;     //个位数据
  95.                
  96.                 ///////////////////////////////////////////////////////
  97.                 //显示程序模块化,只需要改变Data1/2/3/4的值就可以控制显示内容
  98.                
  99.                 display_time=display_time+1;
  100.                 if(display_time>3)
  101.                 {
  102.                         display_time=0;  //0、1、2、3 四个循环
  103.                 }
  104.                
  105.                 if(display_time==0)//第0次显示第一个数码管
  106.                 {
  107.                         B1=0;B2=1;B3=1;B4=1;       
  108.                         display(Data1);                //显示第1位数据
  109.                 }
  110.                
  111.                 if(display_time==1)//第1次显示第二个数码管
  112.                 {
  113.                         B1=1;B2=0;B3=1;B4=1;       
  114.                         display(Data2);                //显示第2位数据
  115.                 }
  116.                
  117.                 if(display_time==2)//第2次显示第三个数码管
  118.                 {
  119.                         B1=1;B2=1;B3=0;B4=1;       
  120.                         display(Data3);                //显示第3位数据
  121.                 }
  122.                
  123.                 if(display_time==3)//第3次显示第四个数码管
  124.                 {
  125.                         B1=1;B2=1;B3=1;B4=0;       
  126.                         display(Data4);                //显示第4位数据
  127.                 }
  128.                        
  129.                
  130.         }
  131. }
复制代码


回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-3 09:15:55 | 显示全部楼层
终于看到AD了,老师真的很辛苦,谢谢!
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-3 09:18:59 | 显示全部楼层
顶贴是一种美德
回复 支持 0 反对 1

使用道具 举报

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

本版积分规则

QQ|关于模吧|APP下载|广告报价|小黑屋|手机版|企业会员|商城入驻|联系我们|模吧 ( 冀公网安备13080502000084号 )

© 2013-2020 Moz8.com 模吧,玩出精彩!