CC2530串口控制LED灯奇怪玩法
实验目的:CC2530用串口从上位机发送16进制命令代码来控制LED3、4、5、6并返回相应动作
一、串口设置
设置串口调试工具
设置接收区和发送区
举例:发送0x01的命令
二、串口发送相应命令
命令代码1:0x01 ==> LED3亮,返回“LED3 is open!"
命令代码2:0x02 ==> LED4亮,返回“LED4 is open!"
命令代码3:0x03 ==> LED5亮,返回“LED5 is open!"
命令代码4:0x04 ==> LED6亮,返回“LED6 is open!"
命令代码5:0x05 ==> LED3、4亮,返回“LED3 and LED4 is open!"
命令代码6:0x06 ==> LED5、6亮,返回“LED5 and LED6 is open!"
命令代码7:0x07 ==> LED3、5亮,返回“LED3 and LED5 is open!"
命令代码8:0x08 ==> LED4、6亮,返回“LED4 and LED6 is open!"
命令代码9:0x09 ==> LED3、4、5跑马灯从左到右,返回“LED3、LED4、LED5 rush rush!"
命令代码10:0x0a ==> LED3、4、5跑马灯从右到左,返回“ rush rush LED3、LED4、LED5!"
命令代码11:0x0b ==> LED4、5、6跑马灯从左到右,返回“ LED3、LED4、LED5 rush rush!"
命令代码12:0x0c ==> LED4、5、6跑马灯从右到左,返回“ rush rush LED3、LED4、LED5!"
命令代码13:0x0d ==> LED3、4、5、6跑马灯从左到右,返回“LED3、LED4、LED5、LED6 rush rush!"
命令代码14:0x0e ==> LED3、4、5、6跑马灯从右到左,返回“ rush rush LED3、LED4、LED5、LED6!"
命令代码15:0x0f ==> LED3、4、5、6闪烁,返回“LED3、LED4、LED5、LED6 flicker!"
命令代码1:0x11 ==> LED3灭,返回“LED3 is closed!"
命令代码2:0x12 ==> LED4灭,返回“LED4 is closed!"
命令代码3:0x13 ==> LED5灭,返回“LED5 is closed!"
命令代码4:0x14 ==> LED6灭,返回“LED6 is closed!"
命令代码5:0x15 ==> LED3、4灭,返回“LED3 and LED4 is closed!"
命令代码6:0x16 ==> LED5、6灭,返回“LED5 and LED6 is closed!"
命令代码7:0x17 ==> LED3、5灭,返回“LED3 and LED5 is closed!"
命令代码8:0x18 ==> LED4、6灭,返回“LED4 and LED6 is closed!"
命令代码9:0x19 ==> LED3、4、5跑马灯灭,返回“LED3、LED4、LED5 is closed!"
命令代码10:0x1a ==> LED3、4、5跑马灯灭,返回“LED3、LED4、LED5 is closed!"
命令代码11:0x1b ==> LED4、5、6跑马灯灭,返回“LED3、LED4、LED5 is closed!"
命令代码12:0x1c ==> LED4、5、6跑马灯灭,返回“LED3、LED4、LED5 is closed!"
命令代码13:0x1d ==> LED3、4、5、6跑马灯灭,返回“LED3、LED4、LED5、LED6 is closed!"
命令代码14:0x1e ==> LED3、4、5、6跑马灯灭,返回“LED3、LED4、LED5、LED6 is closed!"
命令代码15:0x1f ==> LED3、4、5、6灭,返回“LED3、LED4、LED5、LED6 is closed!"
三、源代码
代码如下(示例):
#include<ioCC2530.h>
#define D3 P1_0
#define D4 P1_1
#define D5 P1_3
#define D6 P1_4
#define uint unsigned int
#define uchar unsigned char
/*功能 MS延迟函数*/
void DelayMS(uint z)
{
for(uint i=0;i<z;i++)
for(uint j=0;j<535;j++);
}
/*设置晶振
目标:系统时钟源和时钟32MHz,并且设置定时器标记输出为32MHz*/
void Set_Clock_32M()
{
CLKCONCMD &= ~0x40;
while((CLKCONSTA & 0x40) == 0x40);
CLKCONCMD &= ~0x7f;
}
/*端口初始化
目标:对LED3,4,5,6设为通用I/O,输出,并关闭LED灯*/
void Init_Port()
{
P1SEL &= ~0x1b;
P1DIR |= 0x1b;
P1 &= ~0x1b;
}
/*LED检查是否完整*/
void LED_Check()
{
P1 |= 0x1b;
DelayMS(200);
P1 &= ~0x1b;
DelayMS(200);
}
/*初始化USART0*/
void Init_Uart0()
{
PERCFG &= ~0x01; //设置USART0的I/O位置为备用位置1
P0SEL |= 0x0c; //对P0_2,P0_3设置为外设功能
U0BAUD = 59; //设置波特率为32MHz,9600
U0GCR = 8;
U0CSR |= 0xc0; //设置USART0为UART模式、开启UART接收器使能
U0UCR |= 0x80; //清空USART0单元
UTX0IF = 0; //清空USART0写标志
URX0IF = 0; //清空USART0读标志
URX0IE = 1; //USART0中断使能
EA = 1; //总中断使能
}
/*USART0按字节发送数据
功能:向上位机发送数据
方法:接受到的数据向U0DBUF赋值来传输到上位机,等待UTX0IF置1(等待发送完毕)后清0,在循环传输下一个字符*/
void UR0_SendByte(uchar sdata)
{
U0DBUF = sdata;
while(UTX0IF == 0);
UTX0IF = 0;
}
/*USART0按字符发送数据*/
void UR0_SendString(uchar *str)
{
while(*str != '\0')
{
UR0_SendByte(*str++);
}
}
/*URX0中断服务函数
功能:接收上位机发送的数据(数据在U0DBUF中)*/
uint count=0; //定时器秒钟计数
uchar SelectType = 0; //命令行选择类型(跑马灯/闪烁)
#pragma vector = URX0_VECTOR
__interrupt void Service_URX0Recv()
{
switch(U0DBUF)
{
case 0x01:D3 = 1;UR0_SendString("LED3 is open!\n");break;
case 0x02:D4 = 1;UR0_SendString("LED4 is open!\n");break;
case 0x03:D5 = 1;UR0_SendString("LED5 is open!\n");break;
case 0x04:D6 = 1;UR0_SendString("LED6 is open!\n");break;
case 0x05:D3 = 1;D4 = 1;UR0_SendString("LED3 and LED4 is open!\n");break;
case 0x06:D6 = 1;D5 = 1;UR0_SendString("LED5 and LED6 is open!\n");break;
case 0x07:D3 = 1;D5 = 1;UR0_SendString("LED3 and LED5 is open!\n");break;
case 0x08:D6 = 1;D4 = 1;UR0_SendString("LED4 and LED6 is open!\n");break;
case 0x09:count = 0;SelectType = 1;UR0_SendString("LED3、LED4、LED5 rush rush!\n");break;
case 0x0a:count = 0;SelectType = 2;UR0_SendString("rush rush LED3、LED4、LED5!\n");break;
case 0x0b:count = 0;SelectType = 3;UR0_SendString(" LED6、LED4、LED5 rush rush!\n");break;
case 0x0c:count = 0;SelectType = 4;UR0_SendString(" rush rush LED6、LED4、LED5!\n");break;
case 0x0d:count = 0;SelectType = 5;UR0_SendString(" LED3、LED4、LED5、LED6 rush rush!\n");break;
case 0x0e:count = 0;SelectType = 6;UR0_SendString(" rush rush LED3、LED4、LED5、LED6!\n");break;
case 0x0f:count = 0;SelectType = 7;UR0_SendString("LED3、LED4、LED5、LED6 flicker!\n");break;
case 0x11:D3 = 0;UR0_SendString("LED3 is closed!\n");break;
case 0x12:D4 = 0;UR0_SendString("LED4 is closed!\n");break;
case 0x13:D5 = 0;UR0_SendString("LED5 is closed!\n");break;
case 0x14:D6 = 0;UR0_SendString("LED6 is closed!\n");break;
case 0x15:D3 = 0;D4 = 0;UR0_SendString("LED3 and LED4 is closed!\n");break;
case 0x16:D6 = 0;D5 = 0;UR0_SendString("LED5 and LED6 is closed!\n");break;
case 0x17:D3 = 0;D5 = 0;UR0_SendString("LED3 and LED5 is closed!\n");break;
case 0x18:D6 = 0;D4 = 0;UR0_SendString("LED4 and LED6 is closed!\n");break;
case 0x19:count = 0;SelectType = 8;UR0_SendString("LED3、LED4、LED5 is closed!\n");break;
case 0x1a:count = 0;SelectType = 8;UR0_SendString(" LED3、LED4、LED5 is closed!\n");break;
case 0x1b:count = 0;SelectType = 9;UR0_SendString(" LED6、LED4、LED5 is closed!\n");break;
case 0x1c:count = 0;SelectType = 9;UR0_SendString(" LED6、LED4、LED5 is closed!\n");break;
case 0x1d:count = 0;SelectType = 10;UR0_SendString(" LED3、LED4、LED5、LED6 is closed!\n");break;
case 0x1e:count = 0;SelectType = 10;UR0_SendString(" LED3、LED4、LED5、LED6 is closed!\n");break;
case 0x1f:count = 0;SelectType = 10;UR0_SendString("LED3、LED4、LED5、LED6 is closed!\n");break;
}
}
/*定时器1设置
功能:每0.1s触发一次
种类:32MHz,通道0—比较模式,定时器1—模模式、128分频*/
void Init_Timer1()
{
EA = 1;
T1IE = 1;
T1CC0L = 0xa8;
T1CC0H = 0x61;
T1STAT |= 0x01;
T1CCTL0 |= 0x04;
T1CTL |= 0x0e;
}
/*定时器1中断服务函数*/
#pragma vector = T1_VECTOR
__interrupt void Service_Timer1()
{
count++;
switch(SelectType)
{
case 0:count = 0;break;
case 1:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x02;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x01;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x08;
if(count==31)count = 0;
}
break;
case 2:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x08;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x01;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x02;
if(count==31)count = 0;
}
break;
case 3:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x02;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x10;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x08;
if(count==31)count = 0;
}
break;
case 4:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x08;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x10;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x02;
if(count==31)count = 0;
}
break;
case 5:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x02;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x01;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x10;
}
else if(count<=41)
{
P1 &= ~0x1b;
P1 |= 0x08;
if(count==41)count = 0;
}
break;
case 6:
if(count<=11)
{
P1 &= ~0x1b;
P1 |= 0x08;
}
else if(count<=21)
{
P1 &= ~0x1b;
P1 |= 0x10;
}
else if(count<=31)
{
P1 &= ~0x1b;
P1 |= 0x01;
}
else if(count<=41)
{
P1 &= ~0x1b;
P1 |= 0x02;
if(count==41)count = 0;
}
break;
case 7:
if(count<=11)
P1 |= 0x1b;
else
{
P1 &= ~0x1b;
if(count==21)count = 0;
}
break;
case 8:
P1 &= ~0x0d;
SelectType = 0;
break;
case 9:
P1 &= ~0x1a;
SelectType = 0;
break;
case 10:
P1 &= ~0x1b;
SelectType = 0;
break;
}
}
void main()
{
Set_Clock_32M();
Init_Port();
Init_Uart0();
Init_Timer1();
LED_Check();
while(1);
}
总结
本章节运用到了时钟设置、串口通讯、引脚定义、定时器1设置的操作,写的不是很好,一部分执行的功能分成了两部分,一个是定时器中断里面,一个是串口中断里面,希望广大的网友提供一些宝贵的改进意见,一起来学习单片机哦哦哦!!!