完成单板代码
/*任务5:ZigBee无线模块应用*/
ZigBee Module传递信息过程:
1、从节点单板信息结构体:
typedef struct {
uint8_t temp;
uint8_t hum;
uint32_t light;
int8_t x;
int8_t y;
int8_t z;
}BOARD_INFORMATION;
BOARD_INFORMATION node_board_info; //声明节点单板信息结构体
2、初始化单板,调用底层函数接口
void InitPeripheral(void)
{
SystemInit();
GPIOInit();
InitClk();
InitLedFan();
InitSeg7ledKey();
InitUartSPI();
InitLcd();
InitLight();
InitAxis();
InitZigbee();
}
3、从节点单板收集单板传感器各信息: CollectInformation
void CollectInformation(void)
{
CollectTempHumInfo();
CollectLightInfo();
CollectAxisInfo();
}
3.1、 CollectTempHumInfo()
char CollectTempHumInfo(void)
{
char ret;
ret = Read_Temp_Hum(temp, hum); //底层提供读取温度湿度接口函数
return ret;
}
3.2、CollectLightInfo()
void CollectLightInfo(void)
{
lux = light_read(); //底层提供读取光强接口函数
}
3.3、CollectAxisInfo()
void CollectAxisInfo(void)
{
acc_read(&x, &y, &z); //底层提供读取重力感应接口函数
x = x+xoff;
y = y+yoff;
z = z+zoff;
}
4、从节点单板将收集到的传感器信息传递给OLED:ShowInfoToLcd()
void ShowInfoToLcd(void) //将收集的信息按一定的格式显示在OLED上,同样底层提供显示字符串函数可调用
{
ShowTempHumOnLcd();
ShowLightToLcd();
ShowAxisToLcd();
}
4.1、ShowTempHumOnLcd()
void ShowTempHumOnLcd(void)
{
char buf[20];
snprintf(buf, 16, "Temp: %d.%d ", temp);
OLED_DisStrLine(2, 0, (uint8_t *)buf);
snprintf(buf, 16, "Hum: %d.%d ", hum);
OLED_DisStrLine(3, 0, (uint8_t *)buf);
}
4.2、ShowLightToLcd()
void ShowLightToLcd(void)
{
char buf[24];
snprintf(buf, 20, "light: %d ", light);
OLED_DisStrLine(4, 0, (uint8_t *)buf);
}
4.3、ShowAxisToLcd()
void ShowAxisToLcd(void)
{
char buf[24];
snprintf(buf, 20, "Acc x: %d ", x);
OLED_DisStrLine(5, 0, (uint8_t *)buf);
//printf("\r\nAcc x: %d, ", x);
snprintf(buf, 20, "Acc y: %d ", y);
OLED_DisStrLine(6, 0, (uint8_t *)buf);
//printf("Acc y: %d, ", y);
snprintf(buf, 20, "Acc z: %d ", z);
OLED_DisStrLine(7, 0, (uint8_t *)buf);
//printf("Acc z: %d. ", z);
}
5、将从单板收集的信息通过ZigBee传递给主节点单板:SendInfoByZigbee()
void SendInfoByZigbee()
{
char len,i;
node_board_info.x = x; //将从节点单板收集的信息赋值给从节点单板信息结构体
node_board_info.y = y;
node_board_info.z = z;
node_board_info.temp= temp;
node_board_info.hum = hum;
node_board_info.light = light;
ZigBee_PutChar(0xaa); //用作校验位信息
ZigBee_PutChar(0x55); //用作校验位信息
len = sizeof(node_board_info);
for(i=0;i<len;i++){
ZigBee_PutChar(*((uint8_t *)&node_board_info+ i)); //将结构体信息通过ZigBee模块按字节传递给主节点单板
}
}
5.1、ZigBee_PutChar() //ZigBee传递信息函数
void ZigBee_PutChar(uint8_t Ch)
{
SPI752_PutChar(1, Ch); //1、MCU先将信息通过SPI接口传递给U14
}
5.1.1、SPI752_PutChar()
/*******************************************************************************
* Function Name : SPI752_PutChar
* Description : Use SPI572 channel 0 & 1 send a byte.
* Input : - Channel : 0 & 1.
* - Ch : 8bit data.
* Output : None
* Return : None
*******************************************************************************/
void SPI752_PutChar(uint8_t Channel, uint8_t Ch)
{
while(!(SPI752_RegRead(Channel, SPI752_LSR_R)&0x20));
SPI752_RegWrite(Channel, SPI752_THR_W, Ch);
}
5.1.1.1、SPI752_RegRead
/*******************************************************************************
* Function Name : SPI752_RegRead
* Description : Read Registor.
* Input : - Channel : 0 & 1.
* - Reg : 0x00 - 0x0f.
* Output : None
* Return : Registor value.
*******************************************************************************/
uint8_t SPI752_RegRead(uint8_t Channel, uint8_t Reg)
{
uint8_t rd;
SPI_UART_CS(0); //2、U14将信息通过UART传递给ZigBee模块
SPI_PutGet(1, SPI752_READ | (Reg<<3) | (Channel<<1));
rd = SPI_PutGet(1, 0);
SPI_UART_CS(1);
return rd;
}
5.1.1.1.1、SPI_UART_CS()
#define SPI_UART_CS(x) GPIOSetValue(PORT2, 0, x)
5.1.1.1.2、SPI_PutGet()
/*****************************************************************************
** Function name: SPI_PutGet
**
** Descriptions: SPI port send & receive
**
** parameters: - portNum
** 0: SPI0
** 1: SPI1
** - SendData, send data
**
** Returned value: - Get data
**
*****************************************************************************/
uint16_t SPI_PutGet(uint8_t portNum, uint16_t SendData)
{
if(portNum == 0)
{
/* Move on only if NOT busy and TX FIFO not full. */
while((LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF);
LPC_SSP0->DR = SendData;
/* Wait until the Busy bit is cleared. */
while(LPC_SSP0->SR & SSPSR_BSY);
/* Wait until the Busy bit is cleared */
while((LPC_SSP0->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE);
return LPC_SSP0->DR;
}
else
{
/* Move on only if NOT busy and TX FIFO not full. */
while((LPC_SSP1->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF);
LPC_SSP1->DR = SendData;
/* Wait until the Busy bit is cleared. */
while(LPC_SSP1->SR & SSPSR_BSY);
/* Wait until the Busy bit is cleared */
while((LPC_SSP1->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE);
return LPC_SSP1->DR;
}
}
5.1.1.2、SPI752_RegWrite()
/*******************************************************************************
* Function Name : SPI752_RegWrite
* Description : Write 8bit data to Registor.
* Input : - Channel : 0 & 1.
* - Reg : 0x00 - 0x0f.
* - Data : 8bit data.
* Output : None
* Return : None
*******************************************************************************/
void SPI752_RegWrite(uint8_t Channel, uint8_t Reg, uint8_t Data)
{
SPI_UART_CS(0);
SPI_PutGet(1, SPI752_WRITE | (Reg<<3) | (Channel<<1));
SPI_PutGet(1, Data);
SPI_UART_CS(1);
}
6、从节点单板main.c
int main(void)
{
long i=0;
InitPeripheral();
GPIOSetDir(PORT3, 0, 1); // Set PIO3_0 to output,用LED等做ZigBee传送信息指示灯
ch0 = 0;
ch1 = 0;
init_timer32_a1(1,10000); //初始化定时器
enable_timer32(1); //使能定时器
while(1)
{
if(ch0 >= 2000){ //定时刷新
ch0 = 0;
CollectInformation(); //收集信息
SendInfoToZigbee(); //通过ZigBee传送信息
GPIOSetValue(PORT3, 0, i%2); //LED灯闪动表示ZigBee在传送信息
if(i++ >= 500){
i=0;
}
}
if(ch1 >= 1000){ //OLED的刷新频率低于ZigBee传送的刷新频率
ch1 = 0;
ShowToLcd();
}
}
}
7、主节点单板将从节点单板收集到的信息显示到OLED上
ShowInfoToLcd(void)
void ShowInfoToLcd(void)
{
x = node_board_info.x; //接收ZigBee传递的信息,并show to OLED
y = node_board_info.y;
z = node_board_info.z;
temp = node_board_info.temp;
hum = node_board_info.hum;
light = node_board_info.light;
ShowTempHumOnLcd();
ShowLightToLcd();
ShowAxisToLcd();
}
8、主节点单板将从节点单板收集的信息通过UART传递给主机
void SendInfoByUart()
{
uint8_t rd;
static char idat=0;
if(ZigBee_GetChar(&rd)) //主节点单板通过ZigBee模块接收信息,单板信息循环单字节传送
{
if(idat == 0){
if(rd == 0xaa){ //判断第一个校验码
idat ++;
}
}else if(idat == 1){ //判断第二个校验码
if(rd == 0x55){
idat ++;
} else {
idat = 0; //若检验码不符合,则不接收信息
}
} else {
if(idat < sizeof(node_board_info)+2){ //已经判断前两个校验码OK
*((uint8_t *)&node_board_info+idat-2) = rd; //发送主体信息
if(++idat == sizeof(node_board_info)+2) //从节点单板信息全部传送完成
idat = 0;
}
UART0_PutChar(rd); //通过UART传送,可底层调用
}
}
}
9、主节点单板main.c
int main(void)
{
long i=0;
InitPeripheral(); /*初始化主节点单板收集信息的那些器件*/
ch0 = 0;
ch1 = 0;
GPIOSetDir(PORT3, 0, 1); // Set PIO3_0 to output
init_timer32_a1(1,10000); //同样初始化主节点单板定时器
enable_timer32(1); //使能定时器
while(1)
{
if(ch0 >= 2000){
ch0 = 0;
GPIOSetValue(PORT3, 0, i%2); //LED指示灯
if(i++ == 500){
i=0;
}
}
if(ch1 >= 100){ //定时刷新
ch1 = 0;
ShowToLcd();
}
SendInfoByUart(); //主节点单板将收集到的信息传递给主机服务器
}
}