**

题目:

**

利用原有的电路 AD 及 LED 数码管显示等例子,进行整合。实现由 AD转换器采集温度(用可调电阻模拟),温度在数码管上显示。当温度超出一定范围,用 LED 指示灯进行闪烁报警。(后边附有源码,这里主要讲解一下进制转换问题要使用进制转换的原因是这里采用的是10位AD转换器,即转换结果为10位,且结果为16进制数,例如全一情况:0x000003FF,如果直接将这个结果拿来当4个8位的数码管的输入的话,会发现,显示的也是16进制。所以需要进行进制转换,详细进制转换过程本文中间部分有介绍。

下边附上原电路图与修改后的电路图:

**

题目分析:

**

**这题主要是读取AD转换结果,然后将结果,用十进制并在数码管上显示出来。根据转换结果数值大小确定那种指示灯的亮灭,由于多个AD转换器不能同时使用,这里数码管显示内容仅为通过AD0,并进行一系列转换得来的。AD1实际上并未用到
**于是改进电路:

**

进制转换分析 :

**

是这里采用的是10位AD转换器,即转换结果为10位,且结果为16进制数,例如全一情况:0x000003FF,需要先转换成10进制,在把十进制的每一位,送到16进制中去,(即4位2进制代表一位16进制数,这四位的范围就是0-F)我们要做的就是只让这四位只显示0-9的数,然后4位代表一位10进制数,送到数码管就可以了,这里是用的是4个8位的数码管。

举一个通俗易懂的例子:原AD转换结果为:0x000002A8,需要转换成10进制680,即让数码管显示0680,所以需要把0680分解开,主要分解680,为6和8和0 ,这里需要注意的是,6代表的是百位,8代表的是10位。所以,再将10进制数转换成4位显示一位10进制数的16进制,需要注意的是每一位的位置不一样。即转换成0x00000680。这时再送入数码管输入接口就可以了。)
代码如下(不是用的680,是采集的数据)

