找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2291|回复: 4
打印 上一主题 下一主题
收起左侧

LCD1602和pwm直流电机的单片机程序问题

[复制链接]
跳转到指定楼层
楼主
//单独执行电机程序,电机可以实现案件调速,单独执行lcd显示温度(温度传感器为DS18b20)lcd屏幕也可以显示正确的温度
// 当把两个程序整合成一个程序的时候,电机不能按键调速,lcd屏幕不能正确显示温度这是怎么回事

//整合之后的程序如下
  1. #include <reg52.H>
  2. #include <intrins.H>
  3. #include <math.H>

  4. #define uchar unsigned char
  5.   #define uint unsigned int
  6.   unsigned char pwm_motor_val =0;//左右电机占空比值 取值范围0-170,0最快
  7. unsigned char pwm_t;//周期
  8. sbit led=P1^0;
  9. sbit _4IN = P3^7;//
  10. sbit key_s2 = P3^0;
  11. sbit key_s3 = P3^1;
  12. sbit dula = P2^6;
  13. sbit wela = P2^7;
  14. sbit rw = P3^6;
  15. sbit RS = P3^5;  

  16. sbit LCDEN = P3^4;

  17. void delay(unsigned int z)//毫秒级延时
  18. {
  19.         unsigned int x,y;
  20.         for(x = z; x > 0; x--)
  21.                 for(y = 114; y > 0 ; y--);
  22. }
  23. //定时器0中断
  24. void timer0() interrupt 1
  25. {
  26.         pwm_t++;
  27.         if(pwm_t == 255)
  28.         {        _4IN = 0;
  29.                 led=1;         }
  30.         if(pwm_motor_val == pwm_t)
  31.                 {_4IN = 1;        
  32.                 led=0;        }                        
  33. }

  34. void delayUs()
  35. {
  36.     _nop_();
  37. }

  38. void delayMs(uint a)
  39. {
  40.     uint i, j;
  41.     for(i = a; i > 0; i--)
  42.         for(j = 100; j > 0; j--);
  43. }


  44. void writeComm(uchar comm)
  45. {
  46.      RS = 0;   
  47.     P0 = comm;
  48.     LCDEN = 1;
  49.      delayUs();
  50.     LCDEN = 0;
  51.     delayMs(1);
  52. }

  53. //写数据:RS=1, RW=0;
  54. void writeData(uchar dat)
  55. {
  56.      RS = 1;
  57.      P0 = dat;
  58.      LCDEN = 1;
  59.     delayUs();
  60.     LCDEN = 0;
  61.     delayMs(1);
  62. }


  63. void init()
  64. {
  65.      rw = 0;
  66.      dula = wela = 0;
  67.     writeComm(0x38);
  68.    writeComm(0x0c);
  69.     writeComm(0x06);
  70.     writeComm(0x01);
  71. }

  72. void writeString(uchar * str, uchar length)
  73. {
  74.      uchar i;
  75.     for(i = 0; i < length; i++)
  76.     {
  77.          writeData(str[i]);
  78.      }
  79. }

  80. /**//*****************************DS18B20*******************************/
  81. sbit ds = P2^2;
  82. void dsInit()
  83. {

  84.     unsigned int i;  
  85.     ds = 0;
  86.     i = 100;  
  87.      while(i>0) i--;
  88.     ds = 1;   
  89.     i = 4;
  90.      while(i>0) i--;
  91. }

  92. void dsWait()
  93. {
  94.       unsigned int i;
  95.       while(ds);  
  96.       while(~ds);
  97.       i = 4;
  98.       while(i > 0) i--;
  99. }


  100. bit readBit()
  101. {
  102.     unsigned int i;
  103.     bit b;
  104.     ds = 0;
  105.     i++;   
  106.     ds = 1;
  107.    i++; i++;  
  108.     b = ds;
  109.     i = 8;
  110.     while(i>0) i--;
  111.     return b;
  112. }

  113. unsigned char readByte()
  114. {
  115.     unsigned int i;
  116.     unsigned char j, dat;
  117.    dat = 0;
  118.     for(i=0; i<8; i++)
  119.     {
  120.         j = readBit();

  121.         dat = (j << 7) | (dat >> 1);
  122.     }
  123.     return dat;
  124. }


  125. void writeByte(unsigned char dat)
  126. {
  127.     unsigned int i;
  128.     unsigned char j;
  129.     bit b;
  130.     for(j = 0; j < 8; j++)
  131.     {
  132.         b = dat & 0x01;
  133.         dat >>= 1;

  134.         if(b)   
  135.         {
  136.            ds = 0;          i++; i++;  
  137.             ds = 1;   
  138.             i = 8; while(i>0) i--;  
  139.         }
  140.         else  
  141.         {
  142.             ds = 0;
  143.           i = 8; while(i>0) i--;  
  144.             ds = 1;
  145.            i++; i++;
  146.         }
  147.    }
  148. }


  149. void sendChangeCmd()
  150. {
  151.     dsInit();   
  152.     dsWait();   
  153.     delayMs(1);   
  154.     writeByte(0xcc);
  155.     writeByte(0x44);
  156. }

  157. void sendReadCmd()
  158. {
  159.     dsInit();
  160.     dsWait();
  161.     delayMs(1);
  162.     writeByte(0xcc);
  163.     writeByte(0xbe);
  164. }


  165. int getTmpValue()
  166. {
  167.     unsigned int tmpvalue;
  168.     int value;
  169.     float t;
  170.     unsigned char low, high;
  171.     sendReadCmd();

  172.     low = readByte();
  173.     high = readByte();

  174.     tmpvalue = high;
  175.     tmpvalue <<= 8;
  176.     tmpvalue |= low;
  177.     value = tmpvalue;

  178.   \
  179.     t = value * 0.0625;
  180.     \
  181.     value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
  182.     return value;
  183. }

  184. void display(int v)
  185. {
  186.     unsigned char count;
  187.     unsigned char datas[] = {0, 0, 0, 0, 0};
  188.     unsigned int tmp = abs(v);
  189.     datas[0] = tmp / 10000;
  190.     datas[1] = tmp % 10000 / 1000;
  191.     datas[2] = tmp % 1000 / 100;
  192.     datas[3] = tmp % 100 / 10;
  193.     datas[4] = tmp % 10;
  194.     writeComm(0xc0+3);
  195.     if(v < 0)
  196.     {
  197.         writeString("- ", 2);
  198.    }
  199.     else
  200.     {
  201.        writeString("+ ", 2);
  202.     }
  203.     if(datas[0] != 0)
  204.     {
  205.         writeData('0'+datas[0]);
  206.     }
  207.     for(count = 1; count != 5; count++)
  208.     {
  209.         writeData('0'+datas[count]);
  210.         if(count == 2)
  211.         {
  212.             writeData('.');
  213.         }
  214.     }
  215. }
  216. /**//*****************************DS18B20*******************************/

  217. void main()
  218. {
  219.     uchar table[] = "  xianzaiwendu: ";
  220.     sendChangeCmd();
  221.     init();
  222.     writeComm(0x80);
  223.     writeString(table, 16);
  224.     while(1)
  225.     {
  226.         delayMs(1000); //温度转换时间需要750ms以上
  227.         writeComm(0xc0);
  228.         display(getTmpValue());
  229.         sendChangeCmd();
  230.                 TMOD |= 0x02;//8位自动重装模块
  231.         TH0 = 220;
  232.         TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ
  233.         TR0 = 1;//启动定时器0
  234.         ET0 = 1;//允许定时器0中断
  235.         EA        = 1;//总中断允许

  236.                 if(key_s3 == 0)         //S2按下LED变暗
  237.                 {
  238.                         delay(5);
  239.                         if(key_s3 == 0)
  240.                         {
  241.                                 if(pwm_motor_val < 170)
  242.                                 {
  243.                                         pwm_motor_val=pwm_motor_val+10;
  244.                                 }
  245.                         }
  246.                 }
  247.                 if(key_s2 == 0)        //S3按键LED变亮
  248.                 {
  249.                         delay(5);
  250.                         if(key_s2 == 0)
  251.                         {
  252.                                 if(pwm_motor_val > 0)
  253.                                 {
  254.                                         pwm_motor_val=pwm_motor_val-10;
  255.                                 }
  256.                         }
  257.                 }               
  258.         
  259.     }
  260. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2020-11-16 10:33 | 只看该作者
前面有 sbit dula = P2^6; sbit wela = P2^7; 长着象是数码管
后面是 uchar table[] = "  xianzaiwendu: ";... writeComm(0x80);writeString(table, 16); 看着象1602
你确定是用了两个屏并且都不显示么  
回复

使用道具 举报

板凳
ID:213173 发表于 2020-11-16 19:21 | 只看该作者
这是因为程序构架不合理造成的相互干扰所致。特别是楼主把定时器初始化语句放在主循环while(1)中,使得定时中断不能正常运行。
回复

使用道具 举报

地板
ID:728433 发表于 2020-11-19 19:56 | 只看该作者
wulin 发表于 2020-11-16 19:21
这是因为程序构架不合理造成的相互干扰所致。特别是楼主把定时器初始化语句放在主循环while(1)中,使得定时 ...

//首先谢谢您的解答
//改用DHT11温湿度传感器后,听了您的建议更改了程序
//由于我的知识储备不够出现了一下问题,电机可以调速,但是LCD屏幕还是不显示DHT11温湿度传感器的数据,希望您拨冗帮助
程序如下
  1. #include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #include <intrins.h>
  3. #include <math.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. unsigned int i;
  7. unsigned char pwm_motor_val =0;//左右电机占空比值 取值范围0-170,0最快
  8. unsigned char pwm_t;//周期
  9. sbit led=P1^0;
  10. sbit _4IN = P2^4;//
  11. sbit key_s2 = P3^0;
  12. sbit key_s3 = P3^1;        
  13. sbit RS = P3^5;   //定义端口
  14. sbit RW = P3^6;
  15. sbit EN = P3^4;
  16. sbit DU = P2^0;
  17. sbit WE = P2^1;

  18. sbit Data = P3^7;//定义数据线
  19. uchar rec_dat[15];   //用于显示的接收数据数组

  20. #define RS_CLR RS=0
  21. #define RS_SET RS=1

  22. #define RW_CLR RW=0
  23. #define RW_SET RW=1

  24. #define EN_CLR EN=0
  25. #define EN_SET EN=1

  26. #define DataPort P0
  27. void delay(unsigned int z)//毫秒级延时
  28. {
  29.         unsigned int x,y;
  30.         for(x = z; x > 0; x--)
  31.                 for(y = 114; y > 0 ; y--);
  32. }

  33. void cmg88()//关数码管,点阵函数
  34. {
  35. DU=1;  
  36. P0=0X00;
  37. DU=0;
  38. }
  39. /*------------------------------------------------
  40. uS延时函数,含有输入参数 unsigned char t,无返回值
  41. unsigned char 是定义无符号字符变量,其值的范围是
  42. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  43. 长度如下 T=tx2+5 uS
  44. ------------------------------------------------*/
  45. void DelayUs2x(unsigned char t)
  46. {   
  47. while(--t);
  48. }
  49. /*------------------------------------------------
  50. mS延时函数,含有输入参数 unsigned char t,无返回值
  51. unsigned char 是定义无符号字符变量,其值的范围是
  52. 0~255 这里使用晶振12M,精确延时请使用汇编
  53. ------------------------------------------------*/
  54. void DelayMs(unsigned char t)
  55. {
  56.      
  57. while(t--)
  58. {
  59.      //大致延时1mS
  60.      DelayUs2x(245);
  61.          DelayUs2x(245);
  62. }
  63. }
  64. /*------------------------------------------------
  65.               判忙函数
  66. ------------------------------------------------*/
  67. bit LCD_Check_Busy(void)
  68. {
  69. DataPort= 0xFF;
  70. RS_CLR;
  71. RW_SET;
  72. EN_CLR;
  73. _nop_();
  74. EN_SET;
  75. return (bit)(DataPort & 0x80);
  76. }
  77. /*------------------------------------------------
  78.               写入命令函数
  79. ------------------------------------------------*/
  80. void LCD_Write_Com(unsigned char com)
  81. {  
  82. while(LCD_Check_Busy()); //忙则等待
  83. RS_CLR;
  84. RW_CLR;
  85. EN_SET;
  86. DataPort= com;
  87. _nop_();
  88. EN_CLR;
  89. }
  90. /*------------------------------------------------
  91.               写入数据函数
  92. ------------------------------------------------*/
  93. void LCD_Write_Data(unsigned char Data)
  94. {
  95. while(LCD_Check_Busy()); //忙则等待
  96. RS_SET;
  97. RW_CLR;
  98. EN_SET;
  99. DataPort= Data;
  100. _nop_();
  101. EN_CLR;
  102. }

  103. /*------------------------------------------------
  104.                 清屏函数
  105. ------------------------------------------------*/
  106. void LCD_Clear(void)
  107. {
  108. LCD_Write_Com(0x01);
  109. DelayMs(5);
  110. }
  111. /*------------------------------------------------
  112.               写入字符串函数
  113. ------------------------------------------------*/
  114. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  115. {     
  116. if (y == 0)
  117.          {     
  118.          LCD_Write_Com(0x80 + x);     //表示第一行
  119.          }
  120. else
  121.          {      
  122.          LCD_Write_Com(0xC0 + x);      //表示第二行
  123.          }        
  124. while (*s)
  125.          {     
  126. LCD_Write_Data( *s);     
  127. s ++;     
  128.          }
  129. }
  130. /*------------------------------------------------
  131.               写入字符函数
  132. ------------------------------------------------*/
  133. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  134. {     
  135. if (y == 0)
  136.          {     
  137.          LCD_Write_Com(0x80 + x);     
  138.          }   
  139. else
  140.          {     
  141.          LCD_Write_Com(0xC0 + x);     
  142.          }        
  143. LCD_Write_Data( Data);  
  144. }
  145. /*------------------------------------------------
  146.               初始化函数
  147. ------------------------------------------------*/
  148. void LCD_Init(void)
  149. {
  150.    LCD_Write_Com(0x38);    /*显示模式设置*/
  151.    DelayMs(5);
  152.    LCD_Write_Com(0x38);
  153.    DelayMs(5);
  154.    LCD_Write_Com(0x38);
  155.    DelayMs(5);
  156.    LCD_Write_Com(0x38);  
  157.    LCD_Write_Com(0x08);    /*显示关闭*/
  158.    LCD_Write_Com(0x01);    /*显示清屏*/
  159.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  160.    DelayMs(5);
  161.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  162.    }
  163.    

  164. /*------------------------------------------------
  165.               DHT11延时函数
  166. ------------------------------------------------*/
  167. void DHT11_delay_us(uchar n)
  168. {
  169.     while(--n);
  170. }

  171. void DHT11_delay_ms(uint z)
  172. {
  173.    uint i,j;
  174.    for(i=z;i>0;i--)
  175.       for(j=110;j>0;j--);
  176. }
  177. /*------------------------------------------------
  178.               DHT11开始信号
  179. ------------------------------------------------*/
  180. void DHT11_start()
  181. {
  182.    Data=1;
  183.    DHT11_delay_us(2);
  184.    Data=0;
  185.    DHT11_delay_ms(20);   //延时18ms以上
  186.    Data=1;
  187.    DHT11_delay_us(30);
  188. }
  189. /*------------------------------------------------
  190.               接收八位二进制
  191. ------------------------------------------------*/
  192. uchar DHT11_rec_byte()      //接收一个字节
  193. {
  194.    uchar i,dat=0;
  195.   for(i=0;i<8;i++)    //从高到低依次接收8位数据
  196.    {         
  197.       while(!Data);   //等待50us低电平过去
  198.       DHT11_delay_us(8);     //延时60us,如果还为高则数据为1,否则为0
  199.       dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
  200.       if(Data==1)    //数据为1时,使dat加1来接收数据1
  201.          dat+=1;
  202.       while(Data);  //等待数据线拉低   
  203.     }  
  204.     return dat;
  205. }
  206. /*------------------------------------------------
  207.               接收40bit数据
  208. ------------------------------------------------*/
  209. void DHT11_receive()      //接收40位的数据
  210. {
  211.     uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  212.     DHT11_start();

  213.     if(Data==0)
  214.     {
  215.         
  216.         while(Data==0);   //等待拉高     
  217.                
  218.         DHT11_delay_us(40);  //拉高后延时80us
  219.         R_H=DHT11_rec_byte();    //接收湿度高八位  
  220.         R_L=DHT11_rec_byte();    //接收湿度低八位  
  221.         T_H=DHT11_rec_byte();    //接收温度高八位  
  222.         T_L=DHT11_rec_byte();    //接收温度低八位
  223.         revise=DHT11_rec_byte(); //接收校正位
  224.                         
  225.         DHT11_delay_us(25);    //结束

  226.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  227.         {
  228.             RH=R_H;
  229.             RL=R_L;
  230.             TH=T_H;
  231.             TL=T_L;
  232.         }
  233.         /*数据处理,方便显示*/
  234.         rec_dat[0]='0'+(RH/10);
  235.         rec_dat[1]='0'+(RH%10);
  236.                 rec_dat[2] =' ';
  237.                 rec_dat[3] = 'R' ;
  238.                 rec_dat[4] = 'H';
  239.         rec_dat[5]=' ';
  240.         rec_dat[6]=' ';
  241.         rec_dat[7]=' ';
  242.         rec_dat[8]=' ';
  243.         rec_dat[9]='0'+(TH/10);
  244.         rec_dat[10]='0'+(TH%10);
  245.                 rec_dat[11] =' ';
  246.                 rec_dat[12] = 'C';
  247.                 rec_dat[13] = ' ' ;
  248.         rec_dat[14]=' ';
  249.     }
  250. }
  251. void timer0() interrupt 1
  252. {        
  253.         
  254.         TH0 = 220;
  255.         TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ
  256.         pwm_t=pwm_t+1;
  257.         if(pwm_t == 255)
  258.         {        _4IN = 0;
  259.                 led=1;         }
  260.         if(pwm_motor_val == pwm_t)
  261.                 {_4IN = 1;        
  262.                 led=0;        }
  263.                                  
  264. }

  265. /*------------------------------------------------
  266.                     主函数
  267. ------------------------------------------------*/
  268. void main(void)
  269. {
  270.         uint i;
  271.         cmg88();//关数码管,点阵函数

  272.         LCD_Init();
  273.         LCD_Clear();//清屏
  274.         DHT11_delay_ms(1500);    //DHT11上电后要等待1S以越过不稳定状态在此期间不能发送任何指令
  275.         TMOD = 0x02;//8位自动重装模块
  276. //        TH0 = 220;
  277. //        TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ
  278.         EA        = 1;//总中断允许
  279.         TR0 = 1;//启动定时器0
  280.         ET0 = 1;//允许定时器0中断
  281.         while (1)
  282.          {
  283.                DHT11_receive();
  284.             
  285.          
  286.                 for(i=0;i<15;i++)
  287.                 {
  288.                            LCD_Write_Char(i,1,rec_dat[i]);
  289.                 }        
  290.                   //LCD_Write_Char(0,0,'T');
  291.                   //LCD_Write_Char(0,1,'H');
  292.                    //LCD_Write_String(0,1,"HELLO");
  293.                 if(key_s3 == 0)         //S2按下LED变暗
  294.                 {
  295.                         delay(5);
  296.                         if(key_s3 == 0)
  297.                         {
  298.                                 if(pwm_motor_val < 170)
  299.                                 {
  300.                                         pwm_motor_val=pwm_motor_val+10;
  301.                                 }
  302.                         }
  303.                 }
  304.                 if(key_s2 == 0)        //S3按键LED变亮
  305.                 {
  306.                         delay(5);
  307.                         if(key_s2 == 0)
  308.                         {
  309.                                 if(pwm_motor_val > 0)
  310.                                 {
  311.                                         pwm_motor_val=pwm_motor_val-10;
  312.                                 }
  313.                         }
  314.                 }               
  315.         
  316.          }
  317. }
复制代码

回复

使用道具 举报

5#
ID:213173 发表于 2020-11-20 10:45 | 只看该作者
1279095941 发表于 2020-11-19 19:56
//首先谢谢您的解答
//改用DHT11温湿度传感器后,听了您的建议更改了程序
//由于我的知识储备不够出现 ...

单一应用程序功能正常,多个应用程序随意组合往往会在执行时间上发生冲突。通常为了按键能及时响应运用中断,往往更加剧了冲突。为了避免这类冲突需要在时间上排序,把占时较长的连续执行的模块拆分成多个时间段分时执行。这样在主循环周期内,每个子函数都能执行到全部或部分。感觉上多个应用程序在同时执行。
给你写个示例。只用定时器控制主循环周期,4个子函数轮流执行互不干扰。

温度表 按键仿真.zip (135.35 KB, 下载次数: 5)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表