stm8并行多任务

2019-07-19 21:01发布

      现在手头有个小项目,遇到了些问题,请大神赐教!使用的芯片是stm8s207s8   整个系统包括:1、软件模拟的iic通讯,与触摸ic通讯,判断按键。2、与595通讯,控制按键灯。3、用uart1与语音ic通讯,实时控制播报语音。4、用uart3与指纹模块通讯,以一定频率采集指纹头上的指纹。5、使用一个io口与射频ic通讯,软件解码。     整个系统,需要实时扫描的就只有三个,即:扫描指纹、扫描射频卡、扫描按键。这三个封装函数我都有写好,因为这三个函数里面都涉及语音播报,语音播报是这样一个流程:发送一段指令码,控制语音ic播报指定的一段语音,语音ic成功接收到信号,会返回“ok”,播放完毕会返回“stop”。大家都知道语音播放需要一定时间,我现在写的语音通讯函数,直接用的while((UART1_SR&0X20)==0);这样写有一个坏处,接收这段语音如果有20s,单片机就只能在这等20s,什么别的事都做不了。
     另外,这个项目我启用了3个定时器,设置了相同的频率,把三个扫描函数分别放入一个定时器中断函数中,但我发现他们之间还是会有相互干扰,因为指纹扫描不需要很快1s扫描3次左右足够了,每当指纹通讯时,指纹模块的灯亮,此时如果你要是按密码键盘,根本没有任何反应,后来我就想,设置不同的指纹扫描频率,毕竟你在输入密码的时候,不可能同时输入指纹,只要有按键被按下,在一定时间内,指纹以5s一次扫描,过了这个设定的时间就以1s 3次的速度扫描。这样改良后,效果是比开始好了,但还是感觉有时候,会和扫描射频卡的函数,相冲突。
     其实自己的开发经验挺少的,刚毕业,一直都是裸奔,后来我就在网上查找,单片机跑小系统,并行多任务。大致了解了下ROTS_52,也就4个文件,挺小巧的,但我有些疑问,如果移植到我的项目中,在每个task中有延时该怎么处理,像语音通讯这种几秒中的等待该怎么处理。求大神指教!!!!
     /********************************
*FileName:         MAIN_C
*Author         :   JZHG1992
*Versions:         V1.0
*********************************/

#include "OS.h"


/************************************
*                 主函数
*************************************/

void main( void )
{
        uchar i;

        OS_Timer0_Init();         // 系统定时器时钟初始化
        EA = 1;                                          // 开总中断
        while(1)
        {
                for ( i=0; i<TASK_MAX; i++ )
                {
                        if ( Task_Delay == 0 )
                        {
                                OS_Task_Run( task );
                                break;
                        }
                }
        }                                                               
}


/********************************
*FileName:         OS_C
*Author         :   JZHG1992
*Versions:         V1.0
*********************************/

#include "OS.H"

/************************************
*                 系统任务执行频度参数
*************************************/

uchar Task_Delay[TASK_MAX];

/************************************
*                 系统定时器时钟初始化
*************************************/

void OS_Timer0_Init( void )
{
        uchar i;

        for ( i=0; i<TASK_MAX; i++ )
        {
                Task_Delay = 0;   // 复位系统任务执行频度参数               
        }
        TMOD = (TMOD&0xf0)|0x01; // 设置定时器0方式1
        TH0 = 256-(OS_CLOCK/TASK_CLOCK)/12/256; // 赋初值200Hz
        TL0 = 256-(OS_CLOCK/TASK_CLOCK)/12%256;
        TR0 = 1;  // 使能定时器0
        ET0 = 1;  // 使能定时器0中断
}

/************************************
*                 系统任务调度函数
*************************************/

void OS_Task_Run( void (*ptask)() )
{
        (*ptask)();
}

/************************************
*                 系统中断服务函数
*************************************/

