|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
#include "lcd.h"
#include "key.h"
#include "usmart.h"
#include "sram.h"
#include "malloc.h"
#include "tpad.h"
#include "beep.h"
#include "touch.h"
#include "includes.h"
/////////////////////////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);
//LED任务
//设置任务优先级
#define LED_TASK_PRIO 7
//设置任务堆栈大小
#define LED_STK_SIZE 64
//任务堆栈
OS_STK LED_TASK_STK[LED_STK_SIZE];
//任务函数
void led_task(void *pdata);
//触摸屏任务
//设置任务优先级
#define TOUCH_TASK_PRIO 6
//设置任务堆栈大小
#define TOUCH_STK_SIZE 128
//任务堆栈
OS_STK TOUCH_TASK_STK[TOUCH_STK_SIZE];
//任务函数
void touch_task(void *pdata);
//队列消息显示任务
//设置任务优先级
#define QMSGSHOW_TASK_PRIO 5
//设置任务堆栈大小
#define QMSGSHOW_STK_SIZE 128
//任务堆栈
OS_STK QMSGSHOW_TASK_STK[QMSGSHOW_STK_SIZE];
//任务函数
void qmsgshow_task(void *pdata);
//主任务
//设置任务优先级
#define MAIN_TASK_PRIO 4
//设置任务堆栈大小
#define MAIN_STK_SIZE 128
//任务堆栈
OS_STK MAIN_TASK_STK[MAIN_STK_SIZE];
//任务函数
void main_task(void *pdata);
//信号量集任务
//设置任务优先级
#define FLAGS_TASK_PRIO 3
//设置任务堆栈大小
#define FLAGS_STK_SIZE 128
//任务堆栈
OS_STK FLAGS_TASK_STK[FLAGS_STK_SIZE];
//任务函数
void flags_task(void *pdata);
//按键扫描任务
//设置任务优先级
#define KEY_TASK_PRIO 2
//设置任务堆栈大小
#define KEY_STK_SIZE 128
//任务堆栈
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数
void key_task(void *pdata);
//////////////////////////////////////////////////////////////////////////////
OS_EVENT * msg_key; //按键邮箱事件块
OS_EVENT * q_msg; //消息队列
OS_TMR * tmr1; //软件定时器1
OS_TMR * tmr2; //软件定时器2
OS_TMR * tmr3; //软件定时器3
OS_FLAG_GRP * flags_key; //按键信号量集
void * MsgGrp[256]; //消息队列存储地址,最大支持256个消息
//软件定时器1的回调函数
//每100ms执行一次,用于显示CPU使用率和内存使用率
void tmr1_callback(OS_TMR *ptmr,void *p_arg)
{
static u16 cpuusage=0;
static u8 tcnt=0;
POINT_COLOR=BLUE;
if(tcnt==5)
{
LCD_ShowxNum(182,10,cpuusage/5,3,16,0); //显示CPU使用率
cpuusage=0;
tcnt=0;
}
cpuusage+=OSCPUUsage;
tcnt++;
LCD_ShowxNum(182,30,my_mem_perused(SRAMIN),3,16,0); //显示内存使用率
LCD_ShowxNum(182,50,((OS_Q*)(q_msg->OSEventPtr))->OSQEntries,3,16,0X80);//显示队列当前的大小
}
//软件定时器2的回调函数
void tmr2_callback(OS_TMR *ptmr,void *p_arg)
{
static u8 sta=0;
switch(sta)
{
case 0:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,RED);
break;
case 1:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,GREEN);
break;
case 2:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,BLUE);
break;
case 3:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,MAGENTA);
break;
case 4:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,GBLUE);
break;
case 5:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,YELLOW);
break;
case 6:
LCD_Fill(131,221,lcddev.width-1,lcddev.height-1,BRRED);
break;
}
sta++;
if(sta>6)sta=0;
}
//软件定时器3的回调函数
void tmr3_callback(OS_TMR *ptmr,void *p_arg)
{
u8* p;
u8 err;
static u8 msg_cnt=0; //msg编号
p=mymalloc(SRAMIN,13); //申请13个字节的内存
if(p)
{
sprintf((char*)p,"ALIENTEK %03d",msg_cnt);
msg_cnt++;
err=OSQPost(q_msg,p); //发送队列
if(err!=OS_ERR_NONE) //发送失败
{
myfree(SRAMIN,p); //释放内存
OSTmrStop(tmr3,OS_TMR_OPT_NONE,0,&err); //关闭软件定时器3
}
}
}
//加载主界面
void ucos_load_main_ui(void)
{
LCD_Clear(WHITE); //清屏
POINT_COLOR=RED; //设置字体为红色
LCD_ShowString(10,10,200,16,16,"Explorer STM32");
LCD_ShowString(10,30,200,16,16,"UCOSII TEST3");
LCD_ShowString(10,50,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(10,75,240,16,16,"TPAD:TMR2 SW KEY_UP:ADJUST");
LCD_ShowString(10,95,240,16,16,"KEY0S0 KEY1 SW KEY2:CLR");
LCD_DrawLine(0,70,lcddev.width,70);
LCD_DrawLine(130,0,130,70);
LCD_DrawLine(0,120,lcddev.width,120);
LCD_DrawLine(0,220,lcddev.width,220);
LCD_DrawLine(130,120,130,lcddev.height);
LCD_ShowString(5,125,240,16,16,"QUEUE MSG");//队列消息
LCD_ShowString(5,150,240,16,16,"Message:");
LCD_ShowString(5+130,125,240,16,16,"FLAGS");//信号量集
LCD_ShowString(5,225,240,16,16,"TOUCH"); //触摸屏
LCD_ShowString(5+130,225,240,16,16,"TMR2"); //队列消息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(150,10,200,16,16,"CPU: %");
LCD_ShowString(150,30,200,16,16,"MEM: %");
LCD_ShowString(150,50,200,16,16," Q :000");
delay_ms(300);
}
int main(void)
{
Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
delay_init(168); //延时初始化
uart_init(84,115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //初始化LCD
BEEP_Init(); //蜂鸣器初始化
KEY_Init(); //按键初始化
TPAD_Init(8); //初始化TPAD
my_mem_init(SRAMIN); //初始化内部内存池
tp_dev.init(); //初始化触摸屏
ucos_load_main_ui(); //加载主界面
OSInit(); //初始化UCOSII
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//画水平线
//x0,y0:坐标
//len:线长度
//color:颜色
void gui_draw_hline(u16 x0,u16 y0,u16 len,u16 color)
{
if(len==0)return;
LCD_Fill(x0,y0,x0+len-1,y0,color);
}
//画实心圆
//x0,y0:坐标
//r:半径
//color:颜色
void gui_fill_circle(u16 x0,u16 y0,u16 r,u16 color)
{
u32 i;
u32 imax = ((u32)r*707)/1000+1;
u32 sqmax = (u32)r*(u32)r+(u32)r/2;
u32 x=r;
gui_draw_hline(x0-r,y0,2*r,color);
for (i=1;i<=imax;i++)
{
if ((i*i+x*x)>sqmax)// draw lines from outside
{
if (x>imax)
{
gui_draw_hline (x0-i+1,y0+x,2*(i-1),color);
gui_draw_hline (x0-i+1,y0-x,2*(i-1),color);
}
x--;
}
// draw lines from inside (center)
gui_draw_hline(x0-x,y0+i,2*x,color);
gui_draw_hline(x0-x,y0-i,2*x,color);
}
}
//两个数之差的绝对值
//x1,x2:需取差值的两个数
//返回值:|x1-x2|
u16 my_abs(u16 x1,u16 x2)
{
if(x1>x2)return x1-x2;
else return x2-x1;
}
//画一条粗线
//(x1,y1),(x2,y2):线条的起始坐标
//size:线条的粗细程度
//color:线条的颜色
void lcd_draw_bline(u16 x1, u16 y1, u16 x2, u16 y2,u8 size,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
if(x1<size|| x2<size||y1<size|| y2<size)return;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if(delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平线
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//画线输出
{
gui_fill_circle(uRow,uCol,size,color);//画点
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
u8 err;
pdata = pdata;
msg_key=OSMboxCreate((void*)0); //创建消息邮箱
q_msg=OSQCreate(&MsgGrp[0],256); //创建消息队列
flags_key=OSFlagCreate(0,&err); //创建信号量集
OSStatInit(); //初始化统计任务.这里会延时1秒钟左右
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);
OSTaskCreate(touch_task,(void *)0,(OS_STK*)&TOUCH_TASK_STK[TOUCH_STK_SIZE-1],TOUCH_TASK_PRIO);
OSTaskCreate(qmsgshow_task,(void *)0,(OS_STK*)&QMSGSHOW_TASK_STK[QMSGSHOW_STK_SIZE-1],QMSGSHOW_TASK_PRIO);
OSTaskCreate(main_task,(void *)0,(OS_STK*)&MAIN_TASK_STK[MAIN_STK_SIZE-1],MAIN_TASK_PRIO);
OSTaskCreate(flags_task,(void *)0,(OS_STK*)&FLAGS_TASK_STK[FLAGS_STK_SIZE-1],FLAGS_TASK_PRIO);
OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
//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;
}
}
}
//触摸屏任务
void touch_task(void *pdata)
{
u32 cpu_sr;
u16 lastpos[2]; //最后一次的数据
while(1)
{
tp_dev.scan(0);
if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下
{
if(tp_dev.x[0]<(130-1)&&tp_dev.y[0]<lcddev.height&&tp_dev.y[0]>(220+1))
{
if(lastpos[0]==0XFFFF)
{
lastpos[0]=tp_dev.x[0];
lastpos[1]=tp_dev.y[0];
}
OS_ENTER_CRITICAL();//进入临界段,防止其他任务,打断LCD操作,导致液晶乱序.
lcd_draw_bline(lastpos[0],lastpos[1],tp_dev.x[0],tp_dev.y[0],2,RED);//画线
OS_EXIT_CRITICAL();
lastpos[0]=tp_dev.x[0];
lastpos[1]=tp_dev.y[0];
}
}else lastpos[0]=0XFFFF;//没有触摸
delay_ms(5);
}
}
//队列消息显示任务
void qmsgshow_task(void *pdata)
{
u8 *p;
u8 err;
while(1)
{
p=OSQPend(q_msg,0,&err);//请求消息队列
LCD_ShowString(5,170,240,16,16,p);//显示消息
myfree(SRAMIN,p);
delay_ms(500);
}
}
//主任务
void main_task(void *pdata)
{
u32 key=0;
u8 err;
u8 tmr2sta=1; //软件定时器2开关状态
u8 tmr3sta=0; //软件定时器3开关状态
u8 flagsclrt=0; //信号量集显示清零倒计时
tmr1=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC,(OS_TMR_CALLBACK)tmr1_callback,0,"tmr1",&err); //100ms执行一次
tmr2=OSTmrCreate(10,20,OS_TMR_OPT_PERIODIC,(OS_TMR_CALLBACK)tmr2_callback,0,"tmr2",&err); //200ms执行一次
tmr3=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC,(OS_TMR_CALLBACK)tmr3_callback,0,"tmr3",&err); //100ms执行一次
OSTmrStart(tmr1,&err);//启动软件定时器1
OSTmrStart(tmr2,&err);//启动软件定时器2
while(1)
{
key=(u32)OSMboxPend(msg_key,10,&err);
if(key)
{
flagsclrt=51;//500ms后清除
OSFlagPost(flags_key,1<<(key-1),OS_FLAG_SET,&err);//设置对应的信号量为1
}
if(flagsclrt)//倒计时
{
flagsclrt--;
if(flagsclrt==1)LCD_Fill(140,162,239,162+16,WHITE);//清除显示
}
switch(key)
{
case 1://控制DS1
LED1=!LED1;
break;
case 2://控制软件定时器3
tmr3sta=!tmr3sta;
if(tmr3sta)OSTmrStart(tmr3,&err);
else OSTmrStop(tmr3,OS_TMR_OPT_NONE,0,&err); //关闭软件定时器3
break;
case 3://清除
LCD_Fill(0,221,129,lcddev.height,WHITE);
break;
case 4://校准
OSTaskSuspend(TOUCH_TASK_PRIO); //挂起触摸屏任务
OSTaskSuspend(QMSGSHOW_TASK_PRIO); //挂起队列信息显示任务
OSTmrStop(tmr1,OS_TMR_OPT_NONE,0,&err); //关闭软件定时器1
if(tmr2sta)OSTmrStop(tmr2,OS_TMR_OPT_NONE,0,&err); //关闭软件定时器2
if((tp_dev.touchtype&0X80)==0)TP_Adjust();
OSTmrStart(tmr1,&err); //重新开启软件定时器1
if(tmr2sta)OSTmrStart(tmr2,&err); //重新开启软件定时器2
OSTaskResume(TOUCH_TASK_PRIO); //解挂
OSTaskResume(QMSGSHOW_TASK_PRIO); //解挂
ucos_load_main_ui(); //重新加载主界面
break;
case 5://软件定时器2 开关
tmr2sta=!tmr2sta;
if(tmr2sta)OSTmrStart(tmr2,&err); //开启软件定时器2
else
{
OSTmrStop(tmr2,OS_TMR_OPT_NONE,0,&err); //关闭软件定时器2
LCD_ShowString(148,262,240,16,16,"TMR2 STOP");//提示定时器2关闭了
}
break;
}
delay_ms(10);
}
}
//信号量集处理任务
void flags_task(void *pdata)
{
u16 flags;
u8 err;
while(1)
{
flags=OSFlagPend(flags_key,0X001F,OS_FLAG_WAIT_SET_ANY,0,&err);//等待信号量
if(flags&0X0001)LCD_ShowString(140,162,240,16,16,"KEY0 DOWN ");
if(flags&0X0002)LCD_ShowString(140,162,240,16,16,"KEY1 DOWN ");
if(flags&0X0004)LCD_ShowString(140,162,240,16,16,"KEY2 DOWN ");
if(flags&0X0008)LCD_ShowString(140,162,240,16,16,"KEY_UP DOWN");
if(flags&0X0010)LCD_ShowString(140,162,240,16,16,"TPAD DOWN ");
BEEP=1;
delay_ms(50);
BEEP=0;
OSFlagPost(flags_key,0X001F,OS_FLAG_CLR,&err);//全部信号量清零
}
}
//按键扫描任务
void key_task(void *pdata)
{
u8 key;
while(1)
{
key=KEY_Scan(0);
if(key==0)
{
if(TPAD_Scan(0))key=5;
}
if(key)OSMboxPost(msg_key,(void*)key);//发送消息
delay_ms(10);
}
} |
|