大家好,又见面了,我是你们的朋友全栈君。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "gpio.h"
#include "includes.h"//包含操作系统头文
#include "com.h"
#include "fsmc.h"
#include "timer.h"
//ucosii 操作系统 组网
frame_typedef AccessNet_frame={0,1,1,0,1};//UID为1的终端随机接入
frame_typedef REG_REQ={0,1,1,0,2};//REG_REQ
frame_typedef REG_RSP={0,1,1,0,3};//REG_RSP
frame_typedef RNG_REQ={0,1,1,0,4};//RNG_REQ
frame_typedef RNG_RSP={1,1,1,0,5};//RNG_RSP
/UCOSII任务设置///
//START 任务
//设置任务优先级
#define START_TASK_PRIO 10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);
//拆帧任务
//设置任务优先级
#define OPEN_FRAME_TASK_PRIO 5
//设置任务堆栈大小
#define OPEN_FRAME_STK_SIZE 64
//任务堆栈
OS_STK OPEN_FRAME_TASK_STK[OPEN_FRAME_STK_SIZE];
//任务函数
void open_frame_task(void *pdata);
//控制任务
//设置任务优先级
#define NetIn_TASK_PRIO 4
//设置任务堆栈大小
#define NetIn_STK_SIZE 64
//任务堆栈
OS_STK NetIn_TASK_STK[NetIn_STK_SIZE];
//任务函数
void NetIn_task(void *pdata);
//LED任务
//设置任务优先级
#define LED_TASK_PRIO 6
//设置任务堆栈大小
#define LED_STK_SIZE 64
//任务堆栈
OS_STK LED_TASK_STK[LED_STK_SIZE];
//任务函数
void led_task(void *pdata);
OS_EVENT * msg_rec_frame; //收到帧邮箱事件块指针,msg_key为结构体指针
OS_EVENT * sem_syn; //拆帧和控制之间作同步的信号量
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2//
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
fcmc_Init(); //初始化FSMC接口
TIM3_Int_Init(1-1,21-1);//PRE=4Mhz,0.25us
uart_init(9600); //初始化串口波特率为115200
// printf("initial success\r\n");
OSInit();
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata = pdata;
msg_rec_frame=OSMboxCreate((void*)0); //创建消息邮箱
sem_syn=OSSemCreate(0); //创建信号量
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(open_frame_task,(void *)0,(OS_STK*)&OPEN_FRAME_TASK_STK[OPEN_FRAME_STK_SIZE-1],OPEN_FRAME_TASK_PRIO);
OSTaskCreate(NetIn_task,(void *)0,(OS_STK*)&NetIn_TASK_STK[NetIn_STK_SIZE-1],NetIn_TASK_PRIO);
OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
//拆帧任务
void open_frame_task(void *pdata)
{
u16 recv_data_for_fpga;
u8 err;
u8 i;
u8 t,len;
u16 b[16]={0};
frame_typedef rec_data;
while(1)
{
OSSemPend(sem_syn,0,&err); //第二个参数为等待时间,为0表示一直等
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
for(t=0;t<16;t++)
{
b[t]=0;//赋初值0}
}
for(t=0;t<len;t++)
{
b[t]=USART_RX_BUF[t];//将发送的数存到数组中
}
USART_RX_STA=0;
recv_data_for_fpga=atonum(b); //将数组转成数值
printf("收到的data为:%d\r\n",recv_data_for_fpga);
rec_data=frame_process(recv_data_for_fpga);//拆帧
OSMboxPost(msg_rec_frame,&rec_data); //发送消息
}
delay_ms(10);
}
}
//注:open_frame_task实现的功能:串口向单片机发送数据,单片机对发送的数据进行处理,拆帧。
// 入网任务,终端侧
void NetIn_task(void *pdata)
{
frame_typedef r_data={0,0,0,0,0};
frame_typedef *data=&r_data;
u16 distance;
u8 NetIn_Status=REG_REQ_Status;
u8 err;
while(1)
{
switch (NetIn_Status)
{
case 2:
{
OSSemPost(sem_syn);
//发送信号量,表示开始读数据
data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
~~printf("接收的data->UID_4bit为:%d\r\n",data->UID_4bit);~~
当printf放在此处,串口打印的值出现错误,不能进入下面if循环。
if(data->UID_4bit==1&&data->sub_form_4bit==1)
{
~~printf("接收的data->UID_4bit为:%d\r\n",data->UID_4bit);~~
放在此处可打印出,且进入循环?????
TIM_Cmd(TIM3,ENABLE);
printf("开始计数"); //开始计数
NetIn_Status+=2;
}
}break;
// case RNG_REQ_Status:
case 4:
{
OSSemPost(sem_syn); //发送信号量,表示开始读数据
data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
printf("进入第二回合");
printf("接收的data->sub_form_4bit为:%d\r\n",data->sub_form_4bit);
if(data->sub_form_4bit==3)
{
printf("关闭计数");
TIM_Cmd(TIM3,DISABLE); //关闭计数
distance=distance_cnt*0.25; //单位为us
printf("distance%d\r\n",distance);
// FRAMING(®_REQ); //发测距回复
NetIn_Status+=2;
}
// else NetIn_Status=REG_REQ_Status;
}break;
case Success_Status:
{
OSSemPost(sem_syn); //发送信号量,表示开始读数据
data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
if(data->sub_form_4bit==5&&data->success_flag==1)
{
//成功入网,开始发数据
NetIn_Status=REG_REQ_Status;
}
else NetIn_Status=Success_Status;
}break;
default:
printf("失败,继续循环");
break;
}
delay_ms(10);
};
}
//LED任务
void led_task(void *pdata)
{
u8 t;
while(1)
{
// t++;
// delay_ms(10);
// if(t==8)LED0=1; //LED0灭
// if(t==100) //LED0亮
// {
// t=0;
// LED0=0;
// }
LED0=!LED0;
delay_ms(100);
}
}
????????为什么printf和消息邮箱放在一起会出现错误,消息邮箱收到的结构体的值会改变????
注:
#ifndef __COM_H
#define __COM_H
#include "sys.h"
#define Random_Access_Status 1
#define REG_REQ_Status 2
#define REG_RSP_Status 3
#define RNG_REQ_Status 4
#define RNG_RSP_Status 5
#define Success_Status 6
typedef struct
{
u16 success_flag;
u16 UID_4bit;
u16 prio_4bit;
u16 form_2bit;
u16 sub_form_4bit;
}frame_typedef;
u16 * HexToBinStr( u16 n,int x);
frame_typedef frame_process(u16 data);
void FRAMING(frame_typedef *arm_to_fpga_data);
u16 atonum(u16 s[]);
#endif
#include "com.h"
#include "fsmc.h"
#include "usart.h"
/**************************************************
函数名称:HexToBinStr
函数功能:进制转换
输入参数:(n,x)n代表需要转换的数 x代表进制
返回值:数组a,从高位到地位排序
**************************************************/
u16 a[16];
u16 * HexToBinStr( u16 n,int x)
{
u16 y=0;
while(n!=0)
{
a[15-y]=n%x;
n=n/x;
y++;
}
for(;y<16;y++)
{a[15-y]=0;}
return a;
}
/**************************************************
函数名称:frame_process
函数功能:拆帧处理
输入参数:
返回值:
**************************************************/
frame_typedef frame_process(u16 data)
{
frame_typedef recv_data;
u16 *data_2b;
u16 i;
data_2b=HexToBinStr(data,2); //转换为二进制
// printf("转换后的二进制数据为");
// for(i=0;i<16;i++)
// printf("%d",a[i]);
// printf("\n\r");
// recv_data.sub_form_4bit=0;
// recv_data.form_2bit=0;
// recv_data.prio_4bit=0;
// recv_data.UID_4bit=0;
// recv_data.success_flag=0;
//
recv_data.UID_4bit=data_2b[0]*8+data_2b[1]*4+data_2b[2]*2+data_2b[3]*1;
recv_data.prio_4bit=data_2b[4]*8+data_2b[5]*4+data_2b[6]*2+data_2b[7];
recv_data.form_2bit=data_2b[8]*2+data_2b[9];
recv_data.sub_form_4bit=data_2b[10]*8+data_2b[11]*4+data_2b[12]*2+data_2b[13];
recv_data.success_flag=data_2b[14];
//
// printf("接收的recv_data.UID_4bit为:%d\r\n",recv_data.UID_4bit);
// printf("接收的recv_data.UID_4bit为:%d\r\n",recv_data.sub_form_4bit);
//
return recv_data;
}
/**************************************************
函数名称:FRAMING
函数功能:组帧
输入参数:数据结构体指针
返回值:
**************************************************/
void FRAMING(frame_typedef *arm_to_fpga_data)
{
u16 Tx_data_to_fpga;
Tx_data_to_fpga=arm_to_fpga_data->sub_form_4bit+(arm_to_fpga_data->form_2bit<<4)+(arm_to_fpga_data->prio_4bit<<6)+(arm_to_fpga_data->UID_4bit<<10)+(arm_to_fpga_data->success_flag<<14);
//fpga_write(2,Tx_data_to_fpga);
// printf("发送的data为:%d\r\n",Tx_data_to_fpga);
}
/**************************************************
函数名称:FRAMING
函数功能:组帧
输入参数:数据结构体指针
返回值:
**************************************************/
void control_frame(frame_typedef *control_frame_data)
{
}
/**************************************************
函数名称:atoi
函数功能:将字符串转换为数值
输入参数:字符串数组
返回值:
**************************************************/
u16 atonum(u16 s[])
{
u16 i,n;
n=0;
for(i=0;s[i]>='0'&&s[i]<='9';i++)
{
n=10*n+(s[i]-'0');
}
return n;
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/137809.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...