//只是部分代码,解说进制转换
//16进制每位数值数组
const uint32 a_[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
//10进制相对16进制每位的数值对照数组
const uint32 b_[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//16进制每位的权重,因为AD转换结果只有二进制的10位,所以16进制只考虑到第三位即可,即到256
const uint32 c_[] = {0,16,256,4096,65536};int i=0;
int j=0;
int k=0;
int l=0;AD0CR = (AD0CR&0x00FFFF00)|0x01|(1 << 24);  // 设置AD0.0,并进行第一次转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束AD0CR = AD0CR | (1 << 24);                  // 再次启运转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束       ADC_Data = AD0DR;                           // 读取ADC结果              ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值 共10位       ADC_Data = ADC_Data * 3300/1024;            // 数值转换,转换成温度数值,但是16位的//16进制转10进制ADC_Data2= ADC_Data;//ADC_Data为经过AD转换后的16进制数据ADC_Data3= ADC_Data;//ADC_Data2和ADC_Data3都是用作中间变量       //循环次数,其实第四次就直接跳出循环了,因为AD转换结果只有10位for(i=0;i<4;i++){j=i*4;ADC_Data3 = ADC_Data2 &(0x0000000F << j);//0x0000000F依次左移4位然后和ADC_Data2求与,结果为除了要分离的4位,其余位都为零。if(ADC_Data3 ==0)//判断是否分离完break;else{//这里有移的目的是将0x00000F00,0x0000F000,0x000000F0等格式都转换成0x0000000F形式ADC_Data3=ADC_Data3>>j; //得出16进制数组对应10进制数组的数组编号for(k=0;k<16;k++){if(ADC_Data3 == b_[k]){l=k;}                          }}          ADC_Data4= ADC_Data4 +b_[l]*c_[i] +b_[l];//得出的16进制对应的10进制数}      ADC_Data2 = 0x0;//10进制转换成用1位16进制数代表1个10进制数的16进制,例如:9->0x09for(i=0;i<4;i++){ j=i*4;if(ADC_Data4 !=0)//直到10进制的每一位都转换结束{ADC_Data5=ADC_Data4%10;ADC_Data4=ADC_Data4/10;//依次累加,例如第一步0x000+0x005;第二步0x005+0x020;最后0x025+0x100;等ADC_Data2= ADC_Data2 + (ADC_Data5 << j);}}

需要注意的是,本题目用的是ARM的P1口,且为P1.16-P1.31,所以要将上述转换得到的结果进行左移16位,即变为0x06800000。并对P1口进行输入高电平操作,代码如下:

/*对P1接口输出清零,若相应位没能清零,可能会出现累加现象,例如使用IO1CLR =  0x03FF0000;,由于用到的P1为高16位,就会出现累加现象*/IO1CLR =  0xFFFF0000;IO1SET = (ADC_Data2<<16) & 0xFFFF0000 ;

详细源代码:

#include  "config.h"
//#define VREF  3300/****************************************************************************
* 函数名称:DelayNS()
* 函数功能:长软件延时
* 入口参数:dly   延时参数,值越大,延时越久
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;for(; dly>0; dly--) for(i=0; i<5000; i++);
}/****************************************************************************
* 函数名称:UART0Init()
* 函数功能:初始化串口0。设置为8位数据位,1位停止位,无奇偶校验
* 入口参数:bps 通讯波特率
****************************************************************************/
void  UART0Init(uint32 bps)
{  uint16 Fdiv;PINSEL0 = (PINSEL0 & (~0x0F)) | 0x05;   // 不影响其它管脚连接,设置I/O连接到UART0IO0DIR = 0x0000003B;U0LCR = 0x83;                           // DLAB = 1,可设置波特率Fdiv = (Fpclk / 16) / bps;               // 设置波特率U0DLM = Fdiv / 256;                            U0DLL = Fdiv % 256;                        U0LCR = 0x03;
}//16进制每位数值数组
const uint32 a_[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
//10进制相对16进制每位的数值对照数组
const uint32 b_[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//16进制每位的权重,因为AD转换结果只有二进制的10位,所以16进制只考虑到第三位即可,即到256
const uint32 c_[] = {0,16,256,4096,65536};int i=0;
int j=0;
int k=0;
int l=0;
void display_yellow()
{IO0CLR = 0x38;DelayNS(30);IO0SET = 0x10;DelayNS(30);
}
void display_red()
{IO0CLR = 0x38;DelayNS(10);IO0SET = 0x20;DelayNS(10);}
void display_green()
{    IO0CLR = 0x38;//DelayNS(50);IO0SET = 0x08;//DelayNS(50);}
/****************************************************************************
* 函数名称:main()
* 函数功能:进行通道0、1电压ADC转换,并把结果转换成电压值,然后发送到串口。
* 说    明:在CONFIG.H文件中包含stdio.h。
****************************************************************************/
int  main(void)
{  uint32  ADC_Data;//进制转换时的中间变量uint32  ADC_Data2;uint32  ADC_Data3;uint32  ADC_Data4;uint32  ADC_Data5;UART0Init(9600);                            // 初始化UART0 PINSEL1 = 0x01400000;                              // 设置P0.27、P0.28连接到AIN0、AIN1IO1DIR = 0xFFFFFFFF;                       /* 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延) */AD0CR = (1 << 0)                     |     // SEL = 1 ,选择AD0.0((Fpclk / 1000000 - 1) << 8) |         // CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz(0 << 16)                    |     // BURST = 0 ,软件控制转换操作(0 << 17)                    |      // CLKS = 0 ,使用11clock转换(1 << 21)                    |        // PDN = 1 , 正常工作模式(非掉电转换模式)(0 << 22)                    |        // TEST1:0 = 00 ,正常工作模式(非测试模式)(1 << 24)                    |      // START = 1 ,直接启动ADC转换(0 << 27);                         // EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)DelayNS(10);                              ADC_Data = AD0DR;                              // 读取ADC结果,并清除DONE标志位while(1){  AD0CR = (AD0CR&0x00FFFF00)|0x01|(1 << 24);    // 设置AD0.0,并进行第一次转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束AD0CR = AD0CR | (1 << 24);                  // 再次启运转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束       ADC_Data = AD0DR;                           // 读取ADC结果              ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值 共10位       ADC_Data = ADC_Data * 3300/1024;            // 数值转换//16进制转10进制ADC_Data2= ADC_Data;ADC_Data3= ADC_Data;//j=0;//循环次数,其实第四次就直接跳出循环了,因为AD转换结果只有10位for(i=0;i<4;i++){j=i*4;ADC_Data3 = ADC_Data2 &(0x0000000F << j);//依次左移4位if(ADC_Data3 ==0)break;else{//这里有移的目的是将0x0F00,0xF000,0x000F0等格式都转换成0x0000000F形式ADC_Data3=ADC_Data3>>j;  //得出16进制数组对应10进制数组的数组编号for(k=0;k<16;k++){if(ADC_Data3 == b_[k]){l=k;}                          }}          ADC_Data4= ADC_Data4 +b_[l]*c_[i] +b_[l];//得出的16进制对应的10进制数}      ADC_Data2 = 0x0;//10进制转换成用1位16进制数代表1个10进制数的16进制,例如:9->0x09for(i=0;i<4;i++){ j=i*4;if(ADC_Data4 !=0)//直到10进制的每一位都转换结束{ADC_Data5=ADC_Data4%10;ADC_Data4=ADC_Data4/10;//依次累加,例如第一步0x000+0x005;第二步0x005+0x020;最后0x025+0x100;等ADC_Data2= ADC_Data2 + (ADC_Data5 << j);}}//对于不同数值温度,显示不同颜色灯,且闪烁速度不同,红底闪烁最快,黄灯稍微慢,绿灯不闪if(ADC_Data>1200){if(ADC_Data<1800)display_yellow();elsedisplay_red();}elsedisplay_green();/*对P1接口输出清零,若相应位没能清零,可能会出现累加现象,例如使用IO1CLR =  0x03FF0000;,由于用到的P1为高16位,就会出现累加现象*/IO1CLR =  0xFFFF0000;IO1SET = (ADC_Data2<<16) & 0xFFFF0000 ;printf("AD0.0=%d mV \r\n", ADC_Data);        // 数据串行口输出    //变量清零ADC_Data2 =0x00000000;ADC_Data2 =0x00000000;ADC_Data3 =0x00000000;ADC_Data4 =0x00000000;ADC_Data5 =0x00000000;//AD0.1/* AD0CR = (AD0CR&0x00FFFF00)|0x02|(1 << 24); // 设置AD0.1,并进行第一次转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束AD0CR = AD0CR | (1 << 24);                  // 再次启运转换while( (AD0DR&0x80000000)==0 );             // 等待转换结束ADC_Data = AD0DR;                          // 读取ADC结果ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值ADC_Data = ADC_Data * 3300/1024;            // 数值转换printf("AD0.1=%d mV \r\r\n", ADC_Data);      // 数据通过串行口输出       //DelayNS(100);      */}}

利用10位AD转换器 及 LED 数码管,实现由AD转换器采集温度,并用数码管显示。温度超出一定范围,LED 指示灯闪烁报警。(主要分析进制16进制转换10进制,并用数码管显示问题)相关推荐

  1. 计算机进制小数位之间的转换,计算机进制之间相互转换

    <计算机进制之间相互转换>由会员分享,可在线阅读,更多相关<计算机进制之间相互转换(4页珍藏版)>请在人人文库网上搜索. 1.计算机进制之间相互转换计 算 机 进 制 之 间 ...

  2. 计算机不同进制数之间的转换,计算机进制数之间的转换002

    不错 除以16取余和倍数 如: (120)10 120/16 =8 ...8(余8) 8(余数8)/16=0 (8) (120)10 =(88)16 回答人的补充 2009-08-14 09:42 计 ...

  3. 各种进制数之间的转换

    计算机中各种进制数之间的转换 各种进制之间的转化都可以通过二进制为桥梁 二进制之间整数的转换 示例1:二进制数1100转化为各种进制数 1100转化成十进制数 ​ 1100 = 1*23+1*22+0 ...

  4. 2进制 , 8进制 , 10进制 , 16进制 , 介绍 及 相互转换 及 快速转换

    为什么要使用进制数 数据在计算机中的表示,最终以二进制的形式存在 , 就是各种 <黑客帝国>电影中那些 0101010- 的数字 ; 我们操作计算机 , 实际 就是 使用 程序 和 软件 ...

  5. python16进制转10进制_python 字节串及10进制,16进制相关转换

    进行协议解析时,总是会遇到各种各样的数据转换的问题,从二进制到十进制,从字节串到整数等等 整数之间的进制转换: 10进制转16进制: hex(16) ==> 0x10 16进制转10进制: in ...

  6. java 十六进制转十进制_「16进制转10进制」Java:十六进制转换成十进制 - seo实验室...

    16进制转10进制 问题及代码: /* *问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. 注:十六进制数中的10~15分别用大写的英文字母A.B.C.D.E. ...

  7. 超大数据10进制转2进制详解(可推广到其他进制)/ Codeup 100000579 问题 C: 进制转换

    问题C:进制转换 时间限制 内存限制 1.000sec 32MB 题目描述: 将一个长度最多为30位数字的十进制非负整数转换为二进制数输出. 输入: 多组数据,每行为一个长度不超过30位的十进制非负整 ...

  8. C++16进制转换10进制

    废话不多,直接上代码: #include <iostream> #include <cmath> //要用到pow()函数必须要这个库 using namespace std; ...

  9. Java 十进制正小数转为其他进制正小数(小数点后保留10位)

    N进制小数 题目描述: 编写程序实现将任意10进制正小数m转换成n进制的正小数,小数点后保留10位小数 解答要求: 时间限制1000ms,内存限制64ms 输入: 输入包含两个数m.n,用空格隔开.输 ...

最新文章

  1. 报道 | 本科4篇顶会论文如何做到?清华特奖干货分享:我是这样写论文、做实验、与导师相处...
  2. Linux内存管理 (26)内存相关工具
  3. 【NIPS2018】Spotlight及Oral论文汇总
  4. 创建多个虚拟环境 windows python Anacoda tensorflow
  5. select 组件-bug解决方案
  6. TwentyTwelve透明主题二次美化版
  7. 智能交通|智慧产业园区管理系统集成搭建
  8. 基于网络的 Red Hat 无人值守安装
  9. d1800芯片_基于D1800的收音/对讲机设计制作
  10. SEO中一些黑帽作弊方法介绍
  11. (HTML)浏览器将多个空格压缩为一个空格
  12. mac 语音召唤siri_在Mac上使用Siri可以做的11件事
  13. 利用VRRP功能实现简单的路由器备份(图)
  14. 2018辽大计算机拟录取,四川大学计算机学院2018年硕士研究生招生拟录取名单及成绩公示...
  15. 抑制电源模块电磁干扰的几种方法
  16. 【刷题】BZOJ 2069 [POI2004]ZAW
  17. docker 分析cpu占用过高
  18. HH SaaS电商系统的各种编号(编码/代码/代号)设计
  19. 数据脱敏技术的实践指南
  20. Android系统手机通讯录

热门文章

  1. 深入理解面向discuz的插件开发
  2. DWDM光模块和CWDM光模块的区别
  3. 原生php多表查询方法,ThinkPHP多表联合查询的常用方法
  4. 单片机做的音乐盒c语言程序,16*16滚动点阵屏+音乐盒C语言源程序
  5. opencv目标跟踪概述和人脸跟踪
  6. 计算机专业经典著作(转载)
  7. 多策略中日内策略+趋势策略的配合?
  8. java 使用freemarker 导出word 和图片
  9. CentOS7-命令-立即关机命令(shutdown -h now)
  10. WIN11 hosts文件打不开