完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛
|
收藏起来慢慢品味一番
|
|
|
|
|
|
|
|
|
鸿哥v587
![]()
|
|
|
|
|
|
|
|
|
很厉害!能做到这样,已经有一定造诣。
|
|
|
|
|
|
|
|
|
四五月份来的时候看过一次您的帖子,今天偶然想起这个论坛,来了以后又看见您的帖子,看到您更新了这么多,首先对您的持之以恒表示敬意~马克~
|
|
|
|
|
|
|
|
|
本帖最后由 dubeixian 于 2013-9-2 23:10 编辑
鸿哥您好,我看了你的按键扫描程序,感觉思路很清晰,容易看懂,请问下如果是4*4的键盘的话你还是一次扫描2个按键吗?那switch case 里面一共就有24个case吧, 我的另一种思路是一次扫描4个按键,这样有12个case语句。 不知鸿哥会选择哪种方式呢? 我把鸿哥的按键行列扫描与蜂鸣器转为51单片机4*4扫描的,扫描用24个case语句,该程序适用于于郭天祥51单片机,已测试通过 第二节的独立键盘也移植到51单片机成功,同样适用于郭天祥51单片机学习板。 努力把鸿哥的风格学会~~顶顶鸿哥 |
|
|
|
|
|
|
|
|
我也做了个51平台的移植:https://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=288846&pid=2210942&fromuid=1174554 适用于郭天祥51单片机学习板并测试通过,要好好学习鸿哥的风格,恩恩。 |
|
|
|
|
|
|
|
|
没错,如果是4*4的键盘的话,则一次扫描4个按键,你很聪明,很有天赋,继续努力。 |
|
|
|
|
|
|
|
|
第四十九节:单片机中的战斗机switch---利用定时中断实现跑马灯
开场白: Switch语句是单片机中的战斗机,是整个程序的灵魂,这句话一点都不夸张。我们只要以Switch语句为支点,再复杂再繁琐的程序都可以轻松地编写出来。 在鸿哥的编程体系中,Switch括号里面的全局变量就是最核心的变量,鸿哥把它定义为步骤变量,后缀统一用_step命名。我们只要根据实际情况灵活控制步骤变量,就可 以演绎出无穷的单片机程序。接下来,我将会专门花几个章节来讲switch语句的实战用法。 (1) 功能需求: 让8个LED灯循环依次点亮,同一时刻只有一个LED灯点亮。 (2) 硬件原理: 利用单片机的8个IO口引脚分别连接到8个LED灯的负极,8个LED的正极分别串接一个510欧的电阻,电阻的另一端都连接到电源VCC上。一般来说,单片机IO口的灌电流比输出的驱动 电流要大,所以驱动LED灯的时候,我喜欢用IO口接LED灯的负极,正极经过限流电阻后直接连VCC。 (3) 源码适合的单片机: PIC16F73,晶振为3.579545MHz。 (4)单片机的C语言源代码讲解: #include //补充说明:吴坚鸿程序风格是这样的,凡是输出IO后缀都是_dr,凡是输入的IO后缀都是_sr #define led_dr1 RC0 //控制发光二极管 #define led_dr2 RC1 //控制发光二极管 #define led_dr3 RC2 //控制发光二极管 #define led_dr4 RC3 //控制发光二极管 #define led_dr5 RC4 //控制发光二极管 #define led_dr6 RC5 //控制发光二极管 #define led_dr7 RC6 //控制发光二极管 #define led_dr8 RC7 //控制发光二极管 #define const_led_on_time 1000 //控制led灯的亮的时间长短,这个数值读者根据实际情况改动,我没验证过这个大小 unsigned long led_cnt=0; //延时计数器 unsigned char run_step=0; //这就是鸿哥传说中的步骤变量,单片机程序的核心 main() //主程序 { ADCON0=0x41; //设置AD模式 ADCON1=0x04; //RA0作为AD输入通道,本程序中没有用到AD,不用管它 TRISC=0x00; //LED灯的IO口设置成输出 led_dr1=1; //初始化,全部LED灯都灭 led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=1; T1CON=0x24; //定时中断配置 TMR1H=0xFE; TMR1L=0xEF; INTCON=0xC0; TMR1IF=0; TMR1IE=1; PEIE=1; //外围中断允许 GIE=1; //开总中断 TMR1ON=1; //启动定时器中断 while(1) { CLRWDT(); //喂单片机内部自带的看门狗,大家可以不管它 switch(run_step) { case 0: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=0; //第1个LED灯被点亮 led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=1; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 1: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=0; //第2个LED灯被点亮 led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=2; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 2: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=0; //第3个LED灯被点亮 led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=3; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 3: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=1; led_dr4=0; //第4个LED灯被点亮 led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=4; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 4: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=0; //第5个LED灯被点亮 led_dr6=1; led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=5; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 5: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=0; //第6个LED灯被点亮 led_dr7=1; led_dr8=1; led_cnt=0; //延时计数器清零 run_step=6; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 6: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=0; //第7个LED灯被点亮 led_dr8=1; led_cnt=0; //延时计数器清零 run_step=7; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 7: if(led_cnt>const_led_on_time) //LED灯亮的延时时间 { led_dr1=1; led_dr2=1; led_dr3=1; led_dr4=1; led_dr5=1; led_dr6=1; led_dr7=1; led_dr8=0; //第8个LED灯被点亮 led_cnt=0; //延时计数器清零 run_step=0; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; } } } void interrupt timer1rbint(void) //中断程序入口 { if(TMR1IE==1&&TMR1IF==1) //定时中断程序 { TMR1IF=0; TMR1ON=0; if(led_cnt<0xffffffff) //不要超过最大long类型范围 { led_cnt++; //延时计数器 } TMR1H=0xFF; TMR1L=0xC8; TMR1ON=1; } } (5)下集预告: 单片机中的战斗机switch---多任务并行处理两路独立的跑马灯。 (未完待续,下节更精彩,不要走开哦!) |
|
|
|
|
|
|
|
|
第五十节:单片机中的战斗机switch---多任务并行处理两路独立的跑马灯
开场白: Switch语句是单片机中的战斗机,是整个程序的灵魂,这句话一点都不夸张。我们只要以Switch语句为支点,再复杂再繁琐的程序都可以轻松地编写出来。 在鸿哥的编程体系中,Switch括号里面的全局变量就是最核心的变量,鸿哥把它定义为步骤变量,后缀统一用_step命名。我们只要根据实际情况灵活控制步骤变量,就可以演绎出无穷的单片机程序。接下来,我将会专门花几个章节来讲switch语句的实战用法。 (1) 功能需求: 两路独立并行处理的跑马灯,实现多任务并行处理编程。 第一路跑马灯:让8个LED灯正向循环依次点亮,同一时刻只有一个LED灯点亮,速度相对比较快点。 第二路跑马灯:让8个LED灯反向循环依次点亮,同一时刻只有一个LED灯点亮,速度相对比较慢点。 (2) 硬件原理: 利用单片机的16个IO口引脚分别连接到16个LED灯的负极,16个LED的正极分别串接一个510欧的电阻,电阻的另一端都连接到电源VCC上。一般来说,单片机IO口的灌电流比 输出的驱动电流要大,所以驱动LED灯的时候,我喜欢用IO口接LED灯的负极,正极经过限流电阻后直接连VCC。 (3) 源码适合的单片机: PIC16F73,晶振为3.579545MHz。 (4)单片机的C语言源代码讲解: #include //补充说明:吴坚鸿程序风格是这样的,凡是输出IO后缀都是_dr,凡是输入的IO后缀都是_sr //第1路正向跑马灯 #define one_led_dr1 RC0 //控制发光二极管 #define one_led_dr2 RC1 //控制发光二极管 #define one_led_dr3 RC2 //控制发光二极管 #define one_led_dr4 RC3 //控制发光二极管 #define one_led_dr5 RC4 //控制发光二极管 #define one_led_dr6 RC5 //控制发光二极管 #define one_led_dr7 RC6 //控制发光二极管 #define one_led_dr8 RC7 //控制发光二极管 //第2路反向跑马灯 #define two_led_dr1 RB0 //控制发光二极管 #define two_led_dr2 RB1 //控制发光二极管 #define two_led_dr3 RB2 //控制发光二极管 #define two_led_dr4 RB3 //控制发光二极管 #define two_led_dr5 RB4 //控制发光二极管 #define two_led_dr6 RB5 //控制发光二极管 #define two_led_dr7 RB6 //控制发光二极管 #define two_led_dr8 RB7 //控制发光二极管 #define const_one_led_on_time 1000 //第1路控制led灯的亮的时间长短,相对快点,这个数值读者根据实际情况改动,我没验证过这个大小 #define const_two_led_on_time 2000 //第2路控制led灯的亮的时间长短,相对慢点,这个数值读者根据实际情况改动,我没验证过这个大小 void one_led_run(); //第1路正向跑马灯,相对快点 void two_led_run(); //第2路反向跑马灯,相对慢点 unsigned long one_led_cnt=0; //第1路延时计数器 unsigned long two_led_cnt=0; //第2路延时计数器 unsigned char one_run_step=0; //第1路步骤变量,这就是鸿哥传说中的步骤变量,单片机程序的核心 unsigned char two_run_step=0; //第1路步骤变量,这就是鸿哥传说中的步骤变量,单片机程序的核心 main() //主程序 { ADCON0=0x41; //设置AD模式 ADCON1=0x04; //RA0作为AD输入通道,本程序中没有用到AD,不用管它 TRISC=0x00; //第1路LED灯的IO口设置成输出 TRISB=0x00; //第2路LED灯的IO口设置成输出 one_led_dr1=1; //初始化,全部LED灯都灭 one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; two_led_dr1=1; //初始化,全部LED灯都灭 two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; T1CON=0x24; //定时中断配置 TMR1H=0xFE; TMR1L=0xEF; INTCON=0xC0; TMR1IF=0; TMR1IE=1; PEIE=1; //外围中断允许 GIE=1; //开总中断 TMR1ON=1; //启动定时器中断 while(1) { CLRWDT(); //喂单片机内部自带的看门狗,大家可以不管它 one_led_run(); //第1路正向跑马灯,相对快点 two_led_run(); //第2路反向跑马灯,相对慢点 } } void one_led_run() //第1路正向跑马灯,相对快点 { switch(one_run_step) { case 0: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=0; //第1个LED灯被点亮 one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=1; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 1: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=0; //第2个LED灯被点亮 one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=2; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 2: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=0; //第3个LED灯被点亮 one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=3; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 3: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=1; one_led_dr4=0; //第4个LED灯被点亮 one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=4; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 4: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=0; //第5个LED灯被点亮 one_led_dr6=1; one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=5; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 5: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=0; //第6个LED灯被点亮 one_led_dr7=1; one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=6; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 6: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=0; //第7个LED灯被点亮 one_led_dr8=1; one_led_cnt=0; //延时计数器清零 one_run_step=7; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 7: if(one_led_cnt>const_one_led_on_time) //LED灯亮的延时时间 { one_led_dr1=1; one_led_dr2=1; one_led_dr3=1; one_led_dr4=1; one_led_dr5=1; one_led_dr6=1; one_led_dr7=1; one_led_dr8=0; //第8个LED灯被点亮 one_led_cnt=0; //延时计数器清零 one_run_step=0; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; } } void two_led_run() //第2路反向跑马灯,相对慢点 { switch(two_run_step) { case 0: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=0; //第8个LED灯被点亮 two_led_cnt=0; //延时计数器清零 two_run_step=1; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 1: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=0; //第7个LED灯被点亮 two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=2; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 2: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=0; //第6个LED灯被点亮 two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=3; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 3: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=0; //第5个LED灯被点亮 two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=4; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 4: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=1; two_led_dr4=0; //第4个LED灯被点亮 two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=5; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 5: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=1; two_led_dr3=0; //第3个LED灯被点亮 two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=6; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 6: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=1; two_led_dr2=0; //第2个LED灯被点亮 two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=7; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; case 7: if(two_led_cnt>const_two_led_on_time) //LED灯亮的延时时间 { two_led_dr1=0; //第1个LED灯被点亮 two_led_dr2=1; two_led_dr3=1; two_led_dr4=1; two_led_dr5=1; two_led_dr6=1; two_led_dr7=1; two_led_dr8=1; two_led_cnt=0; //延时计数器清零 two_run_step=0; //这就是鸿哥传说中的怎样灵活控制步骤变量 } break; } } void interrupt timer1rbint(void) //中断程序入口 { if(TMR1IE==1&&TMR1IF==1) //定时中断程序 { TMR1IF=0; TMR1ON=0; if(one_led_cnt<0xffffffff) //不要超过最大long类型范围 { one_led_cnt++; //第1路延时计数器 } if(two_led_cnt<0xffffffff) //不要超过最大long类型范围 { two_led_cnt++; //第2路延时计数器 } TMR1H=0xFF; TMR1L=0xC8; TMR1ON=1; } } (5)下集预告: 单片机中的战斗机switch---按键设置跑马灯的速度。 (未完待续,下节更精彩,不要走开哦!) |
|
|
|
|
|
|
|
|
谢谢鸿哥的夸奖,把鸿哥的风格都弄懂了然后灵活运用才是王道啊。再次感谢鸿哥的无私分享 |
|
|
|
|
|
|
|
|
鸿哥你好,我看到第六节单串口通信,
SYNC = 0 BRGH = 0 BRG16 =0 应该是8位异步,该模式下波特率 = foc/(64*(n+1)) n = spbrgh/spbrg = 0 , 这样我算出来的波特率 = 22.1184*1000000/64 = 345600 = 3*115200, 是不是spbrgh 应该是2,spbrg改为1才对呢 |
|
|
|
|
|
|
|
dubeixian 发表于 2013-9-4 09:12 这个我也忘了,我不想深入研究这类问题。如果你对这类问题感兴趣的话,你可以自己搭电路试试。 |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
求解外围电路实现的是4脚给持续低电平复位并正常工作,高电平不工作的原因
2382 浏览 1 评论
4241 浏览 3 评论
PIC1946程序有一个变量在运行过程中恢复初始值其他变量保持不变
2619 浏览 2 评论
3118 浏览 0 评论
PIC16F1825的RC5引脚,在主程序中操作无效,在中断中可以改变是为什么?
4577 浏览 5 评论
有套STM32与西门子200程序需要代写,有兴趣的工程师与有联系!
2489浏览 1评论
用XC8编译PIC18F25K80时提示下面Error,求怎么解决这个问题
6799浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-15 15:00 , Processed in 1.186782 second(s), Total 83, Slave 73 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