标题:
STM8S光敏测量带AD值电压值和挡位的源程序
[打印本页]
作者:
叫我红领巾
时间:
2018-7-20 00:03
标题:
STM8S光敏测量带AD值电压值和挡位的源程序
硬件电路为光敏电阻串联一个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)
2018-7-20 00:03 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
叫我红领巾
时间:
2018-7-20 00:04
稍加改动可移植到8S103/105等单片机上
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1