这个程序实现消息队列将AD采样值同时发给PC及键盘显示板,可是有个问题就是用sprintf时,定时器1的中断有点问题,键盘显示板不能显示。。
程序如下:
/********************************** "3+1"班专用easyARM2103的uc/OS II模板*********************************
程序的功能:通过按键发送一个信号量,使得灯亮灭一次
*********************************************************************************************************/
#include "main.h"
#include "stdlib.h"
#include "SPI.h"
#include "AD.h"
#include "UART.h"
#define KEY1 1<<16
#define QSIZE 16
#define LEN 20 //给PC显示数组的大小
OS_EVENT* sem;
OS_EVENT* q;
void* msg[QSIZE];
INT16U u=0;
INT16U counter=0;//记录下第几次采样
uint32 original=0;
uint32 i=0;
uint32 visual=0;//visual是需要显示的位
/*********************************************************************************************************
TASK0 任务优先级、堆栈设置及函数声明 用于触发一个信号量
*********************************************************************************************************/
#define TASKKEY_PRIO 7 /* 任务的优先级 */
#define TASKKEY_STACK_SIZE 64 /* 定义用户堆栈长度 */
OS_STK TASKKEY_STACK[TASKKEY_STACK_SIZE]; /* 定义任务0 堆栈 */
void TASKKEY(void *pdata); /* 声明任务0 */
/*********************************************************************************************************
TASK1 任务优先级、堆栈设置及函数声明 用于AD
*********************************************************************************************************/
#define TASKAD_PRIO 6 /* 任务的优先级 */
#define TASKAD_STACK_SIZE 64 /* 定义用户堆栈长度 */
OS_STK TASKAD_STACK[TASKAD_STACK_SIZE]; /* 定义任务1 堆栈 */
void TASKAD(void *pdata); /* 声明任务1 */
/*********************************************************************************************************
TASKRES 任务优先级、堆栈设置及函数声明 用于得到AD的结果,并用SPI发送至键盘显示板
*********************************************************************************************************/
#define TASKRES_PRIO 5 /* 任务的优先级 */
#define TASKRES_STACK_SIZE 64 /* 定义用户堆栈长度 */
OS_STK TASKRES_STACK[TASKRES_STACK_SIZE]; /* 定义任务1 堆栈 */
void TASKRES(void *pdata); /* 声明任务1 */
/*********************************************************************************************************
** Function name: main
** Descriptions: 主函数
** Input parameters: None
** output parameters: None
** Created Date: 2010-12-28
*********************************************************************************************************/
int main (void)
{
OSInit();
OSTaskCreate(TASKKEY,
(void *)0,
&TASKKEY_STACK[TASKKEY_STACK_SIZE-1],
TASKKEY_PRIO
);
OSTaskCreate(TASKAD,
(void*)0,
&TASKAD_STACK[TASKAD_STACK_SIZE-1],
TASKAD_PRIO
);
OSTaskCreate(TASKRES,
(void*)0,
&TASKRES_STACK[TASKRES_STACK_SIZE-1],
TASKRES_PRIO
);
OSStart();
return 0;
}
/*********************************************************************************************************/
void TASKKEY (void *pdata)
{
pdata = pdata;
IO0DIR &= ~KEY1; //按键为输入
while (1)
{
while((IO0PIN & KEY1) != 0) //等待按键按下
{
OSTimeDly(1); //延时一个节拍
}
OSSemPost(sem); //发送信号量
counter++;
//OSQPostOpt(q,&dly[i],OS_POST_OPT_BROADCAST); //发送消息,所有等待此邮箱的任务均获得消息
while((IO0PIN & KEY1) == 0) //等待按键释放
{
OSTimeDly(1); //延时一个节拍
}
}
}
/*********************************************************************************************************/
void TASKAD (void *pdata)
{
INT8U err_sem;
pdata = pdata;
//TargetInit (); //目标板初始化
//sem = OSSemCreate(0); //创建信号量,初始化为0
//q = OSQCreate(msg,QSIZE); //创建消息队列,长度为16条消息
ADInit();
while (1)
{
OSSemPend(sem,0,&err_sem); //等待消息
u = AD_res();
OSQPostOpt(q,&u,OS_POST_OPT_BROADCAST); //发送消息,所有等待此邮箱的任务均获得消息
}
}
/*********************************************************************************************************/
//中断服务程序
void Timer1_service(void)
{
T1IR = 0x01;
visual=DATA[i];//这是一个十进制的数
senddata(dm[visual]);//发送断码至数码管显示
senddata(wm[i]);
i=(i+1)%8;
VICVectAddr = 0; /* 通知中断控制器中断结束 */
//OSTimeTick();
}
//定时器0的初始化
void Timer1Init(void)
{
T1IR = 0xffffffff;
T1TCR = 0x03;
T1TC = 0;
T1MCR = 0x03;
T1MR0 = (Fpclk / 1000);
T1TCR = 0x01;
vicIrqFuncSet(5,1, (INT32U)Timer1_service);//设置为IRQ中断
}
void TASKRES (void *pdata)
{
INT8U err_q;
INT16U* pd;
char a[LEN];
pdata = pdata;
OS_ENTER_CRITICAL();
TargetInit (); //目标板初始化
Timer1Init();
SPI_INIT(); //SPI初始化
OS_EXIT_CRITICAL();
sem = OSSemCreate(0); //创建信号量,初始化为0
q = OSQCreate(msg,QSIZE); //创建消息队列,长度为16条消息
while (1)
{
pd = (INT16U*)OSQPend(q,0,&err_q); //等待消息
original=counter*10000 + *pd; //将采样次数放在前四位表示,所以乘以10000
part(original); //拆分原始数据
//sprintf(a,"%dth is %d/t",counter,*pd);
a[0] = counter/1000+'0';
a[1] = counter%1000/100+'0';
a[2] = counter%100/10+'0';
a[3] = counter%10+'0';
a[4] = 't';
a[5] = 'h';
a[6] = ' ';
a[7] = 'i';
a[8] = 's';
a[9] = ' ';
a[10] = *pd/1000+'0';
a[11] = *pd%1000/100+'0';
a[12] = *pd%100/10+'0';
a[13] = *pd%10+'0';
a[14] = ' ';
a[15] = ' ';
a[16] = ' ';
a[17] = ' ';
a[18] = ' ';
a[19] = ' ';
UART_SEND(a);
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/