找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 672|回复: 10
收起左侧

又来麻烦大家啦,按键切换两个程序,始终没整成功,求大佬们指点,谢谢

[复制链接]
ID:1105755 发表于 2024-6-26 23:00 | 显示全部楼层 |阅读模式
又来麻烦大家啦,按键切换两个程序,始终没整成功,求大佬们指点,谢谢!
用两个按键切换disp0和disp1,两个程序都可独立运行,加上按键切换就是切换不了,请大佬指点!本人也是刚学,绕不明白啦。感谢

单片机源程序如下:
  1. #include <STC8h.H>
  2. #include <stdlib.h>                        //库文件,使用随机数发生函数

  3. typedef unsigned char uchar; //无符号字符型数据
  4. typedef unsigned int  uint;         //无符号整型数据


  5. sbit Key1=P1^6;        //按键开始
  6. sbit Key2=P1^7;        //按键停止

  7. bit flag=0;                //定时时间标志位
  8. uchar num[6];        //产生的随机数
  9. uchar num1[1];
  10. uchar num2[7];        //产生的随机数
  11. uchar num3[2];
  12. uchar cnt;                //计数变量
  13. uchar str[5]= {0xff,0xff,0xff,0xff,0xff};         //定义数组存放35个LED数据
  14. uchar str1[2]= {0xff,0xff};                                        //定义数组存放12个LED数据

  15. void Delay_Us(int i);                //延时函数
  16. void Timer_Init(void);                //定时器初始化
  17. void UART_Init(void);                //串口初始化
  18. void UART_Send(uchar dat);        //串口发送数据
  19. //主函数
  20. void disp0()
  21. {
  22.     uchar i,j,k;                        //定义变量
  23.     UART_Init();                           //串口初始化
  24.     Timer_Init();                           //定时器初始化

  25.     P7M0=0X00;P7M1=0X00;//设置P0口为准双向口状态,弱上位
  26.            P2M0=0X00;P2M1=0X00;
  27.            P4M0=0X00;P4M1=0X00;
  28.            P0M0=0X00;P0M1=0X00;
  29.     P1M0=0X00;P1M1=0X00;
  30.         P3M0=0X00;P3M1=0X00;
  31.     P6M0=0X00;P6M1=0X00;

  32.     {   //35个LED初始状态,全部熄灭
  33.         UART_Send(str[i]);
  34.     }


  35.     P0=0xff;                          //12个LED初始状态,全部熄灭
  36.     P1=0xff;
  37.         P2=0xff;                          //12个LED初始状态,全部熄灭
  38.     P3=0xff;
  39.         P4=0xff;                          //12个LED初始状态,全部熄灭
  40.     P6=0xff;
  41.         P7=0xff;



  42.     while(1)
  43.     {
  44.         if(flag)         //定时时间到
  45.         {
  46.             flag=0;         //标志位清零
  47.             /*----33抽取6个LED-----*/
  48.             for(i=0; i<5; i++)         //所有灯熄灭
  49.             {
  50.                 str[i]=0xff;
  51.             }
  52.             for(i=0; i<6; i++)
  53.             {
  54.                 k=rand()%33; //产生随机数0-32
  55.                 for(j=0; j<i ; j++)
  56.                 {
  57.                     while(num[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  58.                     {
  59.                         k=rand()%33;
  60.                     }
  61.                 }
  62.                 num[i]=k;
  63.                 str[num[i]/8]&=~(0x01<<(num[i]%8));         //将随机数转换为对应的LED数据
  64.             }
  65.              P2=str[0];                          //控制35个LED点亮
  66.              P0=str[1];
  67.                          P7=str[2];                          //控制35个LED点亮
  68.              P6=str[3];
  69.                          P1=str[4];
  70.             {
  71.                 UART_Send(str[i]);
  72.             }



  73.             /*----16抽取1个LED-----*/
  74.             str1[0]=0xff;                          //12个LED全部熄灭
  75.             str1[1]=0xff;
  76.             for(i=0; i<1; i++)
  77.             {
  78.                 k=rand()%16; //产生随机数0-15
  79.                 for(j=0; j<i ; j++)
  80.                 {
  81.                     while(num1[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  82.                     {
  83.                         k=rand()%16;
  84.                     }
  85.                 }
  86.                 num1[i]=k;
  87.                 str1[num1[i]/8]&=~(0x01<<(num1[i]%8));         //将随机数转换为对应的LED数据
  88.             }
  89.             P4=str1[0];                          //控制16个LED点亮
  90.             P3=str1[1];
  91.         }


  92.     if(Key1==0)//按键开始
  93. {
  94.   Delay_Us(500);//延时消抖
  95.    if(Key1==0)
  96. {
  97.   TR0 =!TR0;
  98. }
  99.             while(Key1==0);        //按键松手检测
  100.         }
  101.         if(Key1==0)        //按键停止
  102.         {
  103.             Delay_Us(500);        //延时消抖
  104.             if(Key1==0)
  105.             {
  106.                 TR0=0;


  107.                 /*----33抽取6个LED-----*/
  108.                 for(i=0; i<5; i++) //所有灯熄灭
  109.                 {
  110.                     str[i]=0xff;
  111.                 }
  112.                 for(i=0; i<6; i++)
  113.                 {
  114.                     k=rand()%33; //产生随机数0-32
  115.                     for(j=0; j<i ; j++)
  116.                     {
  117.                         while(num[j]==k)//如果产生的随机数与之前的相同,则重新生成
  118.                         {
  119.                             k=rand()%33;
  120.                         }
  121.                     }
  122.                     num[i]=k;
  123.                     str[num[i]/8]&=~(0x01<<(num[i]%8));        //将随机数转换为对应的LED数据
  124.                 }
  125.                 P2=str[0];                          //控制35个LED点亮
  126.                 P0=str[1];
  127.                             P7=str[2];                          //控制35个LED点亮
  128.                 P6=str[3];
  129.                             P1=str[4];
  130.                 {
  131.                     UART_Send(str[i]);
  132.                 }


  133.                 /*----16抽取1个LED-----*/
  134.                 str1[0]=0xff;                          //12个LED全部熄灭
  135.                     str1[1]=0xff;
  136.                 for(i=0; i<1; i++)
  137.                 {
  138.                     k=rand()%16; //产生随机数0-15
  139.                     for(j=0; j<i ; j++)
  140.                     {
  141.                         while(num1[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  142.                         {
  143.                             k=rand()%16;
  144.                         }
  145.                     }
  146.                     num1[i]=k;
  147.                     str1[num1[i]/8]&=~(0x01<<(num1[i]%8));         //将随机数转换为对应的LED数据
  148.                 }
  149.                 P4=str1[0];                          //控制16个LED点亮
  150.                 P3=str1[1];
  151.             }
  152.             while(Key1==0);        //按键松手检测
  153.         }
  154.     }
  155. }




  156. void disp1()
  157. {
  158.     uchar i,j,k;                        //定义变量
  159.     UART_Init();                           //串口初始化
  160.     Timer_Init();                           //定时器初始化

  161.     P7M0=0X00;P7M1=0X00;//设置P0口为准双向口状态,弱上位
  162.            P2M0=0X00;P2M1=0X00;
  163.            P4M0=0X00;P4M1=0X00;
  164.            P0M0=0X00;P0M1=0X00;
  165.     P1M0=0X00;P1M1=0X00;
  166.         P3M0=0X00;P3M1=0X00;
  167.     P6M0=0X00;P6M1=0X00;

  168.     {   //35个LED初始状态,全部熄灭
  169.         UART_Send(str[i]);
  170.     }


  171.     P0=0xff;                          //12个LED初始状态,全部熄灭
  172.     P1=0xff;
  173.         P2=0xff;                          //12个LED初始状态,全部熄灭
  174.     P3=0xff;
  175.         P4=0xff;                          //12个LED初始状态,全部熄灭
  176.     P6=0xff;
  177.         P7=0xff;



  178.     while(2)
  179.     {
  180.         if(flag)         //定时时间到
  181.         {
  182.             flag=0;         //标志位清零
  183.             /*----33抽取7个LED-----*/
  184.             for(i=0; i<5; i++)         //所有灯熄灭
  185.             {
  186.                 str[i]=0xff;
  187.             }
  188.             for(i=0; i<7; i++)
  189.             {
  190.                 k=rand()%33; //产生随机数0-32
  191.                 for(j=0; j<i ; j++)
  192.                 {
  193.                     while(num2[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  194.                     {
  195.                         k=rand()%33;
  196.                     }
  197.                 }
  198.                 num2[i]=k;
  199.                 str[num2[i]/8]&=~(0x01<<(num2[i]%8));         //将随机数转换为对应的LED数据
  200.             }
  201.              P2=str[0];                          //控制35个LED点亮
  202.              P0=str[1];
  203.                          P7=str[2];                          //控制35个LED点亮
  204.              P6=str[3];
  205.                          P1=str[4];
  206.             {
  207.                 UART_Send(str[i]);
  208.             }



  209.             /*----16抽取2个LED-----*/
  210.             str1[0]=0xff;                          //12个LED全部熄灭
  211.             str1[1]=0xff;
  212.             for(i=0; i<2; i++)
  213.             {
  214.                 k=rand()%16; //产生随机数0-15
  215.                 for(j=0; j<i ; j++)
  216.                 {
  217.                     while(num3[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  218.                     {
  219.                         k=rand()%16;
  220.                     }
  221.                 }
  222.                 num3[i]=k;
  223.                 str1[num3[i]/8]&=~(0x01<<(num3[i]%8));         //将随机数转换为对应的LED数据
  224.             }
  225.             P4=str1[0];                          //控制16个LED点亮
  226.             P3=str1[1];
  227.         }


  228.    if(Key2==0)//按键开始
  229. {
  230.   Delay_Us(500);//延时消抖
  231.    if(Key2==0)
  232. {
  233.   TR0 =!TR0;
  234. }
  235.             while(Key2==0);        //按键松手检测
  236.         }
  237.         if(Key2==0)        //按键停止
  238.         {
  239.             Delay_Us(500);        //延时消抖
  240.             if(Key2==0)
  241.             {
  242.                 TR0=0;


  243.                 /*----33抽取7个LED-----*/
  244.                 for(i=0; i<5; i++) //所有灯熄灭
  245.                 {
  246.                     str[i]=0xff;
  247.                 }
  248.                 for(i=0; i<7; i++)
  249.                 {
  250.                     k=rand()%33; //产生随机数0-32
  251.                     for(j=0; j<i ; j++)
  252.                     {
  253.                         while(num2[j]==k)//如果产生的随机数与之前的相同,则重新生成
  254.                         {
  255.                             k=rand()%33;
  256.                         }
  257.                     }
  258.                     num2[i]=k;
  259.                     str[num2[i]/8]&=~(0x01<<(num2[i]%8));        //将随机数转换为对应的LED数据
  260.                 }
  261.                 P2=str[0];                          //控制35个LED点亮
  262.                 P0=str[1];
  263.                             P7=str[2];                          //控制35个LED点亮
  264.                 P6=str[3];
  265.                             P1=str[4];
  266.                 {
  267.                     UART_Send(str[i]);
  268.                 }


  269.                 /*----16抽取2个LED-----*/
  270.                 str1[0]=0xff;                          //12个LED全部熄灭
  271.                     str1[1]=0xff;
  272.                 for(i=0; i<2; i++)
  273.                 {
  274.                     k=rand()%16; //产生随机数0-15
  275.                     for(j=0; j<i ; j++)
  276.                     {
  277.                         while(num3[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  278.                         {
  279.                             k=rand()%16;
  280.                         }
  281.                     }
  282.                     num3[i]=k;
  283.                     str1[num3[i]/8]&=~(0x01<<(num3[i]%8));         //将随机数转换为对应的LED数据
  284.                 }
  285.                 P4=str1[0];                          //控制16个LED点亮
  286.                 P3=str1[1];
  287.             }
  288.             while(Key2==0);        //按键松手检测
  289.         }
  290.     }
  291. }


  292. void main()
  293. {
  294. while(1)
  295. {
  296.          if(Key1==0)//按键开始
  297. {
  298. Delay_Us(500);//延时消抖
  299. if(Key1==0)
  300. {
  301. disp0(); //12选2
  302. }
  303. while(Key1==0);
  304.   }

  305.       if(Key2==0)//按键开始
  306. {
  307. Delay_Us(500);//延时消抖
  308. if(Key2==0)
  309. {
  310. disp1(); //12选4
  311. }
  312. while(Key2==0);
  313.   }
  314. }
  315. }




  316. //延时函数
  317. void Delay_Us(int i)
  318. {
  319.     while(i--);
  320. }
  321. //定时器初始化
  322. void Timer_Init(void)
  323. {
  324.     TMOD|=0x01; //打开定时器0,1,工作方式1。
  325.     TH0=0x3c;        //给定时器0赋初值,定时50ms
  326.     TL0=0xb0;
  327.     ET0=1;      //打开定时器0中断允许
  328.     TR0=0;                //打开定时器
  329.     PS=1;
  330.     EA=1;       //打开总中断
  331. }
  332. //串口初始化
  333. void UART_Init(void)
  334. {
  335.     SM0=0;                //串口模式0:同步移位寄存器方式
  336.     SM1=0;
  337.     TI=0;                //发送中断清零
  338. }
  339. //串口发送数据,移位寄存器模式
  340. void UART_Send(uchar dat)
  341. {

  342.     SBUF=dat;          //LED数据
  343.     while(~TI);                 //等待发送完成
  344.     TI=0;                        //标志位清零

  345. }
  346. //定时器0中断函数disp0
  347. void Timer0() interrupt 1
  348. {
  349.     TH0=0x3c;   //定时50ms
  350.     TL0=0xb0;
  351.     cnt++;                //中断计数
  352.     if(cnt==3)
  353.     {
  354.         cnt=0;
  355.         flag=1;        //标志位置1
  356.     }
  357. }
复制代码

回复

使用道具 举报

ID:1105755 发表于 2024-6-26 23:19 | 显示全部楼层
刚开始整,判断按键这个地方始终没整对,拜托大家给看看怎么改,万分感谢!
回复

使用道具 举报

ID:1109793 发表于 2024-6-27 07:37 | 显示全部楼层
水平有限,程序太长,根本看不懂。单片机还能取随机数?上电时不是都清零了吗?就算不清零,那点内存能取几个啊?
回复

使用道具 举报

ID:1121801 发表于 2024-6-27 08:13 | 显示全部楼层
给你个检验程序是否有问题的方法,你可以编写一个超级简单的两个子程序,每个子程序只一个引脚输出,这样子程序就会极大简化,这时候再加上你想实现的按键转换功能,因为程序超级简单,很容易就可以分析出来到底是按键程序问题还是延时问题等等,可以试验你的想法到底是不是可以实现的。如果按键对两个简单子程序是可以实现操控的,那么再在两个子程序上去更改,取得你想要的功能。
回复

使用道具 举报

ID:53813 发表于 2024-6-27 09:58 | 显示全部楼层
第210行,WHILE(2)是什么意思?
回复

使用道具 举报

ID:1121700 发表于 2024-6-27 10:16 | 显示全部楼层
估计是按键消抖的问题,先单独测试按键消抖程序是否正常。
回复

使用道具 举报

ID:192020 发表于 2024-6-27 10:37 | 显示全部楼层
别的不说,347行main函数已经结束了,349行后的应该会报错吧?
回复

使用道具 举报

ID:846819 发表于 2024-6-27 17:13 | 显示全部楼层
disp0()和disp1()都是无限循环的任务,while(1)没有退出语句,进入任何一个任务都不能返回。试下在两个任务的合适位置加个break看看可以不。
回复

使用道具 举报

ID:1105755 发表于 2024-6-28 09:58 | 显示全部楼层
cyi8 发表于 2024-6-27 08:13
给你个检验程序是否有问题的方法,你可以编写一个超级简单的两个子程序,每个子程序只一个引脚输出,这样子 ...

好,我试试
回复

使用道具 举报

ID:1105755 发表于 2024-6-28 09:59 | 显示全部楼层
三极管一样的人 发表于 2024-6-27 09:58
第210行,WHILE(2)是什么意思?

我是业余选手,这个是用别人的程序改的
回复

使用道具 举报

ID:1105755 发表于 2024-6-28 10:00 | 显示全部楼层
tgyd 发表于 2024-6-27 17:13
disp0()和disp1()都是无限循环的任务,while(1)没有退出语句,进入任何一个任务都不能返回。试下在两个任务 ...

我试试吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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