二,应用实例
1、将串口中断接收到的数据发送给串口接收数据处理任务
USART1_IRQHandler.c
//串口1中断处理程序
void USART1_IRQHandler(void) //串口1中断服务程序
{
OS_ERR err;
OSIntEnter(); //通知UCOS进入中断
//发送缓冲区空中断
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {
USART_SendData(USART1, *pTxBufRead);//向串口发送缓冲区写入一个字节
if((pTxBufRead++) == &Usart1TxBuf[USART1_TX_BUFFER_LEN - 1]){ //读到最后一个字节
pTxBufRead = Usart1TxBuf; //移动读指针到第首地址
}
if(pTxBufRead == pTxBufWrite){ //若读写指针相等,表明本次缓冲区数据已经读完
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//关闭中断
}
OSSemPost(&Usart1TxBufSem, OS_OPT_POST_1, &err); //释放缓冲区信号量
}
//串口接收到数据中断
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
*pRxBufWrite = USART_ReceiveData(USART1); //读取一个字节到缓冲区
OSTaskQPost(&Usart1RxTaskTCB, pRxBufWrite, 1, OS_OPT_POST_FIFO, &err); //发送该字节所在缓冲区的地址到消息队列,等待任务处理
if((pRxBufWrite++) == &Usart1RxBuf[USART1_RX_BUFFER_LEN - 1]){ //若当前写指针写到缓冲区最后一个地址
pRxBufWrite = Usart1RxBuf; //写指针更新为缓冲区第一个地址,环形队列
}
}
OSIntExit(); //通知UCOS退出中断
}
USART1_IRQHandler.c
我们仅来分析串口1中断处理程序,这里将接收到的数据传递给指针,再用任务内建消息将指针地址传给任务。
Usart1RxTask.c
static void Usart1RxTask (void *p_arg)
{
OS_ERR err;
CPU_TS ts;
void *p_msg;
CPU_INT08U ch;
OS_MSG_SIZE msg_size;
(void)p_arg;
while (DEF_TRUE) {
p_msg = OSTaskQPend(0, OS_OPT_PEND_BLOCKING, &msg_size, &ts, &err);
if(err == OS_ERR_NONE)
{
ch = *((CPU_INT08U *)p_msg);
usart1SendData(ch); //STM32接收到串口发送到32上的数据,并通过串口发送发送到电脑上显示!
}
}
}
Usart1RxTask.c
可以看出,我们从OSTaskQPend取出消息地址赋给空指针p_msg,再将空指针强制类型转换指向要指向的字节,并将其取出来赋给ch。这样就完成了任务消息传递。
2、DMA中断数据传输给指定任务处理
DMA1_Channel1_IRQHandler.c
void DMA1_Channel1_IRQHandler()
{
OS_ERR err;
OSIntEnter(); //通知UCOS进入中断
if(DMA_GetITStatus(DMA1_IT_TC1)) //通道1传输完成中断
{
TIM_Cmd(TIM2, DISABLE);
DMA_ClearITPendingBit(DMA1_IT_GL1); //清除全部中断标志 通道1全局中断
OSTaskQPost(&maintaskTCB,Single_ADC_RegularConvertedValueTab,2, OS_OPT_POST_FIFO, &err); //发送该字节所在缓冲区的地址到消息队列,等待任务处理
TIM_Cmd(TIM2, ENABLE);
}
OSIntExit(); //通知UCOS退出中断
}
DMA1_Channel1_IRQHandler.c
这里将DMA数组的首地址进行传输给相应任务。
void Maintask.c
static void Maintask(void *p_arg)
{
OS_ERR err;
u16 i = 0;
u32 total = 0;
static u16 index_count,index_count1;
// static u16 start_offset_voltage;
static u8 Up_Target_Flag;
static u16 Count_Up,Count_Down;
CPU_TS ts;
CPU_INT16U *p_msg;
OS_MSG_SIZE msg_size;
(void)p_arg;
while (DEF_TRUE)
{
p_msg = (u16 *)OSTaskQPend(0, OS_OPT_PEND_BLOCKING, &msg_size, &ts, &err);
if(err == OS_ERR_NONE)
{
for(i=0;i < ADC_TAB_LENGTH_ONE;i++)
{
printf("%d\n",*p_msg);
total += *p_msg++;
}
total=0;
Single_ADC_Average = total / ADC_TAB_LENGTH_ONE;
printf("%d\n",Single_ADC_Average);
void Maintask.c
首先将OSTaskQPend(0, OS_OPT_PEND_BLOCKING, &msg_size, &ts, &err)返回的空指针强制类型转换成u16类型赋给指针变量p_msg,再将指针自加取出所有数据。
|