MDK编译测试 (分别在STM32F107和STM32F103芯片测试,分别调用了自带的库)
这是个帮助实现同步时间调度的程序,需要低层硬件的支持(定时器中断)。它本身利用定时器(TIM4),使一个特殊的变量“SliceTime”从0开始随时间增长(1/ms),一旦达到了指定的最大值,又回归到零,如此往复……任何一段循环的程序可以通过SLICE宏来间接检查自己是否在允许的时间片内,如果此时不被允许执行,就跳过这段程序。这段源代码的意义就在于实现简单实用的同步时间调度。异步任务可能引起“竞争条件”等一些复杂的问题,如果只需要一个简单的方案就可以解决问题,那么同步编程仍然是最好的选择,这时如果再需要一个简单算法来调度若干个密集型同步任务,那么这段源代码正好可以派上用场!
C用例:
PS.这样的算法应该算是时间片轮转调度算法的一个变化形式,“时间片”在一些文献中用“quantum”这个词来表示,这里则用了“slice”,不过概念上也不完全相同。
#include "test.h"
#include "slice.h"
void Wireless(void);
void FetchData(void);
struct sensordata{
short accx,accy,accz;
}SG;
int main(void)
{
Sys_Init();
SliceTimer_Init(500);
while(1){
FetchData();
Wireless();
}
}
void Wireless(void){
u8 tmp_buf[33];
SLICE(1,300){
LED1=0;
TX_Mode();
sprintf((char*)tmp_buf,"%d,%d,%d",(int)SG.accx,(int)SG.accy,(int)SG.accz);
if(NRF24L01_TxPacket(tmp_buf)==0);
LED1=1;
}
SLICE(301,500){
LED0=0;
RX_Mode();
if(NRF24L01_RxPacket(tmp_buf)==0)
{
tmp_buf[32]=0;
LCD_ShowString(60,170,tmp_buf);
}
LED0=1;
}
}
void FetchData(void){
static unsigned int giveups;
if(giveups>1000){
ADXL345_Read(&SG.accx,&SG.accy,&SG.accz);
LCD_ShowInt(92,70,SG.accx,6,16);
LCD_ShowInt(92,90,SG.accy,6,16);
LCD_ShowInt(92,110,SG.accz,6,16);
giveups=0;
}
else giveups++;
}
Slice.h
#ifndef __SLICE_H_
#define __SLICE_H_
#define SLICE(__s,__e) if(SliceTime>=(__s)&&SliceTime<=(__e))
extern volatile unsigned int SliceTime;
extern unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax);
#endif
Slice.c
#include "slice.h"
#include
volatile unsigned int SliceTime; //ms
unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax){
NVIC_InitTypeDef NVIC_InitStructure;
RCC->APB1ENR|=1<<2; //TIM4时钟使能
TIM4->ARR=10;//设定计数器自动重装值 10/10kHz=1ms
TIM4->PSC=7199;//预分频器7200
TIM4->DIER|=1<<0; //允许更新中断
TIM4->DIER|=1<<6; //允许触发中断
TIM4->CR1=0x8000;//ARPE使能
TIM4->CR1|=0x01; //使能定时器4
NVIC_InitStructure.NVIC_IRQChannel = 30; //TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
SliceTime=0;
SliceTimeMax=smax;
}
void TIM4_IRQHandler(void)
{
if(TIM4->SR&0X0001){
SliceTime++;
if(SliceTime>SliceTimeMax)SliceTime=0;
}
TIM4->SR&=~(1<<0);//清除中断标志位
}
MDK编译测试 (分别在STM32F107和STM32F103芯片测试,分别调用了自带的库)
这是个帮助实现同步时间调度的程序,需要低层硬件的支持(定时器中断)。它本身利用定时器(TIM4),使一个特殊的变量“SliceTime”从0开始随时间增长(1/ms),一旦达到了指定的最大值,又回归到零,如此往复……任何一段循环的程序可以通过SLICE宏来间接检查自己是否在允许的时间片内,如果此时不被允许执行,就跳过这段程序。这段源代码的意义就在于实现简单实用的同步时间调度。异步任务可能引起“竞争条件”等一些复杂的问题,如果只需要一个简单的方案就可以解决问题,那么同步编程仍然是最好的选择,这时如果再需要一个简单算法来调度若干个密集型同步任务,那么这段源代码正好可以派上用场!
C用例:
PS.这样的算法应该算是时间片轮转调度算法的一个变化形式,“时间片”在一些文献中用“quantum”这个词来表示,这里则用了“slice”,不过概念上也不完全相同。
#include "test.h"
#include "slice.h"
void Wireless(void);
void FetchData(void);
struct sensordata{
short accx,accy,accz;
}SG;
int main(void)
{
Sys_Init();
SliceTimer_Init(500);
while(1){
FetchData();
Wireless();
}
}
void Wireless(void){
u8 tmp_buf[33];
SLICE(1,300){
LED1=0;
TX_Mode();
sprintf((char*)tmp_buf,"%d,%d,%d",(int)SG.accx,(int)SG.accy,(int)SG.accz);
if(NRF24L01_TxPacket(tmp_buf)==0);
LED1=1;
}
SLICE(301,500){
LED0=0;
RX_Mode();
if(NRF24L01_RxPacket(tmp_buf)==0)
{
tmp_buf[32]=0;
LCD_ShowString(60,170,tmp_buf);
}
LED0=1;
}
}
void FetchData(void){
static unsigned int giveups;
if(giveups>1000){
ADXL345_Read(&SG.accx,&SG.accy,&SG.accz);
LCD_ShowInt(92,70,SG.accx,6,16);
LCD_ShowInt(92,90,SG.accy,6,16);
LCD_ShowInt(92,110,SG.accz,6,16);
giveups=0;
}
else giveups++;
}
Slice.h
#ifndef __SLICE_H_
#define __SLICE_H_
#define SLICE(__s,__e) if(SliceTime>=(__s)&&SliceTime<=(__e))
extern volatile unsigned int SliceTime;
extern unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax);
#endif
Slice.c
#include "slice.h"
#include
volatile unsigned int SliceTime; //ms
unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax){
NVIC_InitTypeDef NVIC_InitStructure;
RCC->APB1ENR|=1<<2; //TIM4时钟使能
TIM4->ARR=10;//设定计数器自动重装值 10/10kHz=1ms
TIM4->PSC=7199;//预分频器7200
TIM4->DIER|=1<<0; //允许更新中断
TIM4->DIER|=1<<6; //允许触发中断
TIM4->CR1=0x8000;//ARPE使能
TIM4->CR1|=0x01; //使能定时器4
NVIC_InitStructure.NVIC_IRQChannel = 30; //TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
SliceTime=0;
SliceTimeMax=smax;
}
void TIM4_IRQHandler(void)
{
if(TIM4->SR&0X0001){
SliceTime++;
if(SliceTime>SliceTimeMax)SliceTime=0;
}
TIM4->SR&=~(1<<0);//清除中断标志位
}
举报