STC89C52单片机UART AD DA测试实验

发布者:MoonlightStar最新更新时间:2016-04-15 来源: eefocus关键字:STC89C52  单片机  UART  测试实验 手机看文章 扫描二维码
随时随地手机看文章
/////////////////////////////////////////////////////////////////////////// 

实现功能: 调节实验板上的标号为AD0的电位器改变电压,通过PCF8591的采集,把
     数据传输给单片机,单片机通过处理把采集到的电压值,显示在数码管
     上,同时把通过AD0采集到的数据重新写入PCF8591,让其转换成模拟信
     号,改变开发板上D11的亮暗程度,而且把采集到的数据通过串口发送到
     电脑上。注意所采用的通道为第0通道,也就
     是说调节的是AD0电位器
实验板型号:KBL-XYD-C52
实验名称: UART AD DA测试实验
编写人: 谢应东
编写日期:  2012-4-30     
/////////////////////////////////////////////////////////////////////////// 
#include  //包含52单片机头文件
#include  //包含标准输入输出文件

#define uchar unsigned char //宏定义这个谁都知道的
#define uint unsigned int

uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管1至F数字编码

sbit duan=P2^6;   //573锁存器段锁存端
sbit wei=P2^7;   //位锁存端

sbit sda=P2^0;   //定义模拟IIC总线的数据线
sbit scl=P2^1;   //定义模拟IIC总线的时钟线

float fValue;

#define FOSC 11059200L
#define TIMS  (65535-FOSC/12/1000)   //在12T模式下定时器中断1毫秒的计算方法

uint cCount,cFlag=0;
/////////////////////////////////////////////////////////////////////////// 
函数名称:毫秒延时函数
函数功能:实现毫秒级的延时
参数介绍:Delay_MS: 定义需要延时的毫秒的数值
          iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时
    iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得
返回值: 
注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形
          式完成,所以如果改变了晶振的频率,请做相应的改变
/////////////////////////////////////////////////////////////////////////// 

