关于跑马灯的问题(不简单)

tianqi911 电子工程师  2018-05-29 04:17:16

求助。问题如下,实现跑马灯,但是MCU的口是这样的。从左向右,P31 P00 P01 P02 P03 P06 P07 P34.
要求是这样的,第一下按键:P02 P03亮;然后P01 P06亮;P00 P07亮;P31 P34亮。(每一对灯依次亮,每次只有一对灯亮)
第二下按键:反向;
第三下按键:同时闪烁;
地四下按键:全灭。

高人指点,特别有2点,我很困惑解决不了,1,两个IO口拼成一个8bit的,怎么处理?
2,怎么调节灯闪烁的速度;(我试了delay,循环等方法都不好)

请高手写程序出来,我好学习,调试。非常感谢。
...全文
1375 15 点赞 打赏 收藏 举报
写回复
15 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
weixin_42841008 2018-07-31
先理解一下教程先
  • 打赏
  • 举报
回复
hhhh63 2018-07-27
最近正好做过一个走马灯的项目,用AT8B513B,8个端口,顺序走。下面是C程序

//-----------------------------------------------------------------------------
// TITLE :8PB513B TMR0 INT program
// PATTERN :0
// REVISION :1.00.000
// AUTHOR :Hu_cy
// COMPANY :Feeling-tech
// DATE :2015/05/27
// CHIP :8PB513B
// CONFIG :Fosc:IRC1M, OSCO:IOB4, WDT:Disable, OSCD:2T, IOB3OD:Enable, Other: don't care
//-----------------------------------------------------------------------------
//--------------Program Credit History-----------------------------------------
//2015/05/28 Transfer to C lange
//-----------------------------------------------------------------------------
// Pin define
// 1 IOA0 Output low
// 2 IOB7 Output low
// 3 IOB6 Output low
// 4 VDD Power
// 5 IOB5/OSCI TMR0 interrupt toggle output pin (toggle width is 1mS)
// 6 IOB4/OSCO Output low
// 7 IOB3/RSTB Output low
// 8 IOB2/T0CKI Output low
// 9 IOB1 Output low
// 10 IOB0/INT Output low
// 11 VSS Output low
// 12 IOA3 Output low
// 13 IOA2 Output low
// 14 IOA1 Output low
//--------------Include files Segment------------------------------------------
#include <8PB53B.h>

//--------------Function define segment----------------------------------------

//--------------Global or Other define segment---------------------------------
int step = 0; // 步数
int delay = 0; // 延时

//--------------Vaule segment--------------------------------------------------
// 定时计算方法,时钟1M,时钟分率2(在刻录参数中设置),定时分率2(在软件中设置)
// 计数值7(软件中设置,计算得6,可能考虑设置定时需要一定时间加1,实际计数是减1,
// 在这个数的基础上,每个计数周期加1,到256时产生中断并重新计数,设为7时计数249)
// 1M / 2 / 2 / (256-6) = 1000
#define EQ_1mS_value 0x07 //Timer 1mS delay value

//--------------Program segment------------------------------------------------
void main(void)
{
//PORTA=0x00;
PORTB=0x00;
//IOSTA=0x00;
IOSTB=0x00; //Configure Port A & B to output

PCON=0x1F; //Disable WDT, LVDT & External INT

CLRWDT(); //Recommended clear watchdog first!!(If Watchdog enabled)
OPTION=0x00; //Configure Prescal to Timer & ratio= 1:2

TMR0=EQ_1mS_value; //Set TIMER0 1mS value to count

INTEN=0x81; //Enable TMR0 & Global interrupt

while(1); //Wait timer interrupt
}

