微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STC15W 单片机及编程的一些问题

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. #ifndef        __STC15W_H
  2. #define        __STC15W_H

  3. #define ADC_POWER        0x80
  4. #define ADC_FLAG        0x10
  5. #define ADC_START        0x08
  6. #define ADC_SPEEDHH        0x60//90T

  7. sfr P1M1=0x91;
  8. sfr P1M0=0x92;
  9. sfr P1ASF=0x9d;
  10. sfr ADC_CONTR=0xbc;
  11. sfr ADC_RES=0xbd;
  12. sfr ADC_RESL=0xbe;

  13. sfr CMOD=0xD9;
  14. sfr CCON=0xD8;
  15. sfr PCA_PWM0=0xf2;
  16. sfr CCAPM0=0xDA;
  17. sfr CL=0xE9;
  18. sfr CH=0xF9;
  19. sfr CCAP0L=0xEA;
  20. sfr CCAP0H=0xFA;
  21. sbit CR=0xDE;
  22. sbit EADC=0xad;

  23. #endif



  24. /****内部时钟6MHZ  PWM的频率为6000/12/256=1.953125KHZ 周期512us ************/
  25. //注意:在更新重装值时,必须先写高两位PWMn_B9H,PWMn_B8H,后写低八位CCAPnH
  26. //所有与PWM相关的端口,在上电后均为高阻输入态,必须在程序中将这些口设置为双向口或强推挽模式才可正常输出波形
  27. #include<reg51.h>
  28. #include<STC15W.h>
  29. #include<intrins.h>
  30. #define uchar unsigned char
  31. #define uint unsigned int
  32. uchar ch=3;//AD转换通道3
  33. uint adhl1,adhl2;
  34. float getadv;//AD采样的最终电压值0-2.5V
  35. unsigned char code PWM[8]={0xff,0xe2,0xba,0x96,0x80,0x62,0x49,0x00};//设置PWM占空比数组; 当CCAP0H的值为255时,理论上占空比应该为0
  36. //占空比分别为0%、11.765%、27.45%、41.57%、50.20%、61.96%、71.75%、100%
  37. void delay1ms()                //@6.000MHz
  38. {
  39.         unsigned char i, j;
  40.         i = 6;
  41.     j = 211;
  42.         do
  43.         {
  44.                 while (--j);
  45.         } while (--i);
  46. }

  47. void InitADC()//定时10个毫秒或者5个毫秒做一次ADC,根本不影响!待确定******
  48. {
  49.         P1M1=0x18;
  50.     P1M0=0x00;//设置P1_3,P1_4仅为输入模式
  51.         P1ASF=0x18;//设置P1_3,P1_4为AD模拟口
  52.         EA=1; EADC=1;
  53.         ADC_RES=0;//清除结果寄存器
  54.         ADC_RESL=0;
  55.         ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ADC_START|ch;
  56.         delay1ms();//延时,ADC上电稳定
  57. }
  58. void pwm_init()
  59. {        
  60.     CL=0x00;
  61.     CH=0x00;
  62.         //CR=1;//时才启动PCA定时器,CL与CCAP0L开始比较
  63. }

  64. void pwm_set(unsigned char a)
  65. {        
  66.         CCAP0L= a; //设置值直接写入CCAP0L
  67.     CCAP0H= a; //设置值直接写入CCAP0H
  68.         CR=1;//计数器阵列运行控制位
  69. }

  70. void adc_it() interrupt 5
  71. {
  72.         ADC_CONTR&=!ADC_FLAG;
  73.         if(ch==3)   adhl1=(ADC_RES*4+ADC_RESL);//读取10位通道3的AD转换结果
  74.         else
  75.         adhl2=(ADC_RES*4+ADC_RESL);//读取10位通道4的AD转换结果
  76.         ch++;
  77.         if(ch>=5) ch=3;
  78.         ADC_RES=0;ADC_RESL=0;
  79.         ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ADC_START|ch;
  80. }
  81. void main()
  82. {
  83.         InitADC();
  84.         pwm_init();
  85.         P1M1&=0xfd;
  86.         P1M0|=0x02;//PWM的P1_1为推免输出
  87.         CMOD=0x00; //PCA计数脉冲源12分频,无中断使能
  88.         CCAPM0=0x42;//使能PCA的PWM模式,PWM0设置PCA工作方式为PWM方式,无PCA中断
  89.         PCA_PWM0=0x00;//PCA模块0的PWM工作于8位PWM, 与CCAP0L组成的EPC0L设置为0,EPC0H为0
  90.         //AUXR1=0x00; //CCP默认在P12,P11,P10,P37脚
  91.         //pwm_set(0xff);//设置PWM占空比为0,全低电平。NMOS管不导通
  92.         while(1)
  93.         {
  94.                 getadv=2.5*adhl2*0.5/adhl1;        //*0.5软件处理把采样电压减半为满电压时2.5V;仿真时上来就是getadv=0xffff?
  95.                 delay1ms();
  96.                 if(0<=getadv<0.3)//无法使用switch(ADget)
  97.                 {
  98.                         pwm_init();
  99.                         pwm_set(PWM[0]);//设置PWM占空比为0,全低电平,NMOS管不导通。或者这样设置PWM全低电平:pwm_set(PWM[0]);PCA_PWM0|=0x02;
  100.                         //需不需要delay();
  101.                 }
  102.                 if(0.3<=getadv<0.6)
  103.                 {
  104.                         pwm_init();
  105.                         pwm_set(PWM[1]);
  106.                         //需不需要delay();
  107.                 }
  108.                 if(0.6<=getadv<0.9)
  109.                 {
  110.                         pwm_init();
  111.                         pwm_set(PWM[2]);
  112.                 }
  113.                 if(0.9<=getadv<1.2)//仿真时上来就是getadv=0xff或者-1?
  114.                 {
  115.                         pwm_init();
  116.                         pwm_set(PWM[3]);
  117.                 }
  118.                 if(1.2<=getadv<1.5)
  119.                 {
  120.                         pwm_init();
  121.                         pwm_set(PWM[4]);
  122.                 }
  123.                 if(1.5<=getadv<1.8)
  124.                 {
  125.                         pwm_init();
  126.                         pwm_set(PWM[5]);
  127.                 }
  128.                 if(1.8<=getadv<2.1)
  129.                 {
  130.                         pwm_init();
  131.                         pwm_set(PWM[6]);
  132.                 }
  133.                 if(2.1<=getadv<=2.5)
  134.                 {
  135.                         pwm_init();
  136.                         pwm_set(PWM[7]);
  137.                 }         
  138.         }
  139. }

复制代码



            


不知道你是如何就确定已经执行了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烧录工具说明》

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top