[STM32] STM32裸机实现多任务管理可以吗?

[复制链接]
4944|18
 楼主| shenjinliang02 发表于 2018-9-17 17:33 | 显示全部楼层 |阅读模式
目前在用STM32做控制芯片,使用一个232串口接工业触摸屏,需要向触摸屏发送编码器的数据,但编码器在运行时,触摸屏再按下经常不起作用,但编码器不运行时,就可以。同时,还有一个485通讯,连接外围伺服控制。目前主要就是在编码器计数时,触摸屏发送与接受不能及时反应甚至不起作用。请问大家,有什么好的方法来解决,在不使用系统的情况下
dabing89 发表于 2018-9-17 20:57 | 显示全部楼层
先用串口软件把数据发出来看看,看看单片机发出来了不?你获取触摸屏按键对应按下的MODBUS指令,在串口里给单片机发,看看他回不回?如果手动都不行的话,基本是单片机端的问题
zxq6 发表于 2018-9-17 22:24 来自手机 | 显示全部楼层
估计程序里面死等太多了导致。多任务都是用状态机来切换的。不能死等。
mailshichao 发表于 2018-9-18 08:14 | 显示全部楼层
这个任务不算多,分开调试一下就清楚了
 楼主| shenjinliang02 发表于 2018-9-18 08:23 | 显示全部楼层
dabing89 发表于 2018-9-17 20:57
先用串口软件把数据发出来看看,看看单片机发出来了不?你获取触摸屏按键对应按下的MODBUS指令,在串口里给 ...

只运行某按键触摸屏部分是正常的,既向单片机发送部分,当实时传输编码器数值时,再按键有时候不起作用,需要多次按才可以。
 楼主| shenjinliang02 发表于 2018-9-18 08:25 | 显示全部楼层
zxq6 发表于 2018-9-17 22:24
估计程序里面死等太多了导致。多任务都是用状态机来切换的。不能死等。

我是用串口的空闲中断来检测接受,接受标志置为后,再出来接受的数据。
fswyt 发表于 2018-9-18 10:03 | 显示全部楼层
里面涉及到延时时,不要阻塞等待
 楼主| shenjinliang02 发表于 2018-9-18 13:21 | 显示全部楼层
fswyt 发表于 2018-9-18 10:03
里面涉及到延时时,不要阻塞等待

有什么好的办法吗?
fly1974 发表于 2018-9-18 13:59 | 显示全部楼层
stm32有些芯片有专用编码器接口,应该是很少占用单片机资源的!
qinlu123 发表于 2018-9-18 14:20 | 显示全部楼层
把代码用状态机做成非阻塞的就可以多任务,虽然这样写起来累但是用起来爽。
fswyt 发表于 2018-9-18 15:46 | 显示全部楼层
shenjinliang02 发表于 2018-9-18 13:21
有什么好的办法吗?

里面很多人都说了,用状态机就行
caijie001 发表于 2018-9-18 21:10 | 显示全部楼层
随便写个时间片轮询的,,或者直接上os
Ketose 发表于 2018-9-19 09:32 | 显示全部楼层
这个要看你的代码怎么写的。
读编码器不能斯等。最后贴代码。
Ryanhsiung 发表于 2018-9-19 16:21 | 显示全部楼层
当然可以,你可以这么理解  操作系统也是写在裸奔系统上的
jinzhan0132 发表于 2018-9-19 18:02 | 显示全部楼层
状态机加时间片,就能搞定了。
lvface123654 发表于 2018-9-19 19:43 | 显示全部楼层
可以啊,你现在用的模式是大循环模式,即前后台模式,你可以用状态机把实现一个功能的过程全部拆解,然后代码里不要让CPU空转。需要延迟的话要用定时器中断加状态机来做,多个任务,可以做多个状态机。上OS当然最好了,也可以用时间片轮询。我刚做了一个项目比你这个需求要求多了些,也没有OS,做出来效果也很好
 楼主| shenjinliang02 发表于 2018-9-20 09:44 | 显示全部楼层
lvface123654 发表于 2018-9-19 19:43
可以啊,你现在用的模式是大循环模式,即前后台模式,你可以用状态机把实现一个功能的过程全部拆解,然后代 ...

能发下你的简单程序看看嘛?没有用过状态机。
ddllxxrr 发表于 2018-9-20 09:50 | 显示全部楼层
用中断啊
xad74 发表于 2018-9-20 16:38 | 显示全部楼层
****小小调度器开始**********************************************/
#ifndef _Task_H_
#define _Task_H_

#define MAXTASKS 6

//volatile
//extern volatile unsigned char timers[MAXTASKS];
#define _SS static unsigned char _lc=0; switch(_lc){default:
#define _EE ;}; _lc=0; return 255;
#define WaitX(tickets) do {_lc=(__LINE__%255)+1; return tickets ;} while(0); case (__LINE__%255)+1:
#define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); } while(0);
#define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} } //前面的任务优先保证执行
#define CallSub(SubTaskName) do {unsigned char currdt; _lc=(__LINE__%255)+1; return 0; case (__LINE__%255)+1: currdt=SubTaskName;if(currdt!=255) return currdt;} while(0); //和上面是同一行,因为一行显示不下了,里面有 return 0,在执行子函数前释放了一下 CPU
#define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
#define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}
#define SEM unsigned char
//初始化信号量
#define InitSem(sem) sem=0;
//等待信号量
#define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0); //里面有WaitX(0),执行的时候释放了一下 CPU
//等待信号量或定时器溢出, 定时器 tickets 最大为 0xFFFE
#define WaitSemX(sem,tickets) do { sem=tickets+1; WaitX(0); if(sem>1){ sem--; return 1;} } while(0); //里面有 WaitX(0),执行的时候释放了一下 CPU
//发送信号量
#define SendSem(sem) do {sem=0;} while(0);
//延时执行某进程
#define WaitTask(TaskID,Time)   timers[TaskID] = Time
//激活进程
#define ActTask(TaskID)  timers[TaskID] = 1
//停止进程
#define StopTask(TaskID)  timers[TaskID] = 255
//暂停执行
#define PauseSelf(); WaitX(255)
/*****小小调度器结束**********************************************************************/
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部