void OS_ISR( void ) interrupt 1
{
        uchar i;

           TH0 = 256-(OS_CLOCK/TASK_CLOCK)/12/256; // 赋初值200Hz
        TL0 = 256-(OS_CLOCK/TASK_CLOCK)/12%256;
        for ( i=0; i<TASK_MAX; i++ )
        {
                if ( Task_Delay )Task_Delay --;
        }
}




/********************************
*FileName:         OS_H
*Author         :   JZHG1992
*Versions:         V1.0
*********************************/
/********************************
*系统原理:单片机定时器延时中断来产
*               生系统任务调度节拍,设置
*               各个任务的执行频度,来调
*               度各任务。以实现系统多线
*                   操作。
*********************************/
#ifndef _OS_H_
#define _OS_H_
#include<reg52.h>

/************************************
*                定义变量类型
*************************************/

#define uchar unsigned char         // 宏定义uchar
#define uint unsigned int         // 宏定义uint

/************************************
*                配置系统参数
*这里你可以根据你的需要修改
*************************************/

#define OS_CLOCK  12000000   // 系统晶振频率,单位Hz
#define TASK_CLOCK 200       // 任务中断节拍,单位Hz
#define TASK_MAX   2         // 任务数目

/************************************
*        系统任务外调函数与参数
*************************************/

extern uchar Task_Delay[TASK_MAX];        // 系统任务执行频度参数
extern void OS_Timer0_Init( void );       // 系统定时器时钟初始化
extern void OS_Task_Run( void(*ptask)()); // 系统任务调度函数
extern void ( *const task[] )();          // 获得任务指针

//-------------
#endif



/********************************
*FileName:         TASK_C
*Author         :   JZHG1992
*Versions:         V1.0
*********************************/

#include "OS.H"

/************************************
*                 设置系统任务执行频度
*************************************/

#define TASK_DELAY0 TASK_CLOCK/3   // 任务0的执行频度
#define TASK_DELAY1 TASK_CLOCK/1    // 任务1的执行频度

//--------------------------
// 演示用的端口

sbit LED0 = P1^0;
sbit LED1 = P1^1;

/************************************
*                 任务0函数
*************************************/

void task0( void )
{
        Task_Delay[0] = TASK_DELAY0;  // 设置任务执行度

        /* 你的任务 */
        LED0 = !LED0;
               
}

/************************************
*                 任务1函数
*************************************/

void task1( void )
{
        Task_Delay[1] = TASK_DELAY1;  // 设置任务执行度

        /* 你的任务 */
        LED1 = !LED1;
               
}

/************************************
*                 获得任务指针
*        添加你的任务指针
*************************************/

void ( *const task[] )() = { task0, task1 };





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
东北小辉辉
1楼-- · 2019-07-19 23:27
 精彩回答 2  元偷偷看……
东北小辉辉
2楼-- · 2019-07-20 00:21
 精彩回答 2  元偷偷看……
loudianxin
3楼-- · 2019-07-20 03:40
状态机和时间片能解决楼主的问题
心中
4楼-- · 2019-07-20 04:56
 精彩回答 2  元偷偷看……
螃蟹爱虫
5楼-- · 2019-07-20 07:31
帮顶。
东北小辉辉
6楼-- · 2019-07-20 12:12
本帖最后由 东北小辉辉 于 2016-11-25 10:57 编辑

还有,楼主要分清任务的轻重缓急,优先处理死线比较近的硬实时任务。至于非实时任务,可以搞一个缓冲buffer,等到CPU空闲的时候再执行。尽量把单片机的硬件资源榨取干净,通讯协议这些,能用硬件尽量用硬件,你这款单片机应该也有硬件I2C吧?实在不行,再用软件模拟,解码什么的,相信你能解决这个问题,加油。
其实这个问题已经与单片机无关了,是软件架构方面的问题,楼主最好在人多的区发一个帖子,看看大神怎么处理这种问题,我们也跟着学习一下,这个区发帖基本没人理。

一周热门 更多>