⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ZLG的EASYARM上实现的信号量与消息邮箱之间通信的实验程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			main.c
** Last modified Date:  2004-09-16
** Last Version:		1.0
** Descriptions:		The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:			Chenmingji
** Created date:		2004-09-16
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"							//包含了"includes.h"和一些系统配置文件
#include "stdlib.h"

#define	  UART_BPS	115200					//串口通信波特率
#define   LEDS8  	0xFF << 16				//P2[23:16]为LED8~LED1的控制引脚
#define	  TaskStkLengh	64					//定义用户任务的堆栈长度
 
uint32 LED[9]={0,1<<16,1<<17,1<<18,1<<19,1<<20,1<<21,1<<22,1<<23};//LED引脚控制
uint8  FlowCounter=0;						//流水灯花样计数器
const uint32 LED_TBL[6][8]={				//定义流水灯花样数据表,LED低电平点亮
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},
{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01},
{0x0f,0xf0,0x0f,0xf0,0x0f,0xf0,0x0f,0xf0},
{0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55},
{0x18,0x3c,0x7e,0xff,0x7e,0x3c,0x18,0x00},
{0x81,0xc3,0xe7,0xff,0xe7,0xc3,0x81,0x00}};

OS_STK	TaskRcvStk[TaskStkLengh];			//定义串口接收数据任务的堆栈
OS_STK	TaskSwitchLEDStk[TaskStkLengh];		//定义串口发送任务的堆栈
OS_STK	TaskFlowLEDStk[TaskStkLengh];		//定义流水灯任务的堆栈
OS_STK	TaskSendStk[TaskStkLengh];			//定义串口发送任务的堆栈
OS_EVENT *Rcv_box;							//定义串口接收数据消息邮箱指针
OS_EVENT *Send_sem;							//定义串口发送信号量指针
void 	TaskRcv(void *pdata);				//声明串口接收任务,因为其代码在主函数的后面
void    TaskSwitchLED(void *pdata);			//声明开关LED任务,因为其代码在主函数的后面
void    TaskFlowLED(void *pdata);			//声明流水灯任务,因为其代码在主函数的后面
void    TaskSend(void *pdata);				//声明串口发送任务,因为其代码在主函数的后面
void 	UART0Init (void);					//声明串口初始化函数,因为其代码在主函数的后面

/********************************************************************************************************
** 函数名称: main()
** 函数功能: EasyARM.exe软件上的模拟按键控制MagicARM2200上LED的亮灭,并在模拟LED上同步显示
** 说明:	 将跳线器JP23全部短接,JP15全部断开。
			 模拟按键控制相应LED。
********************************************************************************************************/       
int main (void)
{
	OSInit ();						//操作系统初始化																									
	OSTaskCreate(TaskRcv,(void *)0, &TaskRcvStk[TaskStkLengh - 1], 4);//创建任务TaskRcv
	OSStart();						//开始多任务调度
	return 0;															
}
/*********************************************************************************************************
**                            TaskRec 串口接收任务
********************************************************************************************************/
void TaskRcv(void *pdata)
{	INT8U err,key;
	pdata = pdata;											//防止编译器报错
	TargetInit ();											//目标板初始化
	UART0Init();											//串口初始化
	IO2DIR = LEDS8;											//设置LED对应引脚为输出,其它引脚默认为输入
 	IO2SET = LEDS8;											//上电后,首先熄灭所有LED	
	Rcv_box=OSMboxCreate((void*)0);							//创建串口接收数据消息邮箱
	Send_sem=OSSemCreate(0);								//创建串口发送信号量
	while(1)
	{	
		key=*(uint8*)OSMboxPend(Rcv_box,0,&err);			//等待接收串口发送数据,按键编码
			
		if((key>0)&&(key<9))								//1~8之间
			OSTaskCreate(TaskSwitchLED,(void *)&key, &TaskSwitchLEDStk[TaskStkLengh - 1], 5);	//创建开关LED任务
							
		if(key==19) 										//FLOW键按下,LED实现流水灯效果
			OSTaskCreate(TaskFlowLED,(void *)0, &TaskFlowLEDStk[TaskStkLengh - 1], 7);//创建流水灯任务
	
		if(key==0)											//流水灯切换键按下
		{
			FlowCounter++;									//流水灯花样计数器加1
			if(FlowCounter>5)
				FlowCounter=0;								//计数器清零	
		}
		
		if(key==10)											//RST键按下
		{
			IO2SET = LEDS8;									//熄灭所有LED
			OSTaskDel(7);									//删除任务TaskFlowLED
		}
					
	}
}

