找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2552|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

基于請(qǐng)問(wèn),51單片機(jī)的數(shù)控可調(diào)穩(wěn)壓電源的程序沒(méi)有錯(cuò)誤但是仿真失敗,是哪里有問(wèn)題嗎?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
目的:用51單片機(jī)控制按鍵來(lái)增加減少占空比,達(dá)到改變占空比來(lái)改變輸出電壓并進(jìn)行ADC轉(zhuǎn)換后通過(guò)LCD1602顯示出此時(shí)輸出電壓。
問(wèn)題:1.程序編譯時(shí)沒(méi)有錯(cuò)誤,但是用proteus燒錄仿真后沒(méi)有任何反應(yīng)
                  

         2.程序里面的問(wèn)題:
         
程序如下,希望能有大佬幫忙找出程序的問(wèn)題。謝謝各位了!。。。。。。
  1. #include<reg51.h>
  2. #include<intrins.h>        //包含_nop_()函數(shù)定義的頭文件
  3. #define uint unsigned int
  4. #define uchar unsigned char


  5. uchar time;

  6. double count=20; //定義占空比,并初始占空比為26%

  7. sbit PWM=P1^7; //P2^0口輸出PWM

  8. sbit key_add=P3^4; //占空比增加的按鍵 的I/O口

  9. sbit key_dec=P3^5; //占空比減少的按鍵 的I/O口

  10. /************ADC0832端口引腳定義***************/

  11. sbit CS=P1^2;  //將CS位定義為 P1.2引腳
  12. sbit CLK=P1^0;
  13. sbit DIO=P1^1;

  14. /***********液晶端口定義**********/

  15. sbit RS=P1^5;        //寄存器選擇位
  16. sbit RW=P1^4;        //讀寫(xiě)選擇位
  17. sbit E=P1^3;        //使能信號(hào)位
  18. sbit BF=P0^7; //忙碌標(biāo)志位

  19. /**************全局變量聲明***********/

  20. unsigned char code digit[10]={"0123456789"};//定義字符數(shù)組顯示數(shù)字
  21. unsigned char code Str[]={"Volt="}; // 說(shuō)明顯示的是電壓

  22. /************函數(shù)聲明**************/

  23. void delayxms(uint z); //延時(shí)

  24. void PWM_add(); //增加占空比

  25. void PWM_dec(); //減少占空比

  26. void timer0_init(); //定時(shí)器0初始化

  27. bit BusyTest(void); //判斷液晶模塊忙碌狀態(tài)
  28. void WriteInstructuon (unsigned char dictate);//將模式設(shè)置命令或顯示地址寫(xiě)入液晶模塊
  29. void WriteAddress ( unsigned char x); //指定字符顯示的實(shí)際地址
  30. void WriteData( unsigned char y); //將數(shù)據(jù)(標(biāo)準(zhǔn)ASCII碼)寫(xiě)入液晶模塊
  31. void LcdInitiate(void);        //        LCD顯示模式初始化設(shè)置
  32. void display_volt(void);        //顯示電壓符號(hào)
  33. void display_dot(void);        //顯示電壓小數(shù)點(diǎn)
  34. void display_V(void);        //顯示電壓的單位
  35. void display1(unsigned char x);        //顯示電壓的整數(shù)部分
  36. void display2(unsigned char x);        //顯示電壓的小數(shù)部分
  37. unsigned char A_D();        //模數(shù)轉(zhuǎn)換
  38. unsigned int AD_val;                //儲(chǔ)存模數(shù)轉(zhuǎn)換后的值
  39. unsigned char Int,Dec;                //分別儲(chǔ)存轉(zhuǎn)換后的整數(shù)與小數(shù)部分

  40. /*********主函數(shù)********************/

  41. void main()

  42. {

  43. timer0_init();

  44. delayxms(5);

  45. while(1)

  46. {
  47. unsigned int AD_val;                //儲(chǔ)存模數(shù)轉(zhuǎn)換后的值
  48. unsigned char Int,Dec;                //分別儲(chǔ)存轉(zhuǎn)換后的整數(shù)與小數(shù)部分
  49.        
  50. PWM_add();

  51. PWM_dec();


  52.        
  53. LcdInitiate();                //液晶初始化
  54. delayxms(5);                //延時(shí),給硬件反應(yīng)時(shí)間
  55. display_volt();                //顯示電壓符號(hào)
  56. display_dot();                //顯示電壓的小數(shù)點(diǎn)
  57. display_V();                //顯示電壓?jiǎn)挝?br />

  58. while(1)
  59. {
  60.         AD_val=A_D();                //進(jìn)行數(shù)模轉(zhuǎn)換
  61.         Int=(AD_val)/51;                //計(jì)算整數(shù)部分
  62.         Dec=(AD_val%51)*100/51;                //小數(shù)部分計(jì)算
  63.                 display1(Int);        //顯示整數(shù)
  64.         display2(Dec);                //顯示小數(shù)
  65.         delayxms(250);
  66.                 break;
  67. }
  68.   break;
  69. }

  70. }


  71. /****************延時(shí)處理**********************/

  72. void delayxms(uint z) //延時(shí)xms程序

  73. {

  74. uint x,y;

  75. for(y=z;x>0;x--)

  76. for(y=110;y>0;y--);

  77. }



  78. void PWM_add() //電機(jī)加速

  79. {

  80. if(key_add==0)

  81. {

  82. delayxms(2); //此處時(shí)間不能太長(zhǎng),否者會(huì)的中斷產(chǎn)生沖突

  83. if(key_add==0)

  84. {

  85. count+=1; //每按一次加速按鍵占空比加1

  86. if(count>=100) //限定占空比上限

  87. {

  88. count=100;

  89. }

  90. }

  91. while(!key_add);

  92. }

  93. }


  94. void PWM_dec()//電機(jī)減速

  95. {

  96. if(key_dec==0)

  97. {

  98. delayxms(2);//此處時(shí)間不能太長(zhǎng),否者會(huì)的中斷產(chǎn)生沖突

  99. if(key_dec==0)

  100. {

  101. count-=1; //每按一次減速按鍵占空比減0.5

  102. if(count<=0) //限定占空比下限

  103. {

  104. count=0;

  105. }

  106. }

  107. while(!key_dec);

  108. }

  109. }


  110. /***********定時(shí)器0初始化***********/

  111. void timer0_init()

  112. {

  113. TMOD=0x01; //定時(shí)器0工作于方式1

  114. TH0=(65536-10)/256;

  115. TL0=(65536-10)%256;

  116. TR0=1;

  117. ET0=1;

  118. EA=1;

  119. }


  120. /**************定時(shí)0中斷處理******************/

  121. void timer0_int() interrupt 1

  122. {


  123. TR0=0; //設(shè)置定時(shí)器初值期間,關(guān)閉定時(shí)器

  124. TH0=(65536-10)/256;

  125. TL0=(65536-10)%256;

  126. TR0=1;


  127. time++;

  128. if(time<count) //count為占空比

  129. {

  130. PWM=1; //輸出高電平

  131. }

  132. else

  133. PWM=0;

  134. if(time>=100)

  135. {

  136. time=0;

  137. }

  138. }

  139. /*******************判斷液晶忙碌狀態(tài)******************/
  140. /********* result=1,忙碌;=0,不忙 *************/

  141. bit BusyTest(void)
  142. {
  143. bit result;
  144.         RS=0;                        //RS為低電平,RW為高時(shí),可以讀狀態(tài)
  145.         RW=1;
  146.         E=1;                        //=1時(shí)才允許讀寫(xiě)
  147.         _nop_();                //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)
  148.         _nop_();
  149.         _nop_();
  150.         _nop_();
  151.         result=BF;                        //忙碌標(biāo)志賦給result,將E恢復(fù)低電平
  152.         E=0;
  153.         return result;
  154. }

  155. /*************將模式設(shè)置指令或顯示地址寫(xiě)入液晶***************/

  156. void WriteInstruction (unsigned char dictate)
  157. {
  158.   while(BusyTest()==1);                //忙時(shí)等待
  159.         RS=0;
  160.         RW=0;
  161.         E=0;
  162.   _nop_();                //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)
  163.         _nop_();
  164.         P0=dictate;                        //數(shù)據(jù)送入P0,即寫(xiě)入指令或地址
  165.         _nop_();                //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)
  166.         _nop_();
  167.         _nop_();
  168.         _nop_();
  169.         E=1;                                //E置高電平
  170.         _nop_();                //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)
  171.         _nop_();
  172.         _nop_();
  173.         _nop_();
  174.         E=0;                                //E由高電平跳到低電平,液晶開(kāi)始執(zhí)行命令
  175.        
  176. }

  177. /**************指定字符顯示的實(shí)際地址************/

  178. void WriteAddress(unsigned char x)
  179. {
  180.                 WriteInstruction(x|0x80);                        //顯示位置的方法規(guī)定為80H+地址碼x
  181. }

  182. /***************將數(shù)據(jù)寫(xiě)入液晶模塊************/

  183. void WriteData(unsigned char y)
  184. {
  185.                 while(BusyTest()==1);
  186.                 RS=1;                        //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù)
  187.                 RW=0;
  188.                 E=0;                        //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖, 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0".
  189.   
  190.                 P0=y;                        //數(shù)據(jù)送入P0,即將數(shù)據(jù)寫(xiě)入液晶
  191.                 _nop_();                //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)
  192.                 _nop_();
  193.                 _nop_();
  194.                 _nop_();
  195.                 E=1;                                //E置高電平
  196.                 _nop_();                //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)
  197.                 _nop_();
  198.                 _nop_();
  199.                 _nop_();
  200.                 E=0;                                //E由高電平跳到低電平,液晶開(kāi)始執(zhí)行命令
  201.        
  202. }

  203. /************LCD顯示模式初始化*************/

  204. void LcdInitiate(void)
  205. {
  206.        
  207.                  delayxms(15);                        //首次給一個(gè)較長(zhǎng)反應(yīng)時(shí)間
  208.          WriteInstruction(0x38);                //顯模式設(shè)置,16x2顯示,5x7點(diǎn)陣,8位數(shù)據(jù)接口
  209.                  delayxms(5);
  210.          WriteInstruction(0x38);
  211.                  delayxms(5);
  212.          WriteInstruction(0x38);                        //連續(xù)三次,確保初始化成功
  213.                  delayxms(5);
  214.          WriteInstruction(0x0c);                        //顯示模式:顯示開(kāi),無(wú)光標(biāo),不閃爍
  215.                  delayxms(5);
  216.          WriteInstruction(0x06);                        //顯示模式:光標(biāo)右移,字符不移
  217.                  delayxms(5);
  218.          WriteInstruction(0x01);                        //清屏,將顯示內(nèi)容清除
  219.                 delayxms(5);
  220.          
  221. }

  222. /*********************顯示電壓符號(hào)*******************/

  223. void display_volt(void)
  224. {
  225.                 unsigned char i;
  226.          WriteAddress(0x03);                //寫(xiě)顯示地址,將在第2行第一列開(kāi)始顯示
  227.          i=0;                                //從第一個(gè)字符開(kāi)始顯示
  228.          while(Str[i]!='\0')                                        //只要沒(méi)有寫(xiě)到結(jié)束標(biāo)志就繼續(xù)寫(xiě)
  229.          {
  230.                         WriteData(Str[i]);                                        //將字符常量寫(xiě)入LCD
  231.                         i++;                                                                //指向下一個(gè)字符
  232.          }
  233. }

  234. /********************顯示電壓的小數(shù)點(diǎn)*****************/
  235. void display_dot(void)
  236. {
  237.                 WriteAddress(0x09);                                        //寫(xiě)顯示地址,將在第一行第10列開(kāi)始顯示
  238.                 WriteData('.');                                                        //將小數(shù)點(diǎn)的字符常量寫(xiě)入LCD
  239. }

  240. /*******************顯示電壓的單位*******************/

  241. void display_V(void)
  242. {
  243.                 WriteAddress(0x0c);                                //寫(xiě)顯示地址,將在第2行第13列開(kāi)始顯示
  244.                 WriteData('V');                                                        //將字符常量寫(xiě)入LCD
  245. }

  246. /**********************顯示電壓的整數(shù)部分***********************/

  247. void display1(unsigned char x)
  248. {
  249.                 WriteAddress(0x08);                                        //寫(xiě)顯示地址,將在第2行第7列開(kāi)始顯示
  250.                 WriteData(digit[x]);                                                        //將百位數(shù)字的字符常量寫(xiě)入LCD
  251. }

  252. /*******************顯示電壓的小數(shù)部分****************/

  253. void display2(unsigned char x)
  254. {
  255.                 unsigned char i,j;
  256.                 j=x/10;                                                //取小數(shù)點(diǎn)后第一位
  257.          j=x%10;                                                //取小數(shù)點(diǎn)后第二位
  258.          WriteAddress(0x0a);                                        //寫(xiě)顯示地址,將在第1行第11列開(kāi)始顯示
  259.                 WriteData(digit[i]);                                                        //將小數(shù)后的第一位數(shù)字字符常量寫(xiě)入LCD
  260.          WriteData(digit[j]);                                                        //將小數(shù)后的第二位數(shù)字字符常量寫(xiě)入LCD
  261.          
  262. }

  263. /******************模數(shù)轉(zhuǎn)換********************/

  264. unsigned char A_D()
  265. {
  266.                 unsigned char i,dat;
  267.          CS=1;                                                //一個(gè)轉(zhuǎn)換周期開(kāi)始
  268.          CLK=0;                                        //為第一個(gè)脈沖做準(zhǔn)備
  269.          CS=0;                                                //CS置0,片選有效
  270.          DIO=1;                                                //規(guī)定的起始信號(hào)
  271.          CLK=1;                                                //第一個(gè)脈沖
  272.          CLK=0;                                                //第一個(gè)脈沖的下降沿,此時(shí)DIO必須是高電平
  273.          DIO=1;                                                //通道選擇信號(hào)
  274.          CLK=1;                                                //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
  275.          CLK=0;                                                //第二個(gè)脈沖下降沿
  276.          
  277.          DIO=0;                                                //選擇通道0
  278.          CLK=1;                                                        //第三個(gè)脈沖
  279.          CLK=0;
  280.          DIO=1;                                                        //第三個(gè)脈沖下沉后DIO失去作用,置一
  281.          CLK=1;                                                        //第四個(gè)脈沖
  282.          
  283.          for(i=0;i<8;i++)
  284.          {
  285.                         CLK=1;                                        //第四個(gè)脈沖
  286.                         CLK=0;
  287.                         dat<<=1;                                //將下面儲(chǔ)存的低位數(shù)據(jù)右移
  288.                  dat|=(unsigned char)DIO;                                //將輸出數(shù)據(jù)DIO通過(guò)或運(yùn)算儲(chǔ)存在dat最低位
  289.          }
  290.          CS=1;                //片選無(wú)效
  291.          return        dat;                                        //將讀出的數(shù)據(jù)返回
  292. }
復(fù)制代碼

謝謝各位了!。。。。。!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表