找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2289|回复: 1
打印 上一主题 下一主题
收起左侧

STM8S光敏测量带AD值电压值和挡位的源程序

[复制链接]
跳转到指定楼层
楼主
ID:370779 发表于 2018-7-20 00:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
硬件电路为光敏电阻串联一个20K的分压电阻 接1602液晶显示 采用STM8S208MB芯片 内部AIN13通道 可显示采集到的AD值、转换后的电压值以及挡位

STM8S单片机源程序:
  1. /*光敏测量 接20K分压电阻 可显示读取到的AD值 转换后的电压值及挡位 AIN13端口PF5*/
  2. /*注意:LCD R/W引脚需要硬件接地 若要软件接地则GPIO初始化内定义*/

  3. #include"iostm8s208mb.h"

  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define ushort unsigned short

  7. uchar tab1[]="=ADC2  GUANGMIN="; //初始化后显示画面
  8. uchar tab2[]="=      .   V   =";

  9. static uint AD_temp[10]={0,0,0,0,0,0,0,0,0,0}; //建立数组用于存放采集的AD的10个数值
  10. static uint AD_val=0; //全局变量  ADC单次采样数据
  11. static uint voltage=0; //实际测得的电压值

  12. #define LCD_EN PF_ODR_ODR4 //LCD使能端
  13. #define LCD_RS PF_ODR_ODR0 //LCD写端口
  14. #define LCD_DATA PB_ODR    //LCD数据端

  15. void delay(uint z) //约1ms延时
  16. {
  17.   uint i,j;
  18.   while (z--)
  19.   {
  20.     for(i=0;i<50;i++)
  21.       for(j=0;j<20;j++);
  22.   }
  23. }

  24. void GPIO_init(void)
  25. {
  26.   PF_DDR_DDR4=1; //LCD使能端初始化
  27.   PF_CR1_C14=1;
  28.   PF_CR2_C24=1;
  29.   
  30.   PF_DDR_DDR0=1; //LCD写端口初始化
  31.   PF_CR1_C10=1;
  32.   PF_CR2_C20=1;
  33.   
  34.   PB_DDR=0xff; //LCD数据端初始化
  35.   PB_CR1=0xff;
  36.   PB_CR2=0xff;  
  37.   
  38. }

  39. void write_com(uchar com)  //LCD写命令 参考时序图
  40. {
  41.   LCD_RS=0;
  42.   LCD_DATA=com;
  43.   delay(5);
  44.   LCD_EN=1;
  45.   delay(5);
  46.   LCD_EN=0;
  47. }

  48. void write_data(uchar data) //LCD写数据 参考时序图
  49. {
  50.   LCD_RS=1;
  51.   LCD_DATA=data;
  52.   delay(5);
  53.   LCD_EN=1;
  54.   delay(5);
  55.   LCD_EN=0;
  56. }

  57. void LCD_init(void)  //LCD初始化
  58. {
  59.   LCD_EN=0;
  60.   write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
  61.   write_com(0x0c); //设置开显示,不显示光标
  62.   write_com(0x06); //写一个字符后地址指针加1
  63.   write_com(0x01); //显示清0,数据指针清0
  64. }

  65. void LCD_watch(uchar add,uchar data) //LCD显示计数函数
  66. {
  67.   write_com(0x80+0x40+add);
  68.   write_data(0x30+data); //0x30表示字符表内0-9数字的八位为0011 0000
  69. }

  70. void LCD_DIS2(void) //LCD初始化结束后显示内容
  71. {
  72.   uchar num;
  73.   write_com(0x80);
  74.   for(num=0;num<16;num++)
  75.   {
  76.     write_data(tab1[num]);
  77.     delay(5);
  78.   }
  79.   write_com(0x80+0x40);
  80.   for(num=0;num<16;num++)
  81.   {
  82.     write_data(tab2[num]);
  83.     delay(5);
  84.   }
  85. }

  86. void ADC_init(void)  //ADC13初始化函数
  87. {
  88.   ADC_CSR=0x0d; //禁止中断使能 选择AIN13通道
  89.   ADC_CR1=0x02; //Fmaster2分频 连续转换模式
  90.   ADC_CR2=0x08; //禁止外部触发 右对齐方式
  91.   
  92.   PF_DDR_DDR5=0; //PF5设置为无中断悬浮输入
  93.   PF_CR1_C15=0;
  94.   PF_CR2_C25=0;
  95.   
  96.   ADC_TDRH=0xff; //禁止施密特触发功能
  97.   ADC_TDRL=0xff;
  98. //  ADC_CR1|=0x01; //使能唤醒ADC
  99. }

  100. void ADC_GET(void) //ADC转换函数
  101. {
  102.   uchar num=0; //num为采集次数
  103.   ADC_CR1|=0x01; //使能唤醒ADC
  104.   ADC_CR1|=0x01; //启动ADC转换
  105.   while(num<10) //采集10次结果
  106.   {
  107.     while((ADC_CSR&0x80)==0); //判断EOC位是否为1 等待转换结束
  108.     ADC_CSR&=0x7f; //结束后EOC位由软件清零
  109.     AD_temp[num]=(uint)ADC_DRL; //先赋值低位
  110.     AD_temp[num]|=(uint)ADC_DRH<<8; //高位左移8位后与低位拼合
  111.     num++;   
  112.   }
  113.   ADC_CR1&=0xfe; //关闭ADC转换
  114. }

  115. void AVG_AD_temp(void) //平均值滤波函数
  116. {
  117.   uchar i,j;
  118.   uint temp; //定义暂存变量暂存数值
  119.   for(i=10;i>=1;i--)
  120.   {
  121.     for(j=0;j<(i-1);j++)
  122.     {
  123.       if(AD_temp[j]>AD_temp[j+1])
  124.       {
  125.         temp=AD_temp[j];
  126.         AD_temp[j]=AD_temp[j+1];
  127.         AD_temp[j+1]=temp;
  128.       }
  129.     }
  130.   }
  131.   for(i=2;i<=7;i++) //将采集到的10个值取中间6个进行累加求平均
  132.   {
  133.     AD_val+=AD_temp[i];
  134.   }
  135.   AD_val=(uint)AD_val/6;
  136. }

  137. void main(void)
  138. {
  139.   uchar qian,bai,shi,ge,qian1,bai1,shi1,ge1,shi2,ge2;
  140.   GPIO_init();
  141.   ADC_init();
  142.   LCD_init();
  143.   LCD_DIS2();
  144.   while(1)
  145.   {
  146.     ADC_GET();
  147.     AVG_AD_temp();
  148. //    delay(50);
  149.    
  150.     /*这里显示的是AIN13读取到的AD实际值*/
  151.     qian=AD_val/1000; //千位
  152.     bai=AD_val%1000/100; //百位
  153.     shi=AD_val%100/10; //十位
  154.     ge=AD_val%10; //个位
  155.     LCD_watch(1,qian);
  156.     LCD_watch(2,bai);
  157.     LCD_watch(3,shi);
  158.     LCD_watch(4,ge);
  159.    
  160.     /*这里显示的是挡位(0-99对应0-1023) 电压基准来自Vref+*/
  161.     shi2=(uint)(AD_val*0.09766)/10; //十位
  162.     ge2=(uint)(AD_val/0.09766)%10; //个位
  163.     LCD_watch(13,shi2);
  164.     LCD_watch(14,ge2);
  165.    
  166.     voltage=(uint)(AD_val*5.087890625); //获取的AD值乘以基准值 由于乘积为浮点型所以再次转换为整形
  167.     AD_val=0; //AD值清零   
  168.    
  169.     /*这里显示的是AD转换后的电压值 电压基准来自Vref+ 此处和VDD连接 即+5V*/
  170.     qian1=voltage/1000; //千位
  171.     bai1=voltage%1000/100; //百位
  172.     shi1=voltage%100/10; //十位
  173.     ge1=voltage%10; //个位
  174.     LCD_watch(6,qian1);
  175.     LCD_watch(8,bai1);
  176.     LCD_watch(9,shi1);
  177.     LCD_watch(10,ge1);

  178.   }
  179. }
复制代码

所有资料51hei提供下载:
光敏测量带AD值电压值和挡位.rar (272.37 KB, 下载次数: 24)



评分

参与人数 2黑币 +53 收起 理由
jjjjouy + 3 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:370779 发表于 2018-7-20 00:04 | 只看该作者
稍加改动可移植到8S103/105等单片机上
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表