/*********************************************************************************************************
**                           TaskSwitchLED  开关LED任务
********************************************************************************************************/
void TaskSwitchLED(void *pdata)
{	INT8U i,temp;
	i=*(INT8U*)pdata;
	
	if((IO2PIN&LED[i])!=0)	  					//取反LED状态
		IO2CLR=LED[i];	
	else
		IO2SET=LED[i];
	temp=~(IO2PIN>>16)&0xff;					//LED当前显示情况
	OSTaskCreate(TaskSend,(void *)&temp, &TaskSendStk[TaskStkLengh - 1], 8);	//创建模拟LED显示任务
	OSTaskDel(OS_PRIO_SELF);					//删除任务自己	
}

/*********************************************************************************************************
**                           TaskFlowLED  流水灯任务
********************************************************************************************************/
void TaskFlowLED(void *pdata)
{	uint8 j,temp;	
	pdata=pdata;
	for(;;)
	{
		for(j=0;j<8;j++)						//流水灯执行一遍
		{	
			IO2SET = ~((LED_TBL[FlowCounter][j])<<16);
			temp=~(IO2PIN>>16)&0xff;			//LED当前显示情况
			OSTaskCreate(TaskSend,(void *)&temp, &TaskSendStk[TaskStkLengh - 1], 8);//创建串口发送任务
			OSTimeDlyHMSM (0,0,0,250);			//延时250ms
			
			IO2CLR = ((LED_TBL[FlowCounter][j])<<16);
			temp=~(IO2PIN>>16)&0xff;			//LED当前显示情况
			OSTaskCreate(TaskSend,(void *)&temp, &TaskSendStk[TaskStkLengh - 1], 8);//创建串口发送任务
			OSTimeDlyHMSM (0,0,0,250);			//延时250ms
		}	
		
	}
}

/*********************************************************************************************************
**                            Task1 任务1 串口模拟LED显示
********************************************************************************************************/
void TaskSend(void *pdata)
{	uint8 i,err,send[]={0xff,0x80,8,0,0};
	send[3]=*(uint8 *)pdata;					//更新待发送数据
	U0IER=U0IER|0x02;							//使能THER中断
	for(i=0;i<5;i++)							//一次发送5字节数据
		U0THR=send[i];							//写入THR寄存器
	OSSemPend(Send_sem,0,&err);					//等待信号量
	U0IER=U0IER&~0x02;							//关闭THRE中断
	OSTaskDel(OS_PRIO_SELF);					//删除任务自己	
}

/********************************************************************************************************
** 函数名称 :UART0Init()
** 函数功能 :串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率115200。
** 入口参数 :无
** 出口参数 :无
********************************************************************************************************/
void UART0Init(void)
{
	uint16 Fdiv;
	PINSEL0 = (PINSEL0&(~0x0F))|0x05;			//设置UART0引脚连接P0.0和P0.1
	U0LCR = 0x83;								//DLAB=1,允许设置波特率,设置为8位字符长度
	Fdiv  = (Fpclk / 16) / UART_BPS;			//设置波特率
	U0DLM = Fdiv / 256;
	U0DLL = Fdiv % 256;
	U0LCR = 0x03;//DLAB=0,禁止访问除数锁存器,设置为8位字符长度,做到仅修改欲设置的位,无关位不受影响
	U0FCR = 0x01;								//使能FIFO,设置触发点为1个字符
	U0IER = 0x03;								//允许RBR中断,即接收中断;允许THRE中断	
}

/********************************************************************************************************
** 函数名称 :UART0_Exception()
** 函数功能 :UART0中断服务程序,RDA和THRE中断
** 入口参数 :无
** 出口参数 :无
********************************************************************************************************/
void UART0_Exception(void)
{	uint8 IIR;												//定义局部变量,用于读取中断标志寄存器
	static uint8 rcv_buf;									//定义静态局部变量,接收串口数据
	while(((IIR=U0IIR)&0x01)==0)							//中断处理完毕后退出
	{	OS_ENTER_CRITICAL();								//关中断
		switch(IIR&0x0e)									//判别中断源
		{
			case 0x02:										//THRE中断
						VICVectAddr = 0x00;					//向量中断处理结束
						OS_EXIT_CRITICAL();
						OSSemPost(Send_sem);				//发送信号量send_sem
						break;
			case 0x04:										//RDA中断
						rcv_buf = U0RBR;					//读取FIFO中的数据,清RDA中断标志
						VICVectAddr = 0x00;					//向量中断处理结束
						OS_EXIT_CRITICAL();
						OSMboxPost(Rcv_box,(void*)&rcv_buf);//发送消息给串口数据处理任务	
						break;
			default:    break;
		}
	}			
								
} 
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -