xiao小菜鸟 发表于 2016-12-1 07:55:11

坐等更新

田不辣 发表于 2016-12-1 08:30:21

今天早上再次打开还没有更新,有点失望啊。。

Loki 发表于 2016-12-1 09:05:16

顶顶更健康

独行者 发表于 2016-12-1 09:24:36

看看老师来了没?准备上课。

海浪淘沙 发表于 2016-12-1 13:33:01

再学习,理解透了往下学

haiyanglin280 发表于 2016-12-1 19:52:09

模块化 库 教程 会有吗?

我是天才 发表于 2016-12-1 22:06:10

我爱萝丽爱萝丽 发表于 2016-12-2 01:30:37

haiyanglin280 发表于 2016-12-1 19:52
模块化 库 教程 会有吗?

课程多了以后可以整理一个库

我爱萝丽爱萝丽 发表于 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口模拟功能寄存器

设置P1.7引脚对应的程序是: P1ASF=0x80;


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

知识点(49) sfr ADC_CONTR=0xBC声明 模数转换寄存器
.
这个寄存器里面参数较多,不过我们只需要用该用到的就行了,别的暂时不用理会。
寄存器的后三位是引脚选择,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即可保证转换完成。



xiao小菜鸟 发表于 2016-12-2 05:58:37

我爱萝丽爱萝丽 发表于 2016-12-2 04:12 static/image/common/back.gif
1.1 模数转换原理

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

楼主辛苦

my21602 发表于 2016-12-2 11:13:48

终于看明白AD转换怎么回事了!还是萝丽老师讲的明白!

815023524 发表于 2016-12-2 13:50:53

继续跟进

枫飞秋语 发表于 2016-12-2 20:51:15

知识点应该是 46开始

ldy7474 发表于 2016-12-2 21:58:39

我爱萝丽爱萝丽 发表于 2016-12-2 04:12
1.1 模数转换原理

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

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

ldy7474 发表于 2016-12-2 21:59:08

我爱萝丽爱萝丽 发表于 2016-12-2 04:12
1.1 模数转换原理

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

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

我爱萝丽爱萝丽 发表于 2016-12-3 03:34:19

枫飞秋语 发表于 2016-12-2 20:51
知识点应该是 46开始

46 在十二章

我爱萝丽爱萝丽 发表于 2016-12-3 03:35:08

ldy7474 发表于 2016-12-2 21:59
萝莉大神你好;感谢一直以来为我们传道授业解惑老师辛苦了
能着重讲讲滤波算法和量程转换吗?
比 ...
大于5v用电阻分压,滤波用平均值

我爱萝丽爱萝丽 发表于 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结果换算成电压?
#include<reg51.h>

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


sbit DA=P2^4;                        //数码管每个引脚
sbit DB=P3^2;
sbit DC=P3^6;
sbit DD=P2^0;
sbit DE=P2^1;
sbit DF=P2^3;
sbit DG=P3^5;
sbit DP=P3^7;

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


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

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

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

void Delay1ms()                //@12.000MHz
{
        unsigned char i, j;

        i = 12;
        j = 169;
        do
        {
                while (--j);
        } while (--i);
}

void delay_n_ms(unsigned int n) //延时n毫秒函数
{
        while(n)         
        {
                Delay1ms();
                n=n-1;//每循环一次n减小1
        }   
}

void Delay50us()                //@12.000MHz
{
        unsigned char i, j;

        i = 1;
        j = 146;
        do
        {
                while (--j);
        } while (--i);
}

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

        if(x==4){DA=0;DB=1;DC=1;DD=0;DE=0;DF=1;DG=1;DP=0;} //显示“4”
       
        if(x==5){DA=1;DB=0;DC=1;DD=1;DE=0;DF=1;DG=1;DP=0;} //显示“5”
       
        if(x==6){DA=1;DB=0;DC=1;DD=1;DE=1;DF=1;DG=1;DP=0;} //显示“6”
       
        if(x==7){DA=1;DB=1;DC=1;DD=0;DE=0;DF=0;DG=0;DP=0;} //显示“7”
       
        if(x==8){DA=1;DB=1;DC=1;DD=1;DE=1;DF=1;DG=1;DP=0;} //显示“8”
       
        if(x==9){DA=1;DB=1;DC=1;DD=1;DE=0;DF=1;DG=1;DP=0;} //显示“9”
       
}


main()
{
        P2M0=0x1B;                //需要高电平大电流的引脚 2.4、2.3、2.1、2.0,填入数值0001 1011
        P3M0=0xE4;                //需要高电平大电流的引脚 3.7、3.6、3.5、3.2,填入数值1110 0100
       
       
        while(1)
        {
                delay_n_ms(4);//系统周期4ms
               
                P1ASF=0x80;//设置P1.7引脚
                ADC_CONTR=0x88+7;//开始P1.7引脚转换
                Delay50us();   //等待AD转换完成
                adc=ADC_RES;//读取转换结果
               
                Data1=0;
                Data2=adc/100;          //百位数据
                Data3=adc%100/10; //十位数据
                Data4=adc%10;   //个位数据
               
                ///////////////////////////////////////////////////////
                //显示程序模块化,只需要改变Data1/2/3/4的值就可以控制显示内容
               
                display_time=display_time+1;
                if(display_time>3)
                {
                        display_time=0;//0、1、2、3 四个循环
                }
               
                if(display_time==0)//第0次显示第一个数码管
                {
                        B1=0;B2=1;B3=1;B4=1;       
                        display(Data1);                //显示第1位数据
                }
               
                if(display_time==1)//第1次显示第二个数码管
                {
                        B1=1;B2=0;B3=1;B4=1;       
                        display(Data2);                //显示第2位数据
                }
               
                if(display_time==2)//第2次显示第三个数码管
                {
                        B1=1;B2=1;B3=0;B4=1;       
                        display(Data3);                //显示第3位数据
                }
               
                if(display_time==3)//第3次显示第四个数码管
                {
                        B1=1;B2=1;B3=1;B4=0;       
                        display(Data4);                //显示第4位数据
                }
                       
               
        }
}

独行者 发表于 2016-12-3 09:15:55

终于看到AD了,老师真的很辛苦,谢谢!

YH98fwk5Ks 发表于 2016-12-3 09:18:59

顶贴是一种美德
页: 1 [2] 3 4 5 6
查看完整版本: 第十三课:扩展课!电压变成数字