|
【练习】PIC 编程 - LED闪灯 (功力挑战)
[复制链接]
|
|
楼主 |
发表于 3-12-2007 04:06 PM
|
显示全部楼层
原帖由 yes1010 于 3-12-2007 11:06 AM 发表
请问有谁会用basic 或c 把port b.2 从high变low吗 ?
参考:
- #include <16F628A.h>
- #fuses INTRC_IO,NOWDT,NoPROTECT,PUT,NOBROWNOUT
- #use delay(clock=4000000)
- void main()
- {
-
- while(1)
- {
- output_high(pin_b2);
- delay_ms(500);
- output_low(pin_b2);
- delay_ms(500);
- }
- }
-
复制代码 |
|
|
|
|
|
|
|
发表于 3-12-2007 04:25 PM
|
显示全部楼层
原帖由 pic 于 1-12-2007 10:06 AM 发表
现在请大家放你们的源码了, 互相学习观摩, 看看一样的题目, 会有几种写法和做法, 这就是这个练习的精华所在了, 是由大家一起贡献的。 ...
/********************************************************************************/
/********************************************************************************/
/* */
/* File Purpose : Tutorial */
/* */
/* Source File : ledFlash1.c */
/* */
/* Description : LED1,LED2,LED3 blink ON = 500mSec, OFF = 500mSec */
/* */
/* Revision : 00 */
/* */
/* Date : 10 Nov 2007 */
/* */
/* CPU : PIC16F628A */
/* */
/* Compiler : PIC-HITECH(8.05L) */
/* */
/* Author : rothmans */
/* */
/* Personal */
/********************************************************************************/
/********************************************************************************/
#include <pic.h>
#include "ledFlash.h"
#define BLINK_1 50
unsigned char temp1=0;
void main(void)
{
hardware_initialize();
ei();
while(1)
{
if(temp1==BLINK_1)
{
PORTB ^= 0x07;
temp1=0;
}
}
}
void hardware_initialize(void)
{
PCON = 0x0B; /* OSCF = 4MHz, Not PWR ON @ BOD Reset. */
PORTA = 0xFF;
PORTB = 0x00;
CMCON = 0x07;
INTCON = 0x20; /* Enable Timer 0 Interrupt */
PIE1 = 0x00; /* Interrupt Enable Bit */
OPTION = 0x05; /* Disable PORTA Pull-up */
TRISA = 0xFF;
TRISB = 0x00;
TMR0 = 0x63;
}
static void interrupt isr(void)
{
if(T0IE && T0IF)
{
TMR0 = 0x63;
temp1++;
T0IF=0;
}
} |
|
|
|
|
|
|
|
发表于 3-12-2007 04:33 PM
|
显示全部楼层
原帖由 pic 于 1-12-2007 10:06 AM 发表
现在请大家放你们的源码了, 互相学习观摩, 看看一样的题目, 会有几种写法和做法, 这就是这个练习的精华所在了, 是由大家一起贡献的。 ...
/********************************************************************************/
/********************************************************************************/
/* */
/* File Purpose : */
/* */
/* Source File : ledFlash2.c */
/* */
/* Description : LED1 Blinking ON = 500mS : OFF = 500mS */
/* LED1 Blinking ON = 1000mS : OFF = 1000mS */
/* LED1 Blinking ON = 50mS : OFF = 50mS */
/* */
/* Revision : 00 */
/* */
/* Date : 10 Nov 2007 */
/* */
/* CPU : PIC16F628A */
/* */
/* Compiler : PIC-HITECH(8.05L) */
/* */
/* Author : rothmans */
/* */
/* Personal */
/********************************************************************************/
/********************************************************************************/
#include <pic.h>
#include "ledFlash.h"
#define BLINK_0 50 /* 500mS */
#define BLINK_1 100 /* 1000mS */
#define BLINK_2 5 /* 500mS */
unsigned char temp0=0;
unsigned char temp1=0;
unsigned char temp2=0;
void main(void)
{
hardware_initialize();
ei();
while(1)
{
if(temp0==BLINK_0)
{
PORTB_0 ^= 1;
temp0=0;
}
if(temp1==BLINK_1)
{
PORTB_1 ^= 1;
temp1=0;
}
if(temp2==BLINK_2)
{
PORTB_2 ^= 1;
temp2=0;
}
}
}
void hardware_initialize(void)
{
PCON = 0x0B; /* OSCF = 4MHz, Not PWR ON @ BOD Reset. */
PORTA = 0xFF;
PORTB = 0x00;
CMCON = 0x07;
INTCON = 0x20; /* Enable Timer 0 Interrupt */
PIE1 = 0x00; /* Interrupt Enable Bit */
OPTION = 0x05; /* Disable PORTA Pull-up */
TRISA = 0xFF;
TRISB = 0x00;
TMR0 = 0x63;
}
static void interrupt isr(void)
{
if(T0IE && T0IF)
{
TMR0 = 0x63;
temp0++;
temp1++;
temp2++;
T0IF=0;
}
}
各位高手,请给些意见与指点,或是有更好的方法。希望能得到多方面的交流。
谢谢指教。
[ 本帖最后由 rothmans 于 7-12-2007 08:50 AM 编辑 ] |
|
|
|
|
|
|
|
发表于 4-12-2007 12:13 AM
|
显示全部楼层
原帖由 chan1314 于 3-12-2007 02:31 PM 发表
加 ~ 就是 toggle.
不知道syntax , 但是大约是这样, B.2 = ~B.2;
对我就是要这个,谢谢你chan1314,还有再加pic给我参考penbrush 的program,谢谢。
我要在加油看看basic 和 c,谢谢你们,一个月后才有得上网
[ 本帖最后由 yes1010 于 4-12-2007 12:27 AM 编辑 ] |
|
|
|
|
|
|
|
发表于 6-12-2007 10:57 PM
|
显示全部楼层
第三的
//12MHz Crystal
#include <AT89X51.H>
sbit L1 =P1^0; //LED1
sbit L2 =P1^1;
sbit L3 =P1^2;
unsigned int a,b,c;
float D1,D2,D3,on1,on2,on3,t1,T2,T3;
void delay (void);
main() {
TMOD =1;
t1= 1000; //time = 1/freq (in ms)
T2= 2000;
T3= 100;
D1= 5; //duty cycle
D2= 15;
D3= 10;
on1= t1* D1*0.01; //on time in ms
on2= T2*D2*0.01;
on3= T3*D3*0.01;
a=0;
b=0;
c=0;
L1=1;
L2=1;
L3=1;
for(;;a++ &&b++&&c++){ // infinite loop
if ( a ==on1){
L1=0;}
else if (a==t1){
L1=1;
a=0;}
if ( b==on2){
L2=0;}
else if (b==T2){
L2=1;
b=0;}
if ( c ==on3){
L3=0;}
else if (c==T3){
L3=1;
c=0;}
delay ();
} }
void delay (void){ //1ms delay
TH0=0xfc;
TL0=0x18;
TR0=1;
while (!TF0);
TF0=0;
TR0=0;
}
http://files-upload.com/files/662711/LED%20blink%20ah%20blink.hex |
评分
-
查看全部评分
|
|
|
|
|
|
|
楼主 |
发表于 12-12-2007 08:52 AM
|
显示全部楼层
原帖由 chan1314 于 6-12-2007 10:57 PM 发表
第三的
timing out 了许多, 但基本概念有在。再接再厉。。 |
|
|
|
|
|
|
|
楼主 |
发表于 12-12-2007 08:56 AM
|
显示全部楼层
|
|
|
|
|
|
|
楼主 |
发表于 12-12-2007 09:38 AM
|
显示全部楼层
原帖由 rothmans 于 3-12-2007 04:33 PM 发表
各位高手,请给些意见与指点,或是有更好的方法。希望能得到多方面的交流。
首先, 我也没有很厉害, 只是交流。。。其实也没资格做评判之类的。。。
其实, 在这么多的作品里, Rothmans 的是最完美, timing最准确的。。。
但我个人比较喜欢fritlizt的方法, 他是给Solution, 不是解决Problem。
他做出了一个“Task”, 只要把parameter输入, 就能做到要的效果, 可以随意增加LED, 改变timing。
再来就是, 我不知道你们花了多少时间来做, 还有就是, 在闪灯的时候, MCU还有“空”去作其他的事吗?用Interrupt drive的就可能没问题。。。
我看在这个练习里, Jason 和 Penbrush 的受益最大, Jason 才知道自己的不足, 才发现如何实现简单的“多工”,penbrush也是,还要多练习。
不知Jason 很penbrush 会花很多时间在这个练习吗?花了多少时间?
Chan1314也很强, 他可能没有很多的MCU编程经验, 可是有很强的逻辑思考, 是好的开始。
到目前为止, 我还没有看过PICBasic的, 还有CCS C的其他方法, 可能有空我会帖出来, 让大家看看原来还有其他的方法。 |
|
|
|
|
|
|
|
发表于 12-12-2007 11:35 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 13-12-2007 12:21 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 13-12-2007 09:48 AM
|
显示全部楼层
原帖由 chan1314 于 13-12-2007 12:21 AM 发表
其实。。。
我刚刚会用 timer, 也是参考frizith 的。。。
timer interrupt 前几天才教, 然后都是 concept 的。在 C 不会写。。。frizith 用 dallas , timer interrupt 那个part 我看不明白, refer 取得 ...
keil 本身有user manual.读完那本user manual,你就很强的了。 他的manual里面有很complete的guide.
其实为什么会用到jump呢??在c 里面, 最好不要用goto ,有时会导致stack有问题。
interrupt方面在keil里面全部都是一种写法. void [your function name] (void) interrupt [interrupt vector number]
example: void T2ISR (void) interrupt 5
interrupt vector number就要refer manual,我也忘了。
0 = external interrupt 0
1 = timer 0 interrupt
2 = external interrupt 1
3 = timer 1 interrupt
4 = serial port interrupt
在普通的8051 通常只有这些。
5 = timer 2 interrupt
这个是有timer2的8051/8052才有。 |
|
|
|
|
|
|
|
发表于 13-12-2007 02:38 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 13-12-2007 03:15 PM
|
显示全部楼层
原帖由 rothmans 于 13-12-2007 02:38 PM 发表
感谢楼主费尽心思,花了这么长时间详细的分析各个程序的优良点。我也参考了 fritlizt 的程序,有些地方无法参透,能否解释下。
你的程序是从 main() 开始执行,请看下图。
http://aycu35.webshots. ...
其实我不太懂你的问题。你是不是要问我的led blinking 3过后是一个delay.
不过我的led1,2,3要怎样continue blinking? |
|
|
|
|
|
|
|
发表于 13-12-2007 03:35 PM
|
显示全部楼层
原帖由 fritlizt 于 13-12-2007 03:15 PM 发表
其实我不太懂你的问题。你是不是要问我的led blinking 3过后是一个delay.
不过我的led1,2,3要怎样continue blinking?
fritlizt 请看回我贴的那个图,因为之前有些字无法显示。
其实我的问题是:
LedBlinking(1,亮 500mS, 暗 500mS)
LedBlinking(2,亮 1000mS, 暗 1000mS)
LedBlinking(3,亮 50mS, 暗 50mS)
根据程序应该是 LedBlinking(1,亮 500mS, 暗 500mS)这个 function 先执行,你是怎样让 LedBlinking(3,亮 50mS, 暗 50mS)这个 function 执行先的呢?
[ 本帖最后由 rothmans 于 13-12-2007 03:42 PM 编辑 ] |
|
|
|
|
|
|
|
发表于 13-12-2007 03:58 PM
|
显示全部楼层
原帖由 rothmans 于 13-12-2007 03:35 PM 发表
fritlizt 请看回我贴的那个图,因为之前有些字无法显示。
其实我的问题是:
LedBlinking(1,亮 500mS, 暗 500mS)
LedBlinking(2,亮 1000mS, 暗 1000mS)
LedBlinking(3,亮 50mS, 暗 50mS)
根 ...
没有啊。。。
我的program还是execute ledblinking 1先, 接下来led blinking2在接下来led blinking3.
而不是led blinking3才led blinking 1.
|
|
|
|
|
|
|
|
发表于 13-12-2007 04:20 PM
|
显示全部楼层
原帖由 fritlizt 于 13-12-2007 03:58 PM 发表
没有啊。。。
我的program还是execute ledblinking 1先, 接下来led blinking2在接下来led blinking3.
而不是led blinking3才led blinking 1.
你不是需要先让 LedBlinking(3,亮 50mS, 暗 50mS)先闪烁 10次,LedBlinking(1,亮 500mS, 暗 500mS)才闪烁一次吗。
如果依你的方法是怎样完成这个要求的呢?太神奇了,也太不可思意了。
[ 本帖最后由 rothmans 于 14-12-2007 10:48 AM 编辑 ] |
|
|
|
|
|
|
|
发表于 13-12-2007 05:01 PM
|
显示全部楼层
原帖由 rothmans 于 13-12-2007 04:20 PM 发表
你不是需要先让 LedBlinking(3,亮 50mS, 暗 50mS)先闪烁 10次,LedBlinking(1,亮 500mS, 暗 500mS)才闪烁一次吗。
如果依你的方法是怎样完成这个要求的呢?太神奇了,也太不可思意了。
http://plan ...
我的方法很神奇的。。哈哈。
没有啦。。。
其实main program只是拿来set parameters,简单来讲我在main program 设定led 要怎样闪烁。
然后timer interrupt就会读取parameters和base on那些parameters决定闪烁的时间。
blinking led是interrupt blink,不是main program blink的。
timer interrupt会在每1ms interupt一次。
这个方法我是拿来generate pwm用的。
以前是generate 8 channels pwm ,50hz, precision 1%都还可以handle到。 |
|
|
|
|
|
|
|
发表于 13-12-2007 05:30 PM
|
显示全部楼层
原帖由 rothmans 于 13-12-2007 02:38 PM 发表
感谢楼主费尽心思,花了这么长时间详细的分析各个程序的优良点。我也参考了 fritlizt 的程序,有些地方无法参透,能否解释下。
你的程序是从 main() 开始执行,请看下图。
http://aycu27.webshots. ...
猜猜罢了。
他是用 timer 2 interrupt.
main program,
set led 123 的时间, 然后就 wait nothing 10 second.
但是 timer interrupt 还是照走, 就是每1 ms interrupt 一次 ( 原来我们的东西差不多一样, 菜鸟和老鸟的分别)
interrupt 一次, counter 就加一。
十秒之后, 那么value 就换了另一个value , 然后继续wait do nothing 10seconds.
到最后 while (1) 那里, 就 halt.
不对大大力shoot ,今天学到 timer2 interrupt 所以才乱水一点点 |
|
|
|
|
|
|
|
发表于 13-12-2007 05:36 PM
|
显示全部楼层
原帖由 chan1314 于 13-12-2007 05:30 PM 发表
猜猜罢了。
他是用 timer 2 interrupt.
main program,
set led 123 的时间, 然后就 wait nothing 10 second.
但是 timer interrupt 还是照走, 就是每1 ms interrupt 一次 ( 原来我们的东西差不多一样 ...
对, 没错。 基本概念大概是这样。
不过led blinking的core是在timer 2 interrupt那边。 了解timer 2 interrupt,就是了解我的program的了。
timer 2 interrupt routine 在 void T2ISR (void) interrupt 5那边。
*还有timer 2 和timer 1 & timer 0是一样的。会timer 1/0就看得懂的了。
只是register名称不一样罢了。 |
|
|
|
|
|
|
|
发表于 13-12-2007 05:42 PM
|
显示全部楼层
原帖由 fritlizt 于 13-12-2007 05:36 PM 发表
对, 没错。 基本概念大概是这样。
不过led blinking的core是在timer 2 interrupt那边。 了解timer 2 interrupt,就是了解我的program的了。
timer 2 interrupt routine 在 void T2ISR (void) interrupt 5 ...
对, 因为我的书没有timer 2 , 所以不知道那个名,今天老师show , 才知道名字那么奇怪的。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|