STC15W 单片机及编程的一些问题
时间:10-02
整理:3721RD
点击:
AD采样的公式为 getadv=2.5*adhl2/adhl1; (其中adhl2是单片机采样电位器的AD转换结果,adhl1是外接2.5V基准源AD转换的结果)
1、用KEIL软件运行仿真了一下,为什么程序执行到getadv=2.5*adhl2/adhl1;语句后,getadv的值为-1,理论上应该是getadv=0的(因为此时AD转换器还没开始工作,adhl2/adhl1都该为0x0000), 当我根据 if(x<=getadv<y)判断调光函数里时,,程序不进入到if(0<=getadv<0.3){},而是进入到了if(0.3<=getadv<0.6){;;;;}及以后的所有if()函数语句。(定义如下:uint adhl1,adhl2; float getadv;)
2、当定义uchar getadv时,软件运行仿真程序执行到getadv=2.5*adhl2/adhl1;语句后,getadv的值为255,,,,,
当我根据 if(x<=getadv<y)判断调光函数里时,,程序进入到了if(0.9<=getadv<1.2){;;;;}及以后的所有if()函数语句。
编译什么无错误 但是软件运行有点毛病,不知道那个地方出了点问题。求赐教!很怀疑是不是这些小数无法被系统识别。求帮忙!先谢谢了。程序如下:
1、用KEIL软件运行仿真了一下,为什么程序执行到getadv=2.5*adhl2/adhl1;语句后,getadv的值为-1,理论上应该是getadv=0的(因为此时AD转换器还没开始工作,adhl2/adhl1都该为0x0000), 当我根据 if(x<=getadv<y)判断调光函数里时,,程序不进入到if(0<=getadv<0.3){},而是进入到了if(0.3<=getadv<0.6){;;;;}及以后的所有if()函数语句。(定义如下:uint adhl1,adhl2; float getadv;)
2、当定义uchar getadv时,软件运行仿真程序执行到getadv=2.5*adhl2/adhl1;语句后,getadv的值为255,,,,,
当我根据 if(x<=getadv<y)判断调光函数里时,,程序进入到了if(0.9<=getadv<1.2){;;;;}及以后的所有if()函数语句。
编译什么无错误 但是软件运行有点毛病,不知道那个地方出了点问题。求赐教!很怀疑是不是这些小数无法被系统识别。求帮忙!先谢谢了。程序如下:
- #ifndef __STC15W_H
- #define __STC15W_H
- #define ADC_POWER 0x80
- #define ADC_FLAG 0x10
- #define ADC_START 0x08
- #define ADC_SPEEDHH 0x60//90T
- sfr P1M1=0x91;
- sfr P1M0=0x92;
- sfr P1ASF=0x9d;
- sfr ADC_CONTR=0xbc;
- sfr ADC_RES=0xbd;
- sfr ADC_RESL=0xbe;
- sfr CMOD=0xD9;
- sfr CCON=0xD8;
- sfr PCA_PWM0=0xf2;
- sfr CCAPM0=0xDA;
- sfr CL=0xE9;
- sfr CH=0xF9;
- sfr CCAP0L=0xEA;
- sfr CCAP0H=0xFA;
- sbit CR=0xDE;
- sbit EADC=0xad;
- #endif
- /****内部时钟6MHZ PWM的频率为6000/12/256=1.953125KHZ 周期512us ************/
- //注意:在更新重装值时,必须先写高两位PWMn_B9H,PWMn_B8H,后写低八位CCAPnH
- //所有与PWM相关的端口,在上电后均为高阻输入态,必须在程序中将这些口设置为双向口或强推挽模式才可正常输出波形
- #include<reg51.h>
- #include<STC15W.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar ch=3;//AD转换通道3
- uint adhl1,adhl2;
- float getadv;//AD采样的最终电压值0-2.5V
- unsigned char code PWM[8]={0xff,0xe2,0xba,0x96,0x80,0x62,0x49,0x00};//设置PWM占空比数组; 当CCAP0H的值为255时,理论上占空比应该为0
- //占空比分别为0%、11.765%、27.45%、41.57%、50.20%、61.96%、71.75%、100%
- void delay1ms() //@6.000MHz
- {
- unsigned char i, j;
- i = 6;
- j = 211;
- do
- {
- while (--j);
- } while (--i);
- }
- void InitADC()//定时10个毫秒或者5个毫秒做一次ADC,根本不影响!待确定******
- {
- P1M1=0x18;
- P1M0=0x00;//设置P1_3,P1_4仅为输入模式
- P1ASF=0x18;//设置P1_3,P1_4为AD模拟口
- EA=1; EADC=1;
- ADC_RES=0;//清除结果寄存器
- ADC_RESL=0;
- ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ADC_START|ch;
- delay1ms();//延时,ADC上电稳定
- }
- void pwm_init()
- {
- CL=0x00;
- CH=0x00;
- //CR=1;//时才启动PCA定时器,CL与CCAP0L开始比较
- }
- void pwm_set(unsigned char a)
- {
- CCAP0L= a; //设置值直接写入CCAP0L
- CCAP0H= a; //设置值直接写入CCAP0H
- CR=1;//计数器阵列运行控制位
- }
- void adc_it() interrupt 5
- {
- ADC_CONTR&=!ADC_FLAG;
- if(ch==3) adhl1=(ADC_RES*4+ADC_RESL);//读取10位通道3的AD转换结果
- else
- adhl2=(ADC_RES*4+ADC_RESL);//读取10位通道4的AD转换结果
- ch++;
- if(ch>=5) ch=3;
- ADC_RES=0;ADC_RESL=0;
- ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ADC_START|ch;
- }
- void main()
- {
- InitADC();
- pwm_init();
- P1M1&=0xfd;
- P1M0|=0x02;//PWM的P1_1为推免输出
- CMOD=0x00; //PCA计数脉冲源12分频,无中断使能
- CCAPM0=0x42;//使能PCA的PWM模式,PWM0设置PCA工作方式为PWM方式,无PCA中断
- PCA_PWM0=0x00;//PCA模块0的PWM工作于8位PWM, 与CCAP0L组成的EPC0L设置为0,EPC0H为0
- //AUXR1=0x00; //CCP默认在P12,P11,P10,P37脚
- //pwm_set(0xff);//设置PWM占空比为0,全低电平。NMOS管不导通
- while(1)
- {
- getadv=2.5*adhl2*0.5/adhl1; //*0.5软件处理把采样电压减半为满电压时2.5V;仿真时上来就是getadv=0xffff?
- delay1ms();
- if(0<=getadv<0.3)//无法使用switch(ADget)
- {
- pwm_init();
- pwm_set(PWM[0]);//设置PWM占空比为0,全低电平,NMOS管不导通。或者这样设置PWM全低电平:pwm_set(PWM[0]);PCA_PWM0|=0x02;
- //需不需要delay();
- }
- if(0.3<=getadv<0.6)
- {
- pwm_init();
- pwm_set(PWM[1]);
- //需不需要delay();
- }
- if(0.6<=getadv<0.9)
- {
- pwm_init();
- pwm_set(PWM[2]);
- }
- if(0.9<=getadv<1.2)//仿真时上来就是getadv=0xff或者-1?
- {
- pwm_init();
- pwm_set(PWM[3]);
- }
- if(1.2<=getadv<1.5)
- {
- pwm_init();
- pwm_set(PWM[4]);
- }
- if(1.5<=getadv<1.8)
- {
- pwm_init();
- pwm_set(PWM[5]);
- }
- if(1.8<=getadv<2.1)
- {
- pwm_init();
- pwm_set(PWM[6]);
- }
- if(2.1<=getadv<=2.5)
- {
- pwm_init();
- pwm_set(PWM[7]);
- }
- }
- }
不知道你是如何就确定已经执行了if语句?
“理论上应该是getadv=0的“,变量都没初始化,你如何确定是0?
所有变量要初始化
另外if判断一般是整数判断
把getadv=2.5*adhl2*0.5/adhl1; //*0.5软件处理把采样电压减半为满电压时2.5V;仿真时
改为getadv=5.0*adhl2*0.5/adhl1; //*0.5软件处理把采样电压减半为满电压时2.5V;仿真时
再把getadv放大10倍或100倍,以去除小数点,把其变为整数,再用if判断!
我又把这些变量都初始化了,,但是程序运行仿真到if(x<getadv<y)函数时,,还是不行。它会执行所有的if(){;;;;}函数里的语句,,if(getadv>=0||getadv<3)应该是这样判断的,,当我改成这样的时候,,它还是会执行所有的if(){;;;;}函数里的语句?咋回事?
求指教
你的运行状态是不是正好相反,应该快但却是慢的,应该慢但却是快的?
亲,我习惯用串口调试。每个IF里发送到串口调试助手不同的数字,这样判断这是否程序执行正确
另外,AD采集,你可以先用官方提供的代码跑一遍
还有我一般不在keil仿真,直接下板子进行测试
问题已经解决了,,原来是我if函数里的逻辑判断搞错了,,接下来等待下到板子里再调试吧、、谢谢你的解答
不明白,,,说的是什么意思
等板子弄好了,,下进去跑跑,,试一下。谢谢了
大神,,有没有用过U8W-mini下载器给STC冲程。我一直都充不进!不知道怎么回事
可以看看《STC烧录工具说明》