void DelayMs(uint Delay_MS)
{
 uint iNumber,iValue;
 for(iNumber=0;iNumber  {
     iValue=107;
     while(iValue--);
 }
}
/////////////////////////////////////////////////////////////////////////// 
函数名称:DelayUs
函数功能:延时几个微秒(us),用来IIC总线延时
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////// 

void DelayUs()
{;;}
/////////////////////////////////////////////////////////////////////////// 
函数名称:Display_V
函数功能:把通过PCF8591采集到的数据,在单片机处理完之后,显示在数码管上
参数介绍:cBai:要显示在第一个数码管上的数字
    cShi:要显示在第二个数码管上的数字
    cGe: 要显示在第三个数码管上的数字
返回值: 
注意事项:注意实验板上所要用到底的数码管为共阴极的数码管
/////////////////////////////////////////////////////////////////////////// 
void  Display_V(uchar cBai,uchar cShi,uchar cGe)
{
 duan=1;        //打开数码管的段选
 P0=table[cBai]|0x80; //送入相应的段选0x80是为了点亮数码管小数点(dp端)
 duan=0;     //关闭数码管的段选
 P0=0xff;
 wei=1;     //打开数码管的位选
 P0=0xfe;       //给要点亮数码管的公共极低电平
 wei=0;     //关闭数码管的位选
 DelayMs(5);    //稳定时序

 duan=1;     //打开数码管的段选
 P0=table[cShi];   //送入相应的段选
 duan=0;     //关闭数码管的段选
 P0=0xff;
 wei=1;      //打开数码管的位选
 P0=0xfd;     //给要点亮数码管的公共极低电平
 wei=0;      //打开数码管的位选
 DelayMs(5);     //稳定时序

 duan=1;      //打开数码管的段选
 P0=table[cGe];    //送入相应的段选
 duan=0;      //关闭数码管的段选
 P0=0xff;
 wei=1;      //打开数码管的位选
 P0=0xfb;     //给要点亮数码管的公共极低电平
 wei=0;      //打开数码管的位选
 DelayMs(5);     //稳定时序

/////////////////////////////////////////////////////////////////////////// 

函数名称:Init_IIC
函数功能:完成对IIC总线数据线时钟线初始化
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////// 
void Init_IIC() 
{
 sda=1;
 scl=1;
}
/////////////////////////////////////////////////////////////////////////// 
函数名称:Start_IIC
函数功能:IIC总线的开始条件
参数介绍:无
返回值: 
注意事项:具体请参考相关的文档
/////////////////////////////////////////////////////////////////////////// 
void Start_IIC()//开始条件
{
 sda=1;
 DelayUs();
 scl=1;
 DelayUs();
 sda=0; 
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Stop_IIC
函数功能:IIC总线的终止条件
参数介绍:无
返回值: 
注意事项:具体请参考相关的文档
/////////////////////////////////////////////////////////////////////////// 

void Stop_IIC()
{
 sda=0;
 DelayUs();
 scl=1;
 DelayUs();
 sda=1;
 DelayUs();
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Response_IIC
函数功能:IIC总线的应答条件
参数介绍:cNumber: 定义一个延时的变量
返回值: 
注意事项:具体请参考相关的文档
/////////////////////////////////////////////////////////////////////////// 
void Response_IIC()//
{
  uchar cNumber=0;  
  scl=1;
  DelayUs();
  while((sda==1)&&(cNumber<255))
  cNumber++;             //加一个等待时间防止程序一直处在检测状态
  scl=0;     //这个是应答和非应答综合的应答条件
  DelayUs();    
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Write_byte
函数功能:通过IIC总线向PCF8591写入一个字节
参数介绍:cData:要写入的字节的值
    cNumber: 定义for语句中用到的变量,因为IIC总线是一位一位写入的,所
             以需要循环8次
    cTempValue: 临时的一个变量
返回值: 
注意事项:具体请参考相关IIC文档
/////////////////////////////////////////////////////////////////////////// 
void Write_byte(uchar cData)
{
 uchar cNumber,cTempValue;
 cTempValue=cData;
 for(cNumber=0;cNumber<8;cNumber++) //循环8次,完成一个字节的写入
 {
  cTempValue=cTempValue<<1; //CY=cTempValue^7;
  scl=0;
     DelayUs();
  sda=CY;       //CY 进位标志位
  DelayUs();
  scl=1;
  DelayUs();
 }
 scl=0;
 DelayUs();
 sda=1;
 DelayUs();
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Read_byte
函数功能:通过IIC总线,从器件里读取一个字节,因为必须是一位一位读,所以需要
          循环8次
参数介绍:cNumber:for句用到的循环变量 
返回值:  cValue:返回读取到的字节
注意事项:请参考相应的文档
/////////////////////////////////////////////////////////////////////////// 

uchar Read_byte()
{
 uchar cNumber=0,cValue=0;
 scl=0;
 DelayUs();
 sda=1;
 DelayUs(); 
 for(cNumber=0;cNumber<8;cNumber++) //完成对一个字节的读取
 {
  scl=1;
  DelayUs(); 
  cValue=(cValue<<1)|sda;    //通过循环得到一个字节
  scl=0;
  DelayUs();
 }
 return cValue;       //返回读取到的字节
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Read_channel
函数功能:选取PCF8591的AD输入通道,然后再读出采集到数值,即电压值
参数介绍:无
返回值:  cValue:返回采集到的数据
注意事项:无
/////////////////////////////////////////////////////////////////////////// 
uchar Read_channel(uchar cChannel)//PCF通道选择函数
{
 uchar cValue;     //从这个通道读出数据是大多数学习者
 Start_IIC();     //比较模糊的地方
 Write_byte(0x90);       //这个时序请按照AT24C02的任意读时序图进行操作
 Response_IIC();    
 Write_byte(0x40|cChannel);
 Response_IIC();
 Start_IIC();
 Write_byte(0x91);     //给IIC器件写入相应的命令
 Response_IIC();
 cValue=Read_byte();     //读取采集到的数据
 Stop_IIC();
 
 return cValue;      //返回采集到的数据
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Write_Data
函数功能:把要写入的数据写入PCF8591,让其开始转换,然后输出相应的模拟值
参数介绍:cData:要写入PCF8591的数据
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////// 
void Write_Data(uchar cData)
{
 Start_IIC();  //以下严格按照PCF8591写时序图
 Write_byte(0x90); //进行操作
 Response_IIC(); 
 Write_byte(0x40);
 Response_IIC();
 Write_byte(cData);
 Response_IIC();
 Stop_IIC();
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:Init_UART
函数功能:设定UART的波特率,配置定时器0每一毫秒钟中断一次,打开相应的中断
    定时器1产生波特率,让定时器0开始中断计时
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////// 
void Init_UART()
{
 TMOD=0x21;//定时器1工作方式2,8位自动充装
 TH1=0xfd; //通信波特率定为9600bps
 TL1=0xfd; //晶振为11.0592M的

 TL0=TIMS;
 TH0=TIMS>>8; //定时1秒所要装的初值
 SM0=0; //选择串行口工作方式1
 SM1=1;

 EA=1;  //打开全局中断
 ET0=1; //打开定时器0中断
 TR0=1; //让定时器0开始工作
 TR1=1; //波特率的产生依靠是定时器1的溢出率
}
/////////////////////////////////////////////////////////////////////////// 

函数名称:main
函数功能:完成对采集到的电压值的处理,然后显示到前三个数码管上,把采集到的
    数据同时写入PCF8591里,让其转换成模拟信号,改变发光二极管D11的亮
    暗程度
参数介绍:cBai:因为把数分离,才能显示到数码管上,作为分离后显示在第一个数
          码管上的数
    cShi:显示在第二个数码管上的数
    cGe: 显示在第三个数码管上的数
    iTempValue:临时变量,赋予从PCF8591通道0读出来的数值
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////// 

void main()
{
 uchar cBai,cShi,cGe;
 int iTempValue;
 DelayMs(50);//稳定系统
 Init_UART();//初始化串口
 Init_IIC();//IIC总线初始化
 while(1) //大循环是用来不停地扫描PCF8591的数据变换
 
  iTempValue=Read_channel(0);//从PCF8591通道0读出来的数值
  fValue=(float)iTempValue/51; //要把num强制转换为float型进行计算
  cBai=iTempValue/51;//下面这三个分离是把从通道读取到的数值转换为电压
  cShi=iTempValueQ*10/51; //想一下5V为255那么1v是不是代表51
  cGe=iTempValueQ*10Q*10/51;//1.8v是不是数值92
  Display_V(cBai,cShi,cGe);//把电压值显示到数码管上
  Write_Data(iTempValue);//把采集到数据写到PCF8591,让其转换成模拟信号
  if(cFlag==1)
  {
   cFlag=0;//对标志位清零,以便下次再发送
   TI=1;   //这一点至关重要
   printf("The Volatage is %f V\n",fValue); //头文件stdio.h的标准函数
   printf("The Num is %d \n\n",iTempValue);
   while(!TI);//判断是否发送完毕
   TI=0; //发送完成后记住要清零,为了下次发送
  }
 }
}

void Timer0_Routine() interrupt 1
{
 TL0=TIMS;
 TH0=TIMS>>8; //定时1毫秒所要装的初值
 cCount++;
 if(cCount==1000)
 {
  cCount=0;
  cFlag=1;
 
}

关键字:STC89C52  单片机  UART  测试实验 引用地址:STC89C52单片机UART AD DA测试实验

上一篇:1602LCD显示器的使用
下一篇:STC89C52单片机AD测试实验

推荐阅读最新更新时间:2024-03-16 14:50

单片机编程时关于int
在进行单片机编程时,我们经常用Int定义变量。以前学C语言时,我知道int它表示的位数跟具体的硬件结构有关。不过看了一本书中 慎用int 这节后,我对int又有了更一步的认识。 原来C语言并没有进一步明确不同硬件平台下int位宽由硬件平台决定这一点,从而导致了对int不同的理解。实际上int并没有具体的位宽限制,是由所用硬件平台(MCU)和编译器共同决定位宽为多少,通常情况下编译器会将int的位宽定为与所用MCU的位宽一致。 文中也举了两个例子说明因为对int理解的不够深入而犯的错误。一个是因为将int误理解为32位,而编译器和MCU为16位宽。一个产品需要显示开机后的时间,显示精度为秒。如果按照int为32位的话,定义secon
[单片机]
单片机C8051F020及其在露点测试系统中的应用
简介:通过单片机应用于露点测试系统中存在的缺陷,引入了美国Cygnal公司新近在国内推出的C8051F020单片机,并对该单片机的功能和特点进行了应用性探讨,提出了在露点测试系统中采用C8051F020单片机的可行性方案,通过比较显示:该方案具有更高的性价比。 1应用背景 目前在食品加工、饲料、家用电器等行业中广泛应用的露点测试系统要求具有高精度、高可靠性及高稳定性等特点,而且整个测试过程中需要动态连续或者间歇性动态连续进行。测试系统的控制核心部分一般采用单片机系统,其硬件电路示意图如图1所示。这种单片机系统虽然基本能满足生产需要,但是,由于系统扩展芯片多、线路复杂,也都不同程度地暴露出资源再扩受限、易出故障、编程麻烦、升级维
[单片机]
<font color='red'>单片机</font>C8051F020及其在露点<font color='red'>测试</font>系统中的应用
单片机能做什么创意小发明?新手怎么制作单片机智能小车?
曾经,有一个老板跟我说,很羡慕我们这些做技术的。 我们都感觉有点讽刺,一个身价上千万的人,羡慕我们这些年收入不到20万的。 不过从他的说话方式来看,似乎是认真的,他说他也喜欢研究技术,只是年纪大了,学不动了。 不管你身在处于什么身份,相信每个男人心中啊,都有一个创客梦。 先不说通过技术去改变世界了,大多数人都是普通人,不是托尼史塔克。 不过即便是自己动手DIY一个小发明,写个小程序,烧录进去,让这个小玩意按照自己的程序逻辑去执行,也是成就感满满的。 当初,我也是这样被骗进单片机开发这个行业的,没想到一入坑就10年。 这10年技术生涯,虽然没让我过上衣食无忧的生活(这个完全是自己的问题),但是至少我现在想做一个什么小发明还是游刃有余
[单片机]
采用Eclipse IDE技术加快MCU的设计工作
更快、更好、更廉价——产品开发环境层面的竞争日趋白热化,要求也比以前高。过去,不同工具间缺乏互操作性是开发人员面临的主要问题,他们不得不花大量时间来确保互操作性,浪费了产品开发的宝贵资源。 如何用更少的资源与时间开发更好的产品?本文将介绍开放式源代码Eclipse集成设计环境(IDE)的优势以及如何用它来加速开发微控制器(MCU)。 开放式源代码与Eclipse 顾名思义,开放式源意味着源代码的开放性,也就是说,软件应当能够免费再分发,并提供开放式源代码。此外,还要允许他人修改,以衍生出新的软件,并同时维护作者源代码的完整性(2005年开放式源代码计划)。 图1 Eclipse平台的开放式可扩展架构 Eclipse是
[单片机]
采用Eclipse IDE技术加快<font color='red'>MCU</font>的设计工作
用PIC16F87X单片机实现高分辨率频率计的一种方法
1 引言 随着电子技术的迅速发展,以单片机为控制核心的控制器件,已经全面渗透到测试仪器和计量检定的各个方面。同时,频率计作为一种常用工具,在工程技术和无线电测量、计量等领域的应用十分广泛。本文介绍了一种以PIC16F87X系列单片机为控制器的高分辨率频率计的实现方法。 该方法设计的频率计主要用来测量脉冲频率。它采用LCD图形液晶显示,清晰度高,可视范围广,可外接晶体频率源,具有测量速度快、分辨率高的优点。 2 设计原理 PIC16F877A单片机内部集成有捕捉/比较/脉宽调制PWM (CCP)模块。当CCP工作在捕捉(capture)方式时,可捕捉外部输入脉冲的上升沿或下降沿,并产生相应的中断。 PIC16F877A单片
[应用]
详细解读:MSP430G2553单片机串口通信
  MSP430的不同型号,其串行通讯工作模式是一样的。以MSP430G2553为例进行说明。MSP430G2553是20个引脚的16位单片机。具有内置的16位定时器、16k的FLASH和512B的RAM,以及一个通用型模拟比较器以及采用通用串行通信接口的内置通信能力。此外还具有一个10位的模数(A/D)转换器。这里我们详细说明MSP430G2553串口通信。其引脚排布如图1.1所示。其功能表如表1.1所示。   串行通讯模块主要由三个部分组成:波特率生成部分、发送控制器以及接收控制器。如图1.2所示。            一、UART模式   在异步模式下,接收器自身实现帧的同步,外部的通讯设备并不使用这一时钟
[单片机]
详细解读:MSP430G2553<font color='red'>单片机</font>串口通信
MSP430单片机的热敏电阻温度测量
摘要 传统的数字式测量电阻的方法是先将电阻值转换为电信号(如电压),再用A/D转换器将其转换为数字信号,因此电路复杂,费用高。本文介绍一种类R—F转换频率测量温度的方法。直接把热敏电阻Rt接到由RC构成的多谐振荡器电路中,用MSP430单片机的捕获功能来获得多谐振荡器输出信号高低电平的脉宽并同时计数,则热敏电阻Rt与捕获高低电平时的计数值的差值成正比关系,查表可得温度值。 测量温度一般采用热敏电阻做传感器,测量的方法有R—V转换电压测量法和R—F转换频率测量法。这两种方法的电路复杂且成本高,电路中很多元器件直接影响测量精度。本文论述一种类R—F转换频率的测量法,用NE555定时器和热敏电阻等器件构成振荡器,由MSP430单片机
[单片机]
MSP430<font color='red'>单片机</font>的热敏电阻温度测量
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved