本帖最后由 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的函数,不知道该怎么改,请求大佬们给点思路
|