|
之前做了个用按键控制简单灯效实验,这几天恶补了串口,中断知识,将按键模式改用串口实现,实验效果视频点击查看:
串口控制闪灯实验效果视频
硬件:
a. 51最小系统板
b. RS232串行口
软件:
a. Keil uVision3.0;
b. Easy 51Pro v2.0;
c. LP_COMM V1.22;
以下为测试成功的源代码:
/****************************************************
* 声明: 此制作为CIKY单片机学习过程,欢迎爱好者
* 一起学习和探讨,共同进步。
* Title: 串口控制闪灯
* Description: 通过AT89S51单片机控制LED点亮方式,依次
* 为单灯循环轮流点亮、两点循环轮流点亮、
* LED从中心向两边逐个点亮和从中心渐亮渐灭
* 四种方式,还可以给亮灯速度进行加减速。
* @author CIKY
* Date: Jan. 01, 2010
****************************************************/
#include <reg51.h>
#define uchar unsigned char
uchar LEDT1 = 0x01; //保存循环轮流点亮左移时LED状态;
uchar LEDT2 =0x80; //保存循环轮流点亮右移时LED状态;
uchar m = 0; //控制方向
uchar LEDShine[4] = {0xe7,0xc3,0x81,0x00};
//LED灯从中心向两边逐个点亮;
uchar LEDShineC[14] = {0xef,0xcf,0x8f,0x0f,0x8f,0xcf,0xef,0xf7,0xf3,0xf1,0xf0,0xf1,0xf3,0xf7};
//LED从中心向单边逐个点亮熄灭过程;
uchar n = 50; //延时时间
uchar LEDVal ='a'; //保存串行接收数据,0为单灯循环轮流点亮,
//1为两灯循环轮流点亮,2为LED从中心
//向两边逐个点亮方式;
//////////////////延时函数//////////////////////
void Delay(uchar x)
{
while(x--)
{
uchar j;
for(j=0;j<=125;j++);
}
}
///////////////////加减速/////////////////////////////////////
//减速
void fun_LEDSub()
{
if(n<240)
n+=10;
}
//加速
void fun_LEDAdd()
{
if(n>=10)
n-=10;
}
//////////////////1灯循环轮流点亮子程序/////////////////////
//循环左移
void fun_LEDTurnA()
{
LEDT1<<=1;
if(LEDT1==0)
LEDT1=1;
}
//循环右移
void fun_LEDTurnB()
{
LEDT2>>=1;
if(LEDT2==0)
LEDT2=0x80;
}
//1灯循环轮流点亮
void fun_LEDTurn()
{
fun_LEDTurnA();
fun_LEDTurnB();
m=++m%16;
if(m<8)
P1=~LEDT2;
else
P1=~LEDT1;
}
//////////////////两灯循环轮流点亮方式子程序////////////////
void fun_LEDTurn2()
{
fun_LEDTurnB();
fun_LEDTurnA();
P1=~(LEDT1|LEDT2);
}
//////////////////LED从中心向两边逐个点亮子程序/////////////////////
void fun_LEDShine()
{
m=++m%4;
P1=LEDShine[m];
}
//////////////////LED从中心逐步单边点亮子程序/////////////////////
void fun_LEDShineC()
{
m=++m%14;
P1=LEDShineC[m];
}
//////////////////LED模式////////////////////////////
void fun_LEDMode(uchar RcvVal)
{
switch(RcvVal)
{
case 'A':
case 'a':
m=0;
n=50;
LEDT1=0x01;
LEDT2=0x80;
LEDVal='a';
break;
case 'B':
case 'b':
n=50;
LEDT1=0x01;
LEDT2=0x80;
LEDVal='b';
break;
case 'C':
case 'c':
m=0;
n=50;
LEDShine[0]=0xe7;
LEDVal='c';
break;
case 'D':
case 'd':
m=0;
n = 100;
LEDShineC[0]=0xef;
LEDVal='d';
break;
case '+':
fun_LEDAdd();
break;
case '-':
fun_LEDSub();
break;
default:
LEDVal='a';
}
}
///////////////////LED选择模式/////////////////////
//*
void fun_LEDSelectMode(uchar mode)
{
switch (mode)
{
case 'a':
fun_LEDTurn();
break;
case 'b':
fun_LEDTurn2();
break;
case 'c':
fun_LEDShine();
break;
case 'd':
fun_LEDShineC();
break;
default:
fun_LEDTurn();
}
Delay(n);
}
//*/
///////////////////初始化串口//////////////////////
void fun_InitComm()
{
TMOD=0x20; //在11.0592MHz下,设置串行口波特率为9600,方式3
TH1=0xfd;
TL1=0xfd;
SCON=0xd8;
PCON=0x00;
ES=1;
TR1=1;
EA=1;
}
/////////////////主程序入口/////////////////////////
void main(void)
{
P1=0xff;
P1=0xf0;
fun_InitComm();
while(1)
{
fun_LEDSelectMode(LEDVal);
}
}
/////////////////串行口中断///////////////////////////////////
void fun_Uart() interrupt 4 using 1
{
uchar RcvVal;
while(RI==0);
RI=0;
RcvVal=SBUF;
SBUF=RcvVal;
while(TI==0);
TI=0;
fun_LEDMode(RcvVal); } |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|