OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4585|回复: 11

ucos使用中断的问题

[复制链接]

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-3-3
在线时间
15 小时
发表于 2016-4-27 16:40:55 | 显示全部楼层 |阅读模式
1金钱
不好意思,又来叨扰了,我基于ucos2写了一个程序,实现PC12中断输入,控制PC13灯亮一分钟,但是实际上并不好使,还请大家帮我分析一下,给我一点建议
#include "includes.h"
/************************优先级定义**************************************/
#define task_start_prio 4
/**********************堆栈大小定义**************************************/
#define task_start_stack_size 80
static  OS_STK    task_start_stack[task_start_stack_size];
/************************主函数******************************************/
int main(void)
{
    HAL_Init();
    gpio_init();
    BSP_Init();
    OSInit();
    OSTaskCreate(task_start,(void *)0,(OS_STK *)&task_start_stack[task_start_stack_size-1],task_start_prio);
    OSStart();
    return 0;
}
/***********************初始化外设**************************************/
void gpio_init(void)
      {
            __HAL_RCC_GPIOC_CLK_ENABLE();

            GPIO_InitTypeDef  GPIO_Initstruct_pc13;
            GPIO_Initstruct_pc13.Mode=GPIO_MODE_OUTPUT_PP;
            GPIO_Initstruct_pc13.Pin=GPIO_PIN_13;
            GPIO_Initstruct_pc13.Pull=GPIO_PULLUP;
            GPIO_Initstruct_pc13.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
            HAL_GPIO_Init(GPIOC,&GPIO_Initstruct_pc13);
      }
void exti_init(void)
      {
            __HAL_RCC_SYSCFG_CLK_ENABLE();
            GPIO_InitTypeDef  GPIO_Initstruct_pc12;
            GPIO_Initstruct_pc12.Mode=GPIO_MODE_IT_RISING;
            GPIO_Initstruct_pc12.Pin=GPIO_PIN_12;
            GPIO_Initstruct_pc12.Pull=GPIO_PULLDOWN;
            GPIO_Initstruct_pc12.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
            HAL_GPIO_Init(GPIOC,&GPIO_Initstruct_pc12);
      }
void nvic_init()
      {
            HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
            HAL_NVIC_SetPriority(EXTI15_10_IRQn,0,15);
            HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
      }
/************************建立任务***************************************/
void  task_start (void *p_arg)
{
    (void)p_arg;
          {
                while(1)
                      {
                            HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
                      }
          }
}
void EXTI15_10_IRQHandler(void)
      {
            HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
      }
void  HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      {
            OSIntEnter();
            HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
            OSTimeDlyHMSM(0,1,0,0);
            OSIntExit();
      }
/**********************************************************************/





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-27 16:45:36 | 显示全部楼层
你把nvic_init这个函数都贴出来了,却没有在任何地方调用它

回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-3-3
在线时间
15 小时
 楼主| 发表于 2016-4-27 16:48:07 | 显示全部楼层
特朗姆斯 发表于 2016-4-27 16:45
你把nvic_init这个函数都贴出来了,却没有在任何地方调用它

谢谢,可是我在主函数里调用了之后,还是没有效果是怎么回事呢
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-27 16:55:03 | 显示全部楼层
hellcatembert 发表于 2016-4-27 16:48
谢谢,可是我在主函数里调用了之后,还是没有效果是怎么回事呢

你的代码看不到的函数信息太多了,没法判断。

只能说建议的调试思路是:一小个功能一小个功能这样子来,你所有的东西整在一起排错就很困难了。
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-3-3
在线时间
15 小时
 楼主| 发表于 2016-4-27 17:00:46 | 显示全部楼层
特朗姆斯 发表于 2016-4-27 16:55
你的代码看不到的函数信息太多了,没法判断。

只能说建议的调试思路是:一小个功能一小个功能这样子来 ...

