现在手头有个小项目,遇到了些问题,请大神赐教!使用的芯片是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 };
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
还有,楼主要分清任务的轻重缓急,优先处理死线比较近的硬实时任务。至于非实时任务,可以搞一个缓冲buffer,等到CPU空闲的时候再执行。尽量把单片机的硬件资源榨取干净,通讯协议这些,能用硬件尽量用硬件,你这款单片机应该也有硬件I2C吧?实在不行,再用软件模拟,解码什么的,相信你能解决这个问题,加油。
其实这个问题已经与单片机无关了,是软件架构方面的问题,楼主最好在人多的区发一个帖子,看看大神怎么处理这种问题,我们也跟着学习一下,这个区发帖基本没人理。
一周热门 更多>