硬件电路为光敏电阻串联一个20K的分压电阻 接1602液晶显示 采用STM8S208MB芯片 内部AIN13通道 可显示采集到的AD值、转换后的电压值以及挡位
STM8S单片机源程序:
- /*光敏测量 接20K分压电阻 可显示读取到的AD值 转换后的电压值及挡位 AIN13端口PF5*/
- /*注意:LCD R/W引脚需要硬件接地 若要软件接地则GPIO初始化内定义*/
- #include"iostm8s208mb.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define ushort unsigned short
- uchar tab1[]="=ADC2 GUANGMIN="; //初始化后显示画面
- uchar tab2[]="= . V =";
- static uint AD_temp[10]={0,0,0,0,0,0,0,0,0,0}; //建立数组用于存放采集的AD的10个数值
- static uint AD_val=0; //全局变量 ADC单次采样数据
- static uint voltage=0; //实际测得的电压值
-
- #define LCD_EN PF_ODR_ODR4 //LCD使能端
- #define LCD_RS PF_ODR_ODR0 //LCD写端口
- #define LCD_DATA PB_ODR //LCD数据端
- void delay(uint z) //约1ms延时
- {
- uint i,j;
- while (z--)
- {
- for(i=0;i<50;i++)
- for(j=0;j<20;j++);
- }
- }
- void GPIO_init(void)
- {
- PF_DDR_DDR4=1; //LCD使能端初始化
- PF_CR1_C14=1;
- PF_CR2_C24=1;
-
- PF_DDR_DDR0=1; //LCD写端口初始化
- PF_CR1_C10=1;
- PF_CR2_C20=1;
-
- PB_DDR=0xff; //LCD数据端初始化
- PB_CR1=0xff;
- PB_CR2=0xff;
-
- }
- void write_com(uchar com) //LCD写命令 参考时序图
- {
- LCD_RS=0;
- LCD_DATA=com;
- delay(5);
- LCD_EN=1;
- delay(5);
- LCD_EN=0;
- }
- void write_data(uchar data) //LCD写数据 参考时序图
- {
- LCD_RS=1;
- LCD_DATA=data;
- delay(5);
- LCD_EN=1;
- delay(5);
- LCD_EN=0;
- }
- void LCD_init(void) //LCD初始化
- {
- LCD_EN=0;
- write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
- write_com(0x0c); //设置开显示,不显示光标
- write_com(0x06); //写一个字符后地址指针加1
- write_com(0x01); //显示清0,数据指针清0
- }
- void LCD_watch(uchar add,uchar data) //LCD显示计数函数
- {
- write_com(0x80+0x40+add);
- write_data(0x30+data); //0x30表示字符表内0-9数字的八位为0011 0000
- }
- void LCD_DIS2(void) //LCD初始化结束后显示内容
- {
- uchar num;
- write_com(0x80);
- for(num=0;num<16;num++)
- {
- write_data(tab1[num]);
- delay(5);
- }
- write_com(0x80+0x40);
- for(num=0;num<16;num++)
- {
- write_data(tab2[num]);
- delay(5);
- }
- }
- void ADC_init(void) //ADC13初始化函数
- {
- ADC_CSR=0x0d; //禁止中断使能 选择AIN13通道
- ADC_CR1=0x02; //Fmaster2分频 连续转换模式
- ADC_CR2=0x08; //禁止外部触发 右对齐方式
-
- PF_DDR_DDR5=0; //PF5设置为无中断悬浮输入
- PF_CR1_C15=0;
- PF_CR2_C25=0;
-
- ADC_TDRH=0xff; //禁止施密特触发功能
- ADC_TDRL=0xff;
- // ADC_CR1|=0x01; //使能唤醒ADC
- }
- void ADC_GET(void) //ADC转换函数
- {
- uchar num=0; //num为采集次数
- ADC_CR1|=0x01; //使能唤醒ADC
- ADC_CR1|=0x01; //启动ADC转换
- while(num<10) //采集10次结果
- {
- while((ADC_CSR&0x80)==0); //判断EOC位是否为1 等待转换结束
- ADC_CSR&=0x7f; //结束后EOC位由软件清零
- AD_temp[num]=(uint)ADC_DRL; //先赋值低位
- AD_temp[num]|=(uint)ADC_DRH<<8; //高位左移8位后与低位拼合
- num++;
- }
- ADC_CR1&=0xfe; //关闭ADC转换
- }
- void AVG_AD_temp(void) //平均值滤波函数
- {
- uchar i,j;
- uint temp; //定义暂存变量暂存数值
- for(i=10;i>=1;i--)
- {
- for(j=0;j<(i-1);j++)
- {
- if(AD_temp[j]>AD_temp[j+1])
- {
- temp=AD_temp[j];
- AD_temp[j]=AD_temp[j+1];
- AD_temp[j+1]=temp;
- }
- }
- }
- for(i=2;i<=7;i++) //将采集到的10个值取中间6个进行累加求平均
- {
- AD_val+=AD_temp[i];
- }
- AD_val=(uint)AD_val/6;
- }
- void main(void)
- {
- uchar qian,bai,shi,ge,qian1,bai1,shi1,ge1,shi2,ge2;
- GPIO_init();
- ADC_init();
- LCD_init();
- LCD_DIS2();
- while(1)
- {
- ADC_GET();
- AVG_AD_temp();
- // delay(50);
-
- /*这里显示的是AIN13读取到的AD实际值*/
- qian=AD_val/1000; //千位
- bai=AD_val%1000/100; //百位
- shi=AD_val%100/10; //十位
- ge=AD_val%10; //个位
- LCD_watch(1,qian);
- LCD_watch(2,bai);
- LCD_watch(3,shi);
- LCD_watch(4,ge);
-
- /*这里显示的是挡位(0-99对应0-1023) 电压基准来自Vref+*/
- shi2=(uint)(AD_val*0.09766)/10; //十位
- ge2=(uint)(AD_val/0.09766)%10; //个位
- LCD_watch(13,shi2);
- LCD_watch(14,ge2);
-
- voltage=(uint)(AD_val*5.087890625); //获取的AD值乘以基准值 由于乘积为浮点型所以再次转换为整形
- AD_val=0; //AD值清零
-
- /*这里显示的是AD转换后的电压值 电压基准来自Vref+ 此处和VDD连接 即+5V*/
- qian1=voltage/1000; //千位
- bai1=voltage%1000/100; //百位
- shi1=voltage%100/10; //十位
- ge1=voltage%10; //个位
- LCD_watch(6,qian1);
- LCD_watch(8,bai1);
- LCD_watch(9,shi1);
- LCD_watch(10,ge1);
- }
- }
复制代码
所有资料51hei提供下载:
光敏测量带AD值电压值和挡位.rar
(272.37 KB, 下载次数: 24)
|