文章目录声明:本人初学zigbee,很多代码引用自他人,因此本文仅作参考
- 前言
- 一、协调器
- 二、终端
- 1.SampleApp.c
- 2.舵机部分
- 3.ZMain.c
- 三、完整代码
前言
本人这学期课设,要求使用zigbee完成设计。在学习中颇有收获和心得,因此写下本文记录,并分享一些经验。
以下是硬件部分,包括一个协调器和两个终端,使用的传感器包括超声波模块,舵机,避障模块。上位机部分详见zigbee协议栈雷达 上位机部分
一、协调器
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
switch ( pkt->clusterId )
{
//接收终端的距离数据
case SAMPLEAPP_P2P_CLUSTERID:
if(pkt->cmd.DataLength==4)//如果接收到终端1数据
{
byte rf_buff[5]={0};
//取出数据
osal_memcpy(rf_buff, pkt->cmd.Data, pkt->cmd.DataLength);
//串口输出
HalUARTWrite(0, rf_buff, pkt->cmd.DataLength);
}
else if(pkt->cmd.DataLength==1)//如果接收到终端2数据
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //输出接收到的数据
break;
case SAMPLEAPP_PERIODIC_CLUSTERID:
break;
case SAMPLEAPP_FLASH_CLUSTERID:
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
二、终端
因为学校要求使用两个传感器,所以终端2上我接了一个从小车上扒下来的避障模块…
1.SampleApp.c//SampleApp.c
//下载终端1代码时E1为1,E2为0
//下载终端2代码时E1为0,E2为1
#define E1 1//终端1代码可用
#define E2 0//终端2代码不可用
#define Trig P0_4 //超声波产生脉冲引脚
#define Echo P0_5 //超声波回波引脚
#define DATA_PIN P0_6 //终端2传感器引脚
//舵机引脚为P1_0,因为直接使用定时器通道映射了,所以此处不需要声明
int n=0;//舵机角度控制
int flag=0;//舵机转向标记
//void SampleApp_Init( uint8 )
//引脚初始化
#if E1//终端1引脚
//设置p0_4输出
P0DIR |= 0x10; //P0_4定义为输出
//设置p0_5输入
P0DIR &= ~0x20; //P0_4定义为输出
#endif
#if E2//终端2引脚
P0SEL &= 0xBf; //P0_6
P0DIR &= 0xBf;
#endif
//SampleApp.c
void SampleApp_Send_P2P_Message( void )
{
#if E1//终端1代码
int us_count=0;
unsigned int distance_data=0;
//触发引脚Trig产生一个20us的高电平
Trig=1;
Delay_20us();
Trig=0;
//等待Echo回波引脚变高电平
while(Echo==0);
while(Echo==1)//回波一直是高电平
{
//10us延时
Delay_10us();
us_count++;
}
distance_data=us_count*10;//计算时间
distance_data/=58;//计算距离,单位cm
//舵机控制部分
if(n*5 == 180)
{
flag = 1;//如果舵机转到180°,让舵机反转
}
else if(n==0)
{
flag = 0;//如果舵机转到0°,让舵机反转
}
if(flag == 0)//舵机每次正向转动5°
{
duo(n*5);
n++;
}
else if(flag == 1)//舵机每次反向转动5°
{
duo(n*5);
n--;
}
if(distance_data>=1000)
{
//距离大于10米认为出错
HalLcdWriteString( "error", HAL_LCD_LINE_4 );
}
else
{
//超声波距离数据
TxBuff[0]=(distance_data%1000)/100;
TxBuff[1]=((distance_data%1000)%100)/10;
TxBuff[2]=((distance_data%1000)%100)%10;
//舵机角度
TxBuff[3]=n*5;
//发送到协调器
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
4,
TxBuff,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
#endif
#if E2//终端2代码
byte state;
if(DATA_PIN == 1)//引脚检测到高电平
{
MicroWait (10000); // Wait 10ms
if(DATA_PIN == 1)
{
state = 0x31; //发送数据0x31
}
}
else //引脚为低电平
{
state = 0x30; //发送数据0x30
}
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
1,
&state,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
#endif
}
2.舵机部分
此处代码参考ZigBee-CC2530单片机 - 1路硬件PWM控制舵机角度(精度为1us)
//CC2530IOtest.c
#include
#include "CC2530IOtest.h"
//定时器1输出PWM
void Timer1PwmInit()
{
uint value;
CLKCONCMD |= 0x28; //时钟速度32 MHz 定时器标记输出设置[5:3]1MHz
PERCFG |= 0x40; //定时器1 的IO位置 1:备用位置2
P2SEL &= ~0x10; //定时器1优先
P2DIR |= 0xC0; //第1优先级:定时器1通道2-3
//timer1 通道2映射口P1_0
P1DIR |= 0x01;
P1SEL |= 0x01;
//设定周期
value=19999;
T1CC0H = value>>8;
T1CC0L = value;
// 模式选择 通道2比较模式
T1CCTL2 = 0x1c;
//不分频,模计数
T1CTL = 0x02;
}
void mydelay()//延时0.5ms
{
int i,j;
for(i=0;i<500;i++)
for(j=0;j<1000;j++)
asm("NOP");
}
//定时器通道2PWM输出
void Timer1ch2PwmOut(uint value)
{
value= 19999 - value;
T1CC2H = value>>8;
T1CC2L = value;
}
void duo(int d)//转动角度
{
d = 500 + d*11;
Timer1ch2PwmOut(d);
mydelay();
}
//CC2530IOtest.h
#ifndef __CC2530IOtest_H__
#define __CC2530IOtest_H__
typedef unsigned char uchar;
typedef unsigned int uint;
void SystemClockInit(void);
void Timer1PwmInit(void);
void mydelay(void);
void Timer1ch2PwmOut(uint);
void duo(int);
#endif
3.ZMain.c
需要在主函数中初始化定时器
//int main( void )
Timer1PwmInit();//初始化定时器
duo(0);//舵机初始设为0°
osal_start_system(); // No Return from here
三、完整代码
链接:https://pan.baidu.com/s/1Rvep3gEYs6evzICGij_14w
提取码:de5y
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)