我这个是先没有系统成功了,然后再移植到ucos上的,但是经过我的排查,好像始终进不去中断,不知道你有没有好的建议呢,谢谢了。
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-27 17:17:47 | 显示全部楼层
hellcatembert 发表于 2016-4-27 17:00
我这个是先没有系统成功了,然后再移植到ucos上的,但是经过我的排查,好像始终进不去中断,不知道你有没 ...

你先把系统和外部中断功能分开来调,你现在调好系统了,那在裸机里面有没有调好外部中断的功能?如果两个功能分开调都ok了再合到一起发现不行,那么问题就很清楚,就是移植的时候出错,这时候再思考为什么UCOS系统下怎么实现外部中断。
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-3-3
在线时间
15 小时
 楼主| 发表于 2016-4-28 14:55:10 | 显示全部楼层
本帖最后由 hellcatembert 于 2016-4-28 14:56 编辑
特朗姆斯 发表于 2016-4-27 17:17
你先把系统和外部中断功能分开来调,你现在调好系统了,那在裸机里面有没有调好外部中断的功能?如果两个 ...

真的很不好意思,又来麻烦了,我在裸机里面调试成功了,ucos里面的中断调用也是按照格式写的,但是还是进不去中断。不知道,你能不能受累给分析一下呢。这个是中断函数的代码,void EXTI15_10_IRQHandler()
      {
            OSIntEnter();
            HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
            OSIntExit();
      }
void  HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      {
            HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
            HAL_Delay(100000);//这个函数是我重写的,已经验证没有问题。
      }

真的很谢谢你。

回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-28 15:20:05 | 显示全部楼层
void  HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      {
            HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
            HAL_Delay(100000);//这个函数是我重写的,已经验证没有问题。
      }

你把GPIO_PIN_RESET改成GPIO_PIN_SET试试呢
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-28 15:27:35 | 显示全部楼层
因为是UCOS系统你要考虑到任务调度的问题, 你的task_start这个任务是一直在运行的,所以其实你的程序一直在执行HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);这个操作。这和你想要点亮灯1s的目的相违背。

关于你想要实现的功能我大致给你一个思路:
1. 初始化PC13的时候先灯灭。
2. 创建一个新的任务,在任务中不断地判断一个全局变量标志(flag),如果标志被置位就亮灯,然后延迟1秒钟之后暗灯。
3. PC12的中断服务程序里置位flag标志。
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-3-3
在线时间
15 小时
 楼主| 发表于 2016-4-28 16:29:17 | 显示全部楼层
特朗姆斯 发表于 2016-4-28 15:27
因为是UCOS系统你要考虑到任务调度的问题, 你的task_start这个任务是一直在运行的,所以其实你的程序一直 ...

你的意思是,一个任务运行,操作系统根本不会进入中断是么,好像不管我用什么方式,始终进不去中断
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-4-28 16:35:36 | 显示全部楼层
hellcatembert 发表于 2016-4-28 16:29
你的意思是,一个任务运行,操作系统根本不会进入中断是么,好像不管我用什么方式,始终进不去中断

。。。

我的意思是:即使你进了中断亮灯了,中断结束后回到start_task这个任务,你又把灯灭了
回复

使用道具 举报

7

主题

188

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2282
金钱
2282
注册时间
2013-12-16
在线时间
448 小时
发表于 2016-4-29 10:07:18 | 显示全部楼层
本帖最后由 zdfwyh 于 2016-4-29 10:09 编辑

楼上是对的,有操作系统的情况下延时函数是会被强制打断去执行任务程序的.除非你在延时时关了中断,但这将严重破坏系统实时性,严重时会导致崩溃,在中断中加延时本身也是不允许的,必须要保证系统实时性,中断服务必须短小精悍,省时,做完就走.

void  HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      {
            LED=1;
      }
void  task_start (void *p_arg)
{
    (void)p_arg;
          {
                while(1)
                      {
                           if(LED){ HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);LED=0;OSTimeDlyHMSM(0,1,0,0);}//点灯,延时1分钟
                          
                           HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//灭灯
                      }
          }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 03:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表