找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1627|回复: 18
收起左侧

单片机3P口24LED跑马灯程序求助

[复制链接]
ID:471297 发表于 2021-12-21 13:10 | 显示全部楼层 |阅读模式
50黑币
3P口24LED跑马灯程序求助。目前P0和P1口正常,请教增加P2口程序怎么修改呢?还有通电时不要让LED全部亮要怎么修改呢?
效果:
3P口跑马灯.gif

单片机程序:
  1. #include <REG52.H>

  2. unsigned char RunMode;
  3. //**********************************System Fuction*************************************************
  4. void Delay1ms(unsigned int count)
  5. {
  6.         unsigned int i,j;
  7.         for(i=0;i<count;i++)
  8.         for(j=0;j<120;j++);
  9. }


  10. unsigned char GetKey(void)
  11. {
  12.         unsigned char KeyTemp,CheckValue,Key = 0x00;
  13.         CheckValue = P3&0x32;
  14.         if(CheckValue==0x32)
  15.                 return 0x00;
  16.         
  17.         Delay1ms(10);  //延迟1ms(10)
  18.         KeyTemp = P3&0x32;
  19.         if(KeyTemp==CheckValue)
  20.                 return 0x00;

  21.         if(!(CheckValue&0x02))
  22.                 Key|=0x01;
  23.         if(!(CheckValue&0x10))
  24.                 Key|=0x02;
  25.         if(!(CheckValue&0x20))
  26.                 Key|=0x04;
  27.         return Key;
  28. }

  29. unsigned int TimerCount,SystemSpeed,SystemSpeedIndex;
  30. void InitialTimer2(void)
  31. {
  32.         T2CON  = 0x00;                        //16 Bit Auto-Reload Mode
  33.          TH2 = RCAP2H = 0xFC;          //重装值,初始值        TL2 = RCAP2L = 0x18;
  34.         ET2=1;                                        //定时器 2 中断允许
  35.         TR2 = 1;                                //定时器 2 启动
  36.         EA=1;
  37. }

  38. unsigned int code SpeedCode[]={   1,   2,   3,   5,   8,  10,  14,  17,  20,  30,
  39.                                                              40,  50,  60,  70,  80,  90, 100, 120, 140, 160,
  40.                                                                 180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//30
  41. void SetSpeed(unsigned char Speed)
  42. {
  43.         SystemSpeed =SpeedCode[Speed];
  44. }

  45. void LEDShow(unsigned int LEDStatus)
  46. {
  47.         P0 = ~(LEDStatus&0x00FF);
  48.         P1 = ~((LEDStatus>>8)&0x00FF);
  49.   
  50. }

  51. void InitialCPU(void)
  52. {
  53.         RunMode = 0x00;
  54.         TimerCount = 0;
  55.         SystemSpeedIndex = 10;

  56.         P1 = 0x00;
  57.         P0 = 0x00;
  58.         P2 = 0x00;
  59.         P3 = 0xFF;
  60.         Delay1ms(500);
  61.         P1 = 0xFF;
  62.         P0 = 0xFF;
  63.         P2 = 0xFF;
  64.         P3 = 0xFF;
  65.         SetSpeed(SystemSpeedIndex);
  66.         
  67. }

  68. //Mode 0
  69. unsigned int LEDIndex = 0;
  70. bit LEDDirection = 1,LEDFlag = 1;

  71. void Mode_0(void)
  72. {
  73.         if(LEDDirection)
  74.                 LEDShow(0x0001<<LEDIndex);
  75.         else
  76.                 LEDShow(0x8000>>LEDIndex);
  77.         if(LEDIndex==15)
  78.                 LEDDirection = !LEDDirection;
  79.    LEDIndex = (LEDIndex+1)%16;
  80. }

  81. void TimerEventRun(void)
  82. {
  83.         
  84.         if(RunMode ==0x00)
  85.         {
  86.                 Mode_0();
  87.         }

  88. }

  89. void Timer2(void) interrupt 5 using 3
  90. {
  91.         TF2 = 0;         //中断标志清除( Timer2 必须软件清标志!)
  92.         if(++TimerCount>=SystemSpeed)
  93.         {
  94.                 TimerCount = 0;
  95.                 TimerEventRun();
  96.            }
  97. }
  98. unsigned char MusicIndex = 0;
  99. void KeyDispose(unsigned char Key)
  100. {
  101.         
  102.         if(Key&0x02)
  103.         {
  104.                 if(SystemSpeedIndex>0)
  105.                 {
  106.                         --SystemSpeedIndex;
  107.                         SetSpeed(SystemSpeedIndex);
  108.                 }
  109.                 else
  110.                 {
  111.                         
  112.                 }
  113.         }
  114.         if(Key&0x04)
  115.         {
  116.                 if(SystemSpeedIndex<28)
  117.                 {
  118.                         ++SystemSpeedIndex;
  119.                         SetSpeed(SystemSpeedIndex);
  120.                 }
  121.                 else
  122.                 {
  123.                         
  124.                 }
  125.         }        
  126. }

  127. //***********************************************************************************
  128. main()
  129. {
  130.         unsigned char Key;
  131.         InitialCPU();
  132.         InitialTimer2();

  133.         while(1)
  134.         {
  135.                 Key = GetKey();
  136.                 if(Key!=0x00)
  137.                 {
  138.                         KeyDispose(Key);
  139.                 }
  140.         }
  141. }
复制代码



24LED流水灯仿真.rar

122.22 KB, 下载次数: 11

最佳答案

查看完整内容

如果,上面一个有问题的话,用这个: void Mode_0(void) { unsigned char temp; if(LEDDirection) { temp = (0x01 >3) == 0) P0 = ~temp; else P0 = 0xff; if((LEDIndex>>3) == 1) P1 = ~temp; else P1 = 0xff; if((LEDIndex>>3) == 2) P2 = ~temp; else P2 = 0xff; } else { temp = (0x80 >> (LEDIndex & 0x07)); if((LEDIndex>>3) == 2) P0 = ~temp; else P0 = 0xff ...
回复

使用道具 举报

ID:624769 发表于 2021-12-21 13:10 | 显示全部楼层
网络不安全 发表于 2021-12-21 20:24
求大神帮助,不要石沉大海啦

如果,上面一个有问题的话,用这个:

void Mode_0(void)
{
        unsigned char        temp;
        if(LEDDirection)
        {
                temp = (0x01 << (LEDIndex & 0x07));
                if((LEDIndex>>3) == 0)        P0 = ~temp;
                else        P0 = 0xff;
                if((LEDIndex>>3) == 1)        P1 = ~temp;
                else        P1 = 0xff;
                if((LEDIndex>>3) == 2)        P2 = ~temp;
                else        P2 = 0xff;
        }
        else
        {
                temp = (0x80 >> (LEDIndex & 0x07));
                if((LEDIndex>>3) == 2)        P0 = ~temp;
                else        P0 = 0xff;
                if((LEDIndex>>3) == 1)        P1 = ~temp;
                else        P1 = 0xff;
                if((LEDIndex>>3) == 0)        P2 = ~temp;
                else        P2 = 0xff;       
        }
           if(++LEDIndex == 24)
        {
                LEDIndex = 0;
                LEDDirection = !LEDDirection;
        }
}
回复

使用道具 举报

ID:471297 发表于 2021-12-21 15:22 | 显示全部楼层
通电不让LED全亮已解决
回复

使用道具 举报

ID:161164 发表于 2021-12-21 15:39 | 显示全部楼层
试试这样改
  1. void LEDShow(unsigned long LEDStatus)
  2. {
  3.         P0 = ~(LEDStatus&0x00FF);
  4.         P1 = ~((LEDStatus>>8)&0x00FF);
  5.         P2 = ~((LEDStatus>>16)&0x00FF);  /<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  6. }
  7. void Mode_0(void)
  8. {
  9.         if(LEDDirection)
  10.                 LEDShow(0x000001<<LEDIndex);  /<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  11.         else
  12.                 LEDShow(0x800000>>LEDIndex);  /<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  13.         if(LEDIndex==23)  /<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  14.                 LEDDirection = !LEDDirection;
  15.    LEDIndex = (LEDIndex+1)%24;  /<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  16. }
复制代码



回复

使用道具 举报

ID:471297 发表于 2021-12-21 16:27 | 显示全部楼层

您好,我按您的方法修改了,P2口LED全亮闪一下,不能往返,是不是还有地方需要修改呢?
  1. #include <REG52.H>

  2. unsigned char RunMode;
  3. //**********************************System Fuction*************************************************
  4. void Delay1ms(unsigned int count)
  5. {
  6.         unsigned int i,j;
  7.         for(i=0;i<count;i++)
  8.         for(j=0;j<120;j++);
  9. }


  10. unsigned char GetKey(void)
  11. {
  12.         unsigned char KeyTemp,CheckValue,Key = 0x00;
  13.         CheckValue = P3&0x32;
  14.         if(CheckValue==0x32)
  15.                 return 0x00;
  16.         
  17.         Delay1ms(10);  //延迟1ms(10)
  18.         KeyTemp = P3&0x32;
  19.         if(KeyTemp==CheckValue)
  20.                 return 0x00;

  21.         if(!(CheckValue&0x02))
  22.                 Key|=0x01;
  23.         if(!(CheckValue&0x10))
  24.                 Key|=0x02;
  25.         if(!(CheckValue&0x20))
  26.                 Key|=0x04;
  27.         return Key;
  28. }

  29. unsigned int TimerCount,SystemSpeed,SystemSpeedIndex;
  30. void InitialTimer2(void)
  31. {
  32.         T2CON  = 0x00;                        //16 Bit Auto-Reload Mode
  33.         TH2 = RCAP2H = 0xFC;          //重装值,初始值        TL2 = RCAP2L = 0x18;
  34.         ET2=1;                                        //定时器 2 中断允许
  35.         TR2 = 1;                                //定时器 2 启动
  36.         EA=1;
  37. }

  38. unsigned int code SpeedCode[]={   1,   2,   3,   5,   8,  10,  14,  17,  20,  30,
  39.                                                              40,  50,  60,  70,  80,  90, 100, 120, 140, 160,
  40.                                                                 180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//30
  41. void SetSpeed(unsigned char Speed)
  42. {
  43.         SystemSpeed =SpeedCode[Speed];
  44. }

  45. void LEDShow(unsigned long LEDStatus)    //修改处
  46. {
  47.         P0 = ~(LEDStatus&0x00FF);
  48.         P1 = ~((LEDStatus>>8)&0x00FF);
  49.         P2 = ~((LEDStatus>>16)&0x00FF);  //修改处
  50. }

  51. void InitialCPU(void)
  52. {
  53.         RunMode = 0x00;
  54.         TimerCount = 0;
  55.         SystemSpeedIndex = 10;

  56.         P0 = 0xFF;
  57.         P1 = 0xFF;
  58.         P2 = 0xFF;
  59.         P3 = 0xFF;
  60.         Delay1ms(500);
  61.         P0 = 0xFF;
  62.         P1 = 0xFF;
  63.         P2 = 0xFF;
  64.         P3 = 0xFF;
  65.         SetSpeed(SystemSpeedIndex);
  66.         
  67. }

  68. //Mode 0
  69. unsigned int LEDIndex = 0;
  70. bit LEDDirection = 1,LEDFlag = 1;

  71. void Mode_0(void)
  72. {
  73.         if(LEDDirection)
  74.                 LEDShow(0x000001<<LEDIndex);   //修改处
  75.         else
  76.                 LEDShow(0x800000>>LEDIndex);   //修改处
  77.         if(LEDIndex==23)                       //修改处
  78.                 LEDDirection = !LEDDirection;
  79.    LEDIndex = (LEDIndex+1)%24;                 //修改处
  80. }

  81. void TimerEventRun(void)
  82. {
  83.         
  84.         if(RunMode ==0x00)
  85.         {
  86.                 Mode_0();
  87.         }

  88. }

  89. void Timer2(void) interrupt 5 using 3
  90. {
  91.         TF2 = 0;         //中断标志清除( Timer2 必须软件清标志!)
  92.         if(++TimerCount>=SystemSpeed)
  93.         {
  94.                 TimerCount = 0;
  95.                 TimerEventRun();
  96.            }
  97. }
  98. unsigned char MusicIndex = 0;
  99. void KeyDispose(unsigned char Key)
  100. {
  101.         
  102.         if(Key&0x02)
  103.         {
  104.                 if(SystemSpeedIndex>0)
  105.                 {
  106.                         --SystemSpeedIndex;
  107.                         SetSpeed(SystemSpeedIndex);
  108.                 }
  109.                 else
  110.                 {
  111.                         
  112.                 }
  113.         }
  114.         if(Key&0x04)
  115.         {
  116.                 if(SystemSpeedIndex<28)
  117.                 {
  118.                         ++SystemSpeedIndex;
  119.                         SetSpeed(SystemSpeedIndex);
  120.                 }
  121.                 else
  122.                 {
  123.                         
  124.                 }
  125.         }        
  126. }

  127. //***********************************************************************************
  128. main()
  129. {
  130.         unsigned char Key;
  131.         InitialCPU();
  132.         InitialTimer2();

  133.         while(1)
  134.         {
  135.                 Key = GetKey();
  136.                 if(Key!=0x00)
  137.                 {
  138.                         KeyDispose(Key);
  139.                 }
  140.         }
  141. }
复制代码


回复

使用道具 举报

ID:471297 发表于 2021-12-21 20:24 | 显示全部楼层
求大神帮助,不要石沉大海啦
回复

使用道具 举报

ID:624769 发表于 2021-12-22 00:31 | 显示全部楼层
网络不安全 发表于 2021-12-21 20:24
求大神帮助,不要石沉大海啦

void LEDShow(unsigned long LEDStatus)
{
        unsigned char temp;
        temp        = LEDStatus;
        P0        = ~temp;
        temp        = LEDStatus >> 8;
        P1        = ~temp;
        temp        = LEDStatus >> 16;
        P2        = ~temp;
}

void Mode_0(void)
{
        if(LEDDirection)
                LEDShow(0x00000001<<LEDIndex);
        else
                LEDShow(0x00800000>>LEDIndex);
           if(++LEDIndex == 24)
        {
                LEDIndex = 0;
                LEDDirection = !LEDDirection;
        }
}
回复

使用道具 举报

ID:471297 发表于 2021-12-22 01:00 | 显示全部楼层
188610329 发表于 2021-12-22 00:31
void LEDShow(unsigned long LEDStatus)
{
        unsigned char temp;

您好,我按您的方法修改后,仿真效果和第一次修改的一样,灯跑到P2口就8只一起亮,然后返回不亮,可能其他地方也有错吧。附件里有仿真+程序,您方便帮我试试吗?
回复

使用道具 举报

ID:844772 发表于 2021-12-22 09:06 | 显示全部楼层
1.我这台电脑只能上网,不能测试了。
2.应该是这句问题 LEDShow(0x00000001<<LEDIndex); 它实际只传递了24位,你要是改,大致是改函数void Mode_0(void),
3.在C51你即使用强制类转换也传不过去(不知新版的是不是可以了。)   
4.建议观察void LEDShow(unsigned long LEDStatus)中temp值是否正确,最好加上&0xFF.
void Mode_0(void)
{     unsigned long LEDStatus;
        if(LEDDirection)
            {   LEDStatus=0x00000001;
                LEDStatus<<=LEDIndex;
                LEDShow(LEDStatus);
            }
        else
           {   LEDStatus=0x00800000;
               LEDStatus <<=LEDIndex;
                LEDShow(LEDStatus);
            }
           if(++LEDIndex == 24)
        {
                LEDIndex = 0;
                LEDDirection = !LEDDirection;
        }
}
回复

使用道具 举报

ID:161164 发表于 2021-12-22 12:00 | 显示全部楼层
网络不安全 发表于 2021-12-21 16:27
您好,我按您的方法修改了,P2口LED全亮闪一下,不能往返,是不是还有地方需要修改呢?

我用我的代码加上强制转换数据类型就可以了不知道为什么你的代码不行
ezgif.com-gif-maker.gif




  1. #include <STC89C5xRC.H>
  2. #define u16 unsigned int
  3. #define u8 unsigned char
  4. #define TMR_Max 1

  5. typedef struct {
  6.     u16 ACC;
  7.     u16 PRE;
  8.     u8 DN:1;
  9. } TIMER;
  10. TIMER TMR[TMR_Max];
  11. #define TMR_XX TMR[0]
  12. void Timer0Init()                //1ms@12.000MHz 12T
  13. {
  14.     TMOD &= 0xF0;                //设置定时器模式
  15.     TMOD |= 0x01;                //设置定时器模式
  16.     TL0 = 0x18;                //设置定时初始值
  17.     TH0 = 0xFC;                //设置定时初始值
  18.     TF0 = 0;                //清除TF0标志
  19.     TR0 = 1;                //定时器0开始计时
  20. }
  21. void timer0_int () interrupt 1
  22. {u8 i;
  23.     TL0 = 0x18;                //设置定时初始值
  24.     TH0 = 0xFC;                //设置定时初始值
  25.                 for(i = 0;i < TMR_Max;i++)
  26.                 {
  27.                         if(!TMR[i].DN)
  28.                         {
  29.                                 if(++TMR[i].ACC >= TMR[i].PRE)
  30.                                 {
  31.                                         TMR[i].DN = 1;
  32.                                         TMR[i].ACC= 0;
  33.                                 }
  34.                         }
  35.                 }
  36. }

  37. void LEDShow(unsigned long LEDStatus)
  38. {
  39.     P0 = ~(LEDStatus & 0x00FF);
  40.     P1 = ~((LEDStatus >> 8) & 0x00FF);
  41.     P2 = ~((LEDStatus >> 16) & 0x00FF);
  42. }
  43. //Mode 0
  44. unsigned int LEDIndex = 0;
  45. bit LEDDirection = 1, LEDFlag = 1;
  46. void Mode_0(void)
  47. {
  48.     if(LEDDirection)
  49.         LEDShow((unsigned long)0x000001 << LEDIndex); //修改处
  50.     else
  51.         LEDShow((unsigned long)0x800000 >> LEDIndex); //修改处
  52.     if(LEDIndex == 23)
  53.         LEDDirection = !LEDDirection;
  54.     LEDIndex = (LEDIndex + 1) % 24;
  55. }
  56. void main()
  57. {
  58.         Timer0Init();
  59.     ET0 = 1;                        //Timer0 interrupt Enable
  60.     EA = 1;                                //All interrupt Enable
  61.         TMR_XX.PRE = 50;
  62.        
  63.         while(1)
  64.         {
  65.                 if(TMR_XX.DN)
  66.                 {TMR_XX.DN = 0;
  67.                         Mode_0();
  68.                 }
  69.         }
  70. }
复制代码



回复

使用道具 举报

ID:332444 发表于 2021-12-22 15:34 | 显示全部楼层
既然已经解决,何必重提?
1.gif
回复

使用道具 举报

ID:471297 发表于 2021-12-23 12:20 | 显示全部楼层
lkc8210 发表于 2021-12-22 12:00
我用我的代码加上强制转换数据类型就可以了不知道为什么你的代码不行

我这个代码应该有问题吧
回复

使用道具 举报

ID:94031 发表于 2021-12-23 13:42 | 显示全部楼层
网络不安全 发表于 2021-12-23 12:20
我这个代码应该有问题吧

10楼chengxujiegoujiugengnibuyiyang
回复

使用道具 举报

ID:94031 发表于 2021-12-23 13:47 | 显示全部楼层
xuyaqi 发表于 2021-12-23 13:42
10楼chengxujiegoujiugengnibuyiyang

10楼程序结构就跟你不一样,先看懂别人程序。
回复

使用道具 举报

ID:624769 发表于 2021-12-23 15:15 | 显示全部楼层
网络不安全 发表于 2021-12-23 12:20
我这个代码应该有问题吧

应该是你仿真有问题,不支持16位以上,所以,我一共给你写了两个版本,8位和32位,但是,最后是32位的不行,8位的版本就OK了。所以,问题应该在你的仿真上,如果直接下载到单片机,应该两个都能用。
回复

使用道具 举报

ID:332444 发表于 2021-12-23 19:03 | 显示全部楼层
简单的计数判断轻松实现用不了写那么多代码,都是掩人耳目的伎俩。
回复

使用道具 举报

ID:471297 发表于 2021-12-24 10:11 | 显示全部楼层
请教CheckValue = P3&0x32;//按键接在p3.1 p3.4 p3.5这个是怎么计算得来的?
回复

使用道具 举报

ID:979299 发表于 2021-12-24 10:40 | 显示全部楼层
请教CheckValue = P3&0x32;//按键接在p3.1 p3.4 p3.5这个是怎么计算得来的?

在这里不是按位与运算,是直接取地址,0x32就是给这几个端口赋值1。程序中直接位定义不行吗
回复

使用道具 举报

ID:140489 发表于 2021-12-24 12:50 | 显示全部楼层
写两个数组就能搞定的事,不要写的那么麻烦
  1. #include <REG52.H>


  2. unsigned int code tab[]={0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F,0XFF};
  3. unsigned int code tab1[]={0X7F,0XBF,0XDF,0XEF,0XF7,0XFB,0XFD,0XFE,0XFF};
  4. //**********************************System Fuction*************************************************
  5. void Delay1ms(unsigned int count)
  6. {
  7.         unsigned int i,j;
  8.         for(i=0;i<count;i++)
  9.         for(j=0;j<120;j++);
  10. }


  11. //***********************************************************************************
  12. main()
  13. {


  14.                 unsigned char cont;
  15.         unsigned char i;

  16.     while(1)
  17.     {
  18. /////////////////////////////
  19.                 switch(cont)
  20.                 {
  21.                         case 0:         for(i=0; i<9; i++)
  22.                         {
  23.                                 P0=tab[i];
  24.                                 Delay1ms(200);
  25.                                 if(i==7)
  26.                                         cont=1;                               
  27.                         }  break;

  28.                         case 1:         for(i=0; i<9; i++)
  29.                         {
  30.                                 P2=tab[i];
  31.                                 Delay1ms(200);
  32.                                 if(i==7)
  33.                                         cont=2;                               
  34.                         }  break;

  35.                         case 2:         for(i=0; i<9; i++)
  36.                         {
  37.                                 P1=tab[i];
  38.                                 Delay1ms(200);
  39.                                 if(i==7)
  40.                                         cont=3;                               
  41.                         }  break;
  42.                         case 3:         for(i=0; i<9; i++)
  43.                         {
  44.                                 P1=tab1[i];
  45.                                 Delay1ms(200);
  46.                                 if(i==7)
  47.                                         cont=4;                               
  48.                         }  break;
  49.                         case 4:         for(i=0; i<9; i++)
  50.                         {
  51.                                 P2=tab1[i];
  52.                                 Delay1ms(200);
  53.                                 if(i==7)
  54.                                         cont=5;                               
  55.                         }  break;
  56.                         case 5:         for(i=0; i<9; i++)
  57.                         {
  58.                                 P0=tab1[i];
  59.                                 Delay1ms(200);
  60.                                 if(i==7)
  61.                                         cont=0;                               
  62.                         }  break;


  63.                         default: break;
  64.                 }
  65.         }
  66. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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