void interrupt HW_isr(void) @ HWINT_BASE
{
if(INTFLAGbits.T0IF != 1)
{
INTFLAG=0x00; //error, undefine interrupt, clean all flags
return;
}

TMR0=EQ_1mS_value;
//PORTB^=0x20; //Make interrupt toggle on IOB5 pin
INTFLAG=0xFE; //Clear T0IF Flag(Not recommed INTFLAGbits.T0IF=0;)

++delay;
switch(step)
{
// 因为IOB3和IOB4只有低电位和开路状态,没有高电位状态,所以外围电路设计成
// 低电平有效,8PB513B只有6位输出,0B00111110表示第1位有效。
case 0:
PORTB = 0B00111110; // 第1步,第1位置位
if(delay < 1000) // 延时1000ms
return;
break;

case 1:
PORTB = 0B00111101; // 第2步,第2位置位
if(delay < 2500) // 延时500ms
return;
break;

case 2:
PORTB = 0B00111011; // 第3步,第3位置位
if(delay < 1000) // 延时1000ms
return;
break;

case 3:
PORTB = 0B00110111; // 第4步,第4位置位
if(delay < 500) // 延时500ms
return;
break;

case 4:
PORTB = 0B00101111; // 第5步,第5位置位
if(delay < 1000) // 延时1000ms
return;
break;

default:
PORTB = 0B00011111; // 最后一步,第6位置位
if(delay < 500) // 延时500ms
return;
step = -1; // 置为-1,下面再加1变为0,执行第一步
break;
}
delay = 0;
step++;
}

每次延时任意定

再说楼主的项目,八个灯,两两一对,只用4个输出口,每个输出口接两个灯,另外4个口做输入键,把上面的程序改一下就行。
  • 打赏
  • 举报
回复
定时器+计数器,简单
  • 打赏
  • 举报
回复
SupermanTm 2018-07-22
查表不就完了么,别说8位,你大可以做一个16位的表,输出先把灯全部灭掉然后在用查出的值AND或OR到端口去
  • 打赏
  • 举报
回复
guanyq1 2018-07-21
这还是先好好看看入门教程再来吧
  • 打赏
  • 举报
回复
Votangroom 2018-07-02
我只能说你这个端口的位置..还是一个个定义比较好;
人家没学过状态机,你和他BBBB....
延时不行用定时器啊,51有两个定时器。状态机说的简单点就是switch case,自己好好想想怎么写吧
  • 打赏
  • 举报
回复
Mask_T 2018-06-02
控制的话也就用状态机 很简单 可以用定时器中断控制速度
  • 打赏
  • 举报
回复
zgl7903 2018-05-30
写一个状态机 很容易搞定
  • 打赏
  • 举报
回复
tianqi911 2018-05-30
@lbing7 你好,请问怎么使用枚举的方法?
  • 打赏
  • 举报
回复
tianqi911 2018-05-30
@tianxj001,端口对应测试怎么操作?能否说的具体点?另外,while 和for插入延时,确实无效,我用的这款51是自己带库的。延时都是库里的函数。但用了完全无效,一用延时,整个程序就不运行了。可能是哪里有问题?
  • 打赏
  • 举报
回复
tianxj001 2018-05-30
你这个端口排列无规则,基本上就是一个乱,简单的拆分8bit到端口是无法做到的。貌似中间p0-p3 还有点顺序,这个可以按照你描述的端口顺序,对应D6-D3 或者反过来对应D1-D4,这几个端口通过8bit 位屏蔽,直接送到P0口是可行的,其他的,还是一个一个测试一个一个端口对应操作吧,没有别的方法了。 至于跑马灯速度,基本上都是在while 或者for循环中插入延时函数来做速度调整的,肯定有效,如果你观察到无效,只能说你写的代码有问题。
  • 打赏
  • 举报
回复
tianqi911 2018-05-30
@zgl7903你好,请问怎么写?能不能写个例子。
  • 打赏
  • 举报
回复
lbing7 2018-05-29
难哦。。。几年没来,还是有直接求代码的。。。
  • 打赏
  • 举报
回复
lbing7 2018-05-29
你的io并不是在一个字节上的,非用位操作反而不见得高效,改枚举可能可读性好一些 另外,delay如果你的实现没有溢出的话,按理应该有效
  • 打赏
  • 举报
回复
相关推荐
发帖
单片机/工控
加入

2.6w+

社区成员

硬件/嵌入开发 单片机/工控
申请成为版主
帖子事件
创建了帖子
2018-05-29 04:17
社区公告
暂无公告