zoukankan      html  css  js  c++  java
  • PCF8591学习(二)AD转换,算法,串口打印

    利用A/D,加上简单的计算,加上串口打印,我们就可以简单的测量电压了。就可以做简单的电压或电流表了。调节电位器,电压会变化,led灯也会变化,电脑显示实验现象如图:

    源代码:
    1. 项目名称:PCF8591AD和串口打印 
    2. 项目内容:A/D转换,把转换的数字量 
    3. 送给P0口控制LED的亮灭 ; 
    4. 并把转换的数字逻辑 
    5. 运算,送给串口,打印到电脑上。 
    6. 这样就可以采样电压信号了,并处理。 
    7. 可以扩展做出电压表,电流表等。 
    8. 作者:YUAN 
    9. */  
    10.   
    11. #include <reg52.h>  
    12. #include <stdio.h>        //printf输出头文件  
    13. #include <intrins.h>  //_nop_()延时头文件  
    14. typedef unsigned char uChar8;  
    15. typedef unsigned int uInt16;  
    16. sbit SDA = P1^0;  
    17. sbit SCL = P1^1;  
    18. #define PCF8591Add 0x90 //PCF8591的器件地址和写操作  
    19. uChar8 gTemp;  
    20. float gfDataVal;    //用在转载计算的数值,并发送给计算机  
    21.   
    22. //延时函数  
    23. void DelayMS(uInt16 lValMS);  
    24. void Delay5us(void);  
    25. //IIC操作的几个函数  
    26. void IICInit(void);     //IIC初始化  
    27. void IICStart(void);    //起始信号  
    28. void IICStop(void);     //停止信号  
    29. void IICAck(void);      //应答信号  
    30. void IICReadAck(void);  //读应答信号  
    31. void IICWriteOneByte(uChar8 lByteVal);                  //写一个字节  
    32. uChar8 IICReadOneByte(void);        //读一个字节  
    33. void PCF8591WriteRegulate(uChar8 lREGVal);  //Regulate控制器,这里写控制函数  
    34. uChar8  ReadDataPCF8591(void);  
    35. //   
    36.   
    37. //串口的几个程序  
    38. void UartInit(void);        //串口初始化  
    39. void UartPrint(float iVal); //Printd打印,打印函数  
    40.                                   
    41. void main()  
    42. {  
    43.     IICInit();  
    44.     UartInit();  
    45.     while(1)  
    46.     {      
    47.         /*写入控制字00,即模拟量输出关闭,选择通道0, 
    48.         不自动增加通道,模拟量输入围方式0*/  
    49.          PCF8591WriteRegulate(0x00);  
    50.          P0 = ReadDataPCF8591();   
    51.          gTemp = P0;    //用来中转的存储区  
    52.          gfDataVal = (float)gTemp/255*5;   //强制转换  
    53.          DelayMS(1000);  
    54.          UartPrint(gfDataVal);  
    55.     }  
    56. }  
    57.   
    58. void DelayMS(uInt16 lValMS) //延时函数  
    59. {  
    60.     uInt16 luiVal,lujVal;  
    61.     for(luiVal = 0; luiVal < lValMS; luiVal++)  
    62.         for(lujVal = 0; lujVal < 113; lujVal++);  
    63. }  
    64. void Delay5us(void)  
    65. {  
    66.     _nop_();_nop_();_nop_();  
    67.     _nop_();_nop_();_nop_();  
    68. }  
    69. //IIC总线空闲时均为高电平  
    70. void IICInit(void)      //IIC初始化  
    71. {  
    72.     SCL = 0;  
    73.     SDA=1;  
    74.     Delay5us();  
    75.     SCL=1;  
    76. }  
    77. //SCL高电平期间SDA由高到低的变化为起始信号  
    78. void IICStart(void) //起始信号  
    79. {  
    80.     SCL = 0;  
    81.     Delay5us();  
    82.     SDA = 1;  
    83.     Delay5us();  
    84.     SCL = 1;  
    85.     Delay5us();  
    86.     SDA = 0;  
    87.     Delay5us();  
    88.     //防止接下来SDA数据变化导致IIC总线误判   
    89.     SCL = 0;       
    90. }  
    91. //SCL高电平期间SDA由低到高的变化为终止信号  
    92. void IICStop(void)      //停止信号  
    93. {  
    94.     SCL = 0;  
    95.     Delay5us();  
    96.     SDA = 0;  
    97.     Delay5us();  
    98.     SCL = 1;  
    99.     Delay5us();  
    100.     SDA = 1;  
    101.     Delay5us();  
    102.     //防止接下来SDA数据变化导致IIC总线误判   
    103.     SCL = 0;  
    104. }  
    105. //一个脉冲期间,SDA为低电平为应答  
    106. void IICAck(void)       //应答信号  
    107. {  
    108.     SCL = 0;  
    109.     Delay5us();  
    110.     SDA = 0;  
    111.     Delay5us();  
    112.     SCL = 1;  
    113.     Delay5us();  
    114.     SCL = 0;          
    115. }  
    116. /*cpu读应答信号,如果应答了则 
    117. 继续传输数据,否则在一定时间里, 
    118. 默认已经应答,继续传数据 
    119. */  
    120. void IICReadAck(void)   //读应答信号  
    121. {  
    122.     uChar8 li = 0;  
    123.     SCL = 0;  
    124.     SDA = 1;  //确保读出的值为0,因此先送1  
    125.     Delay5us();  
    126.     SCL = 1;  
    127.     Delay5us();  
    128.     //如果没有应答或时间没有超过预定时间则停在此处  
    129.     while((1 == SDA)&&(li<255))li++;  
    130.     SCL = 0;  
    131.     Delay5us();       
    132.     SDA = 1;              
    133. }  
    134. /* 
    135.     写1个字节,先写高位。 
    136. */  
    137. void IICWriteOneByte(uChar8 lByteVal)                   //写一个字节  
    138. {  
    139.     uChar8 li,liVal;  
    140.     liVal = lByteVal;  
    141.   
    142.     for(li=0;li<8;li++)      
    143.     {  
    144.           
    145.         SCL = 0;   
    146.         Delay5us();   
    147.         SDA = (bit)(liVal&0x80);    //把数据准备好等待传送  
    148.         Delay5us();   
    149.         SCL = 1;  
    150.         Delay5us();  
    151.         liVal <<= 1;  
    152.     }   
    153.     SCL = 0;   
    154.     Delay5us();   
    155.     SDA = 1;  
    156. }  
    157. /* 
    158. 读取一个字节并把读到的值返回 
    159. */  
    160. uChar8 IICReadOneByte(void)  
    161. {  
    162.     uChar8 li,liVal;  
    163.     SCL = 0;  
    164.     SDA = 1;  
    165.     for(li=0;li<8;li++)  
    166.     {  
    167.         liVal <<= 1;  
    168.         SCL = 0;  
    169.         Delay5us();  
    170.         SCL = 1;  
    171.         Delay5us();  
    172.         liVal = (liVal|SDA);  
    173.     }  
    174.     SCL = 0;   
    175.     return liVal;  
    176. }     
    177. //Regulate控制器,这里写控制函数  
    178. void PCF8591WriteRegulate(uChar8 lREGVal)  
    179. {  
    180.     IICStart();  
    181.     IICWriteOneByte(PCF8591Add);    //PCF8591的地址,写控制  
    182.     IICReadAck();  
    183.     IICWriteOneByte(lREGVal);       //写入控制字  
    184.     IICReadAck();  
    185.     IICStop();  
    186. }     
    187. uChar8  ReadDataPCF8591(void)  
    188. {  
    189.     uChar8 liVal;  
    190.     IICStart();  
    191.     IICWriteOneByte(PCF8591Add|0x01);   //PCF8591的地址,读控制      
    192.     liVal = IICReadOneByte();  
    193.     IICAck();  
    194.     IICStop();  
    195.     return liVal;     
    196. }   
    197. //串口的程序  
    198. void UartInit(void)  
    199. {  
    200.     TMOD &= 0x0f;    //只改变要改变的  
    201.     TMOD |= 0x20;   //设置定时器0为工作方式2  
    202.     TL1 = 0xfd;  
    203.     TH1 = 0xfd;     //设置波特率为9600bps  
    204.     TR1 = 1;        //允许T1开始计数  
    205.   
    206.     SCON &= 0x5f;  
    207.     SCON |= 0x50;   //设置串口工作在方式1,允许接收数据   
    208. }  
    209. //把读出来的值打印到计算机上  
    210. void UartPrint(float iVal)  
    211. {  
    212.     TI=1;  
    213.     printf("测得电压为:%f\n",iVal);  
    214.     while(!TI);  
    215.     TI=0;  
    216. }  
     
  • 相关阅读:
    Python:Lasso方法、GM预测模型、神经网络预测模型之财政收入影响因素分析及预测
    ARIMA模型构建、预测——基于Python
    家用电器用户行为分析与事件识别学习笔记
    JQData数据提取及MySQL简单操作——基于Python
    android 沉浸通知栏
    PullToRefreshScrollView 修改下拉刷新图标
    Android AlertDialog 设置setSingleChoiceItems不显示列表的原因【setMessage和setSingleChoiceItems不能同时使用】
    图片跑马灯抽奖,本地图片变换简单实现
    android知识点大总结
    Android 面试精华题目总结
  • 原文地址:https://www.cnblogs.com/yuanbao825/p/5107626.html
Copyright © 2011-2022 走看看