完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STC12C5A60S2单片机,ad转换一直进行200ms,每次转换的结果都相加,200ms后求这么多次采样的平均值,平均值与某个值进行比较,然后再一次转换200ms,再求平均,再比较......这样一直循环下去。
我用定时器定时50ms,4次中断后就是200ms,但是定时器开始工作后,ad转换能同时进行吗?还是定时器先工作,直到定时完50ms后才进行ad转换呢? 新手求助,拜托各位大佬了! void main() { while(1) { n=0; sum=0; TMOD=0x01; TH0=0x4C; //11.0592MHZ晶振,定时50ms TL0=0; EA=1; ET0=1; TR0=1; //定时器开始工作 while(n<=4) //没到200ms就一直ad转换 { InitADC(); //ad初始化 ADC_CONTR=ADC_POWER|ADC_SPEEDLL|P1ASF|ADC_START; _nop_(); _nop_(); _nop_(); _nop_(); while(!(ADC_CONTR&ADC_FLAG)); ADC_CONTR&=~ADC_FLAG; //一次ad转换结束 x=ADC_RES*256+ADC_RESL; sum+=x; } //n=0; y=sum/2457; //求平均 if(y>=31) //比较 { D1=0; Bee=0; } } } void InitADC() { P1ASF=0X04; ADC_RES=0; AUXR1=0x04; ADC_CONTR=ADC_POWER|ADC_SPEEDLL; Delay(2); } void Delay(unsigned int n) { unsigned int x; while(n--) { x=5000; while(x--); } } void exter() interrupt 1 { TH0=0x4C; TL0=0; n++; } |
|
相关推荐
6个回答
|
|
定时器是独立于cpu的外设 只要在初始化的时候设定了 模式和初值 他会自己不停的工作的,在你设置的定时器中断后 条件出发会进入中断,这时候cpu才会前去处理,所以说开启定时器之后ad是可以进行工作的
|
|
|
|
向北c 发表于 2018-5-10 09:24 那定时器中断的时候,ad也在工作吗?因为我定时200ms,我想让ad在200ms内一直不间断工作 |
|
|
|
这个问题取决于你的设计思路和目的,
定时50ms,如果定时到了时进行采样,那么200ms就是采样4次, 如果第一次采样开始进行定时,到200ms结束采样,定时50ms只是用来确定200ms是否到时,期间每次采样结束后就进行下一次采样,与定时器无关的话,那么200ms内的采样次数就取决于每次采样所需要的时间,这个次数通常都大于4次 |
|
|
|
人中狼 发表于 2018-5-10 10:32 我的思路是您说的第二种思路,是让采样次数大于4次的,但是我不知道我编的程序是不是这样的,能烦请您帮我看一下吗? |
|
|
|
试试这样改吧
unsigned char adc_times; void main() { n=0; sum=0; adc_times = 0; TMOD=0x01; TH0=0x4C; //11.0592MHZ晶振,定时50ms TL0=0; InitADC(); //ad初始化 EA=1; ET0=1; TR0=1; //定时器开始工作 while(1) { while(n<=4) //没到200ms就一直ad转换 { ADC_CONTR=ADC_POWER|ADC_SPEEDLL|P1ASF|ADC_START; _nop_(); _nop_(); _nop_(); _nop_(); while(!(ADC_CONTR&ADC_FLAG)); ADC_CONTR&=~ADC_FLAG; //一次ad转换结束 x=ADC_RES*256+ADC_RESL; sum+=x; adc_times ++; } n=0; y=sum/adc_times; //求平均 if(y>=31) //比较 { D1=0; Bee=0; } sum = 0; adc_times = 0; } } |
|
|
|
//查询定时法ADC转换查程序,不受中断影响,适用于STC12/15系列单片机
#include #include #define uint unsigned int //宏定义数据类型uint #define uchar unsigned char //宏定义数据类型uchar #define ulong unsigned long //宏定义数据类型ulong //宏定义ADC的操作命令 #define ADC_POWER 0x80 //ADC电源控制位 #define ADC_START 0x08 //ADC启动控制位 #define ADC_FLAG 0x10 //ADC完成标志位 //#define ADC_SPEEDLL 0x00 //420时钟速度控制 #define ADC_SPEEDL 0x20 //280时钟速度控制 //#define ADC_SPEEDH 0x40 //140时钟速度控制 //#define ADC_SPEEDHH 0x60 //70时钟速度控制 /********变量定义******/ uchar table[2]; //缓存 uint Average; //ADC采样平均值变量 bit OUT=0; //输出标志 /*--------------------------------------------- 定时器0初始化,时钟12T、16位重载模式 ----------------------------------------------*/ void Timer0Init(void) //2毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器自动重载模式 TL0 = 0xCD; //设置定时初值 TH0 = 0xF8; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 // ET0=1; //允许T0中断 // EA=1; //开全局中断 } /*------------------------------- 1ms延时子程序(11.0592MHz 1T) -------------------------------*/ void delayms(uint k) { uint i,j; for(i=k;i>0;i--) for(j=1150;j>0;j--); } /*------------------------ InitADC -------------------------*/ void InitADC() { P1ASF=0x01; //设置P1的0通道端口作为模拟输入 ADC_RES=0; //清除ADC_RES存储器以前的结果 ADC_RESL=0; //清除ADC_RESL存储器以前的结果 ADC_CONTR=ADC_POWER|ADC_SPEEDL; //ADC 开启电源、转换速度 1010 0000 delayms(1); //上电延时1ms } /*--------------------------- Get ADC Result ----------------------------*/ uint Read(uchar CHA) //获取ADC结果 { ADC_CONTR=ADC_POWER|ADC_SPEEDL|CHA|ADC_START;//启动转换1010 1000 _nop_(); //延时确保正确读到ADC_CONTR寄存器的值 _nop_(); _nop_(); _nop_(); while(!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成标志置位 1011 1000 ADC_CONTR &=~ADC_FLAG; //关闭ADC return(ADC_RES*4+ADC_RESL); //返回十位ADC结果 } /****** ADC滤波子程序*******/ void LB_ADC() { static ulong PJZ_ADC=0; //累加100次采样的变量 static uchar count=0; //计数器变量 PJZ_ADC += Read(0); //第1通道累加100次采样 count++; //计数器变量自+1 if(count>=100) //如果计数到100次采样 { count=0; //计数器清0 Average=((PJZ_ADC+5)/100); //获取平均值含四舍五入 PJZ_ADC=0; //采样变量清0 OUT=1; //输出标志置1 } } /*******计时采样程序***********/ void Time() { if(TF0==1) //如果查询定时器溢出标志TF0为1 { //定时器溢出周期2ms TF0=0; //定时器溢出标志TF0清0 LB_ADC(); //采用滤波 } } /************数据解析保存*************/ void analysis() { if(OUT==1) { OUT=0; table[0]=Average>>8; //保存高8位数据 table[1]=Average; //保存低8位数据 } } /*********主函数****************/ void main() { P1M1 = 0x01; //设置P1.0高阻 P1M0 = 0x00; //设置P1.0高阻 InitADC(); //初始化ADC Timer0Init(); //初始化定时器0 while(1) { Time(); //运行计时采样程序 analysis(); //200ms刷新缓存数据 //可以插入计算/查表/显示/串口程序 } } |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
205 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1253 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
848 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
853 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1073 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12009 浏览 31 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 13:14 , Processed in 0.655807 second(s), Total 51, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号