标题:
我有一个STC8G1k08—20PIN的多通道内部ADC查询测量程序,想改成定时器加中断检测该...
[打印本页]
作者:
619247581
时间:
2020-6-18 17:15
标题:
我有一个STC8G1k08—20PIN的多通道内部ADC查询测量程序,想改成定时器加中断检测该...
本帖最后由 619247581 于 2020-6-18 17:16 编辑
#include<stc8g.h> //STC8G系列单片机头文件,可去最新版stc—isp里下载
#include "intrins.h"
#include "stdio.h"
#include "codetab.h"
#include "LQ12864.h"
/******************************+**********************************
函数功能: 采AD转换完成的值
说 明:
入口参数: channel 定义ADC口,范围:0x00~0x07 0x08~0x0e 0x0f
P1.0~P1.7 P3.0~P3.6 单片机VCC脚
出口参数: tes
*****************************************************************/
unsigned int AD_get(unsigned char channel)
{
int tes; //定义一个变量tes,用来储存ADC读取的结果
ADC_CONTR = 0x80|0x40|channel; //启动 AD 转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询 ADC 完成标志
ADC_CONTR &= ~0x20; //清完成标志
tes = ADC_RES; //读取 ADC 结果
return tes; //返回AD转换完成的值
}
/****************************************************************
函数功能: 读取8个采到的AD值,求其平均值并返回所求值
说 明:先取两次AD值,并丢弃,再采8个AD值,求其平均值,再返回值
入口参数: channel 定义ADC口,范围:0x00~0x07 0x08~0x0e 0x0f
P1.0~P1.7 P3.0~P3.6 单片机VCC脚
出口参数: res
*****************************************************************/
unsigned int AD_work(unsigned char channel)
{
char i;
unsigned int res=0;
AD_get(channel);
AD_get(channel); //前两个数据丢弃,在切换通道的时候更加稳定
res = 0; //res清零
for (i=0; i<8; i++)
{
res += AD_get(channel); //读取 8 次数据
}
res=res/8; //取平均值
return res; //返回完成的值
}
//主函数
void main()
{
unsigned int vcc; //定义无符号整形变量vcc,存储AD_val运算完后的整数值
unsigned int vcc1; //定义无符号整形变量vcc1,存储AD_val运算完后的小数值
unsigned int vcc2; //定义无符号整形变量vcc2,存储AD_vcc运算完后的整数值
unsigned int vcc3; //定义无符号整形变量vcc3,存储AD_vcc运算完后的小数值
unsigned int AD_val; //定义无符号整形变量AD_val,存储P1.0采到的AD值
unsigned int AD_vcc; //定义无符号整形变量AD_vcc,存储P1.1采到的AD值
unsigned char s[8]={0}; //定义无符号整形数组s,存储AD_val的值
unsigned char t[8]={0}; //定义无符号整形数组t,存储AD_vcc的值
P0M0 = 0x00; //设置P0.0~P0.7为双向口模式
P0M1 = 0x00;
P1M0 = 0x00; //设置P1.0~P1.7为双向口模式
P1M1 = 0x00;
P2M0 = 0x00; //设置P2.0~P2.7为双向口模式
P2M1 = 0x00;
P3M0 = 0x00; //设置P3.0~P3.7为双向口模式
P3M1 = 0x00;
P4M0 = 0x00; //设置P4.0~P4.7为双向口模式
P4M1 = 0x00;
P5M0 = 0x00; //设置P5.0~P5.7为双向口模式
P5M1 = 0x00;
P1M0 = 0x00; //设置 P1.0和P1.1,P1.4 为 ADC 口,也就是高阻输入模式
P1M1 = 0x13;
P3M0 = 0x00; //设置P3.1~P3.6为ADC 口
P3M1 = 0x7e;
ADCCFG = 0x0f; //设置 ADC 时钟为系统时钟/2/16/16
ADC_CONTR = 0x80; //使能 ADC 模块
OLED_Init(); //OLED初始化
while(1)
{
AD_val=AD_work(0x00); //将P1.0口的返回值储存到变量AD_val
AD_vcc=AD_work(0x01); //将P1.1口的返回值储存到变量AD_vcc
vcc=AD_val*20/1024; //取模作为显示电压1的整数
vcc1=AD_val*20%1024; //取余作为显示电压1的小数
vcc2=AD_vcc*20/1024; //取模作为显示电压2的整数
vcc3=AD_vcc*20%1024; //取余作为显示电压2的小数
if(vcc1<10) //如果小数部分小于10,则在数组里小数部分前置两个零
{
sprintf(s,"%d.00%dv",vcc,vcc1); //打印电压值到数组s
}
else if(vcc1<100) //如果小数部分小于100,则在数组里小数部分前置一个零
{
sprintf(s,"%d.0%dv",vcc,vcc1); //打印电压值到数组s
}
else if(vcc1>=1000) //如果小数部分小于1000,则在数组里小数部分强制减去18
{
sprintf(s,"%d.%dv",vcc,vcc1-18); //打印电压值到数组s
}
else //如果小数部分大于1000,无特殊要求
{
sprintf(s,"%d.%dv",vcc,vcc1); //打印电压值到数组s
}
if(vcc3<10) //如果小数部分小于10,则在数组里小数部分前置两个零
{
sprintf(t,"%d.00%dv",vcc2,vcc3);
}
else if(vcc3<100) //如果小数部分小于100,则在数组里小数部分前置一个零
{
sprintf(t,"%d.0%dv",vcc2,vcc3); //打印电压值到数组t
}
else if(vcc3>=1000) //如果小数部分小于1000,则在数组里小数部分强制减去18
{
sprintf(t,"%d.%dv",vcc2,vcc3-18); //打印电压值到数组t
}
else //如果小数部分大于1000,无特殊要求
{
sprintf(t,"%d.%dv",vcc2,vcc3); //打印电压值到数组t
}
// sprintf(s,"%d",AD_val); //把AD_val的值打印成一个字符串保存在数组s中
// sprintf(t,"%d",AD_vcc); //把AD_vcc的值打印成一个字符串保存在数组s中
delay(2000); //延时2秒,防止数据刷新太快
OLED_P6x8Str(24,0,"Voltage tester");
OLED_P6x8Str(0,1,"V1:");
OLED_P6x8Str(19,1,s); //在显示屏显示数组s里的值
OLED_P6x8Str(0,2,"I1:");
OLED_P6x8Str(0,4,"V3:");
OLED_P6x8Str(0,5,"I3:");
OLED_P6x8Str(0,7,"V5:");
OLED_P6x8Str(64,1,"V2:");
OLED_P6x8Str(83,1,t); //在显示屏显示数组t里的值
OLED_P6x8Str(64,2,"I2:");
OLED_P6x8Str(64,4,"V4:");
OLED_P6x8Str(64,5,"I4:");
OLED_FormLine(0,3);
OLED_FormLine(0,6);
AD_val=0; //清零
AD_vcc=0; //清零
vcc=0; //清零
vcc1=0; //清零
vcc2=0; //清零
vcc3=0; //清零
}
}
复制代码
如题,想改成定时器加中断检测内部多通道ADC的函数,不知道该怎么改,请求大佬们给点思路
作者:
Joseph824
时间:
2021-7-7 21:01
看看你的代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1