单片机流水灯串口控制的功能要求【从PC通过串口发送字符(‘R’,’L,‘S),分别控制流水灯向右流动、向左流动、停止】:
(1)编写完整的C语言程序实现功能要求,采用循环轮询结构;
答:循环轮转结构是在main函数中,按事先编写好的顺序进行执行,其缺点是实时性差,不适合有外部驱动的情况在这里不展示代码了。
(2)考虑采用前后台结构编程的话,程序的大体结构是什么样子的?用程序框图或文字描述一下;
答:前后台系统相比轮询系统,前后台系统在轮询系统的基础上加入了中断的概念,外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断我们称之为前台,main()函数中的无限循环称为后台。
其详细代码如下:
#include<reg51.h>
#include <absacc.h>
#include <intrins.h>
void UsartConfiguration();
void delay(int z);
void led_r();
void led_l();
void led_die();
void main()
{
UsartConfiguration();
while(1)
{
}
}
void UsartConfiguration()//硬件初始化
{
SCON=0X50;
TMOD=0X20;
PCON=0X80;
TH1=0XF3;
TL1=0XF3;
ES=1;
EA=1;
TR1=1;
}
void Usart() interrupt 4串行通信中断函数
{
unsigned char receiveData;
receiveData=SBUF;
if(receiveData=='S'||receiveData=='s'||receiveData==83||receiveData==115)
{
led_die();
}
if(receiveData=='L'||receiveData=='l'||receiveData==76||receiveData==108)
{
led_l();
}
if(receiveData=='R'||receiveData=='r'||receiveData==82||receiveData==114)
{
led_r();
}
RI = 0;
SBUF=receiveData;
while(!TI);
TI=0;
}
void led_r()//又流水灯
{
char temp,num;
temp=0x7f;
for(num=0;num<8;num++)
{ P2=temp;
delay(1000);
temp=_cror_(temp,1);
}
}
void led_l()//左流水灯
{
char temp,num;
temp=0xfe;
for(num=0;num<8;num++)
{ P2=temp;
delay(1000);
temp=_crol_(temp,1);
}
}
void led_die()//灯熄灭
{
P2=0x00;
}
void delay(int z)//延时函数
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
(3)如果可以采用多任务方式编程的话,程序的大体结构是什么样子的?用程序框图或文字描述一下。
答:多任务系统相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。在多任务系统中,任务与中断一样,也具有优先级,优先级高的任务会被优先执行。但一个紧急事件在中断中被标志之后,如果事件对应的任务优先级足够高,就会立刻得到响应,相比前后台系统,多任务系统的实时性又被提高了。
其大致框架如下:
int flag1 = 0 ;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
//硬件相关初始化
HardWareInit();
//OS初始化
RTOSInit();
//OS启动,开启多任务调度,不再返回
RTOSStart();
}
void ISR1(void)
{
flag1=1;//置标志位
}
void ISR2(void)
{
flag2=1;//置标志位
}
void ISR3(void)
{
flag1=3;//置标志位
}
void DoSomething1(void)
{
//无限循环,不能返回
for(;;)
{
if(flag1) {}
}
}
void DoSomething2(void)
{
//无限循环,不能返回
for(;;)
{
if(flag2) {}
}
}
void DoSomething3(void)
{
//无限循环,不能返回
for(;;)
{
if(flag3) {}
}
}