首先我们来看下下面两个图:
51单片机的内部结构框图
STM32内部框图
单片机内部包含众多硬件模块,相对单片机CPU来说这些就是外设(串口,GPIO,定时器,SPI, I2C等),就像我们的电脑主板一样,在CPU周围布置了很多外设(内存,硬盘,显卡,声卡,网卡等)。然后这些模块基本都是独立工作的,通过内部总线或I/O交互;既然是独立工作,那么就不会过多的占用CPU时钟,比如说定时器:我们设置好它的工作模式后,启动它,然后它就不停的按照我们设置的方式工作,到达状态后会有相应状态位可以检测,我们通过CPU主程序来检测标志位,同时执行相应操作;这种方式就像公司的一个组织架构一样,比如说你是老板,你交给你的直接下级去做一件事情,那么你老板是不是也要去做每个事情的细节呢?一个人你能亲历亲为,多个人呢?只是有一种特殊情况,如果我们作为中断用,那么再中断中就不要处理过多事情,因为中断实际是占用CPU时间运行的。
下面有个例子,希望能帮到您
用定时器实现4个LED不同频率的闪烁
Proteus原理图
代码:
/************ (C) COPYRIGHT 2016 wllis **************
*
* 文件名: RTOS_LED_Flash.c
* 描 述:通过简单的系统实现4个LED的不同频率的闪烁
* 作 者: wllis
* 日 期: 2016/02/04
*
* LED0->P0.0
* LED1->P0.1
* LED2->P0.2
* LED3->P0.3
*
****************************************************/
#include <reg52.h>
/*************** TYPEDEFINES ***********************/
typedef unsigned char UINT8;
typedef unsigned int UINT16;
// 系统全局变量
#define OS_CLOCK 12000000 // 系统晶振频率,单位Hz
#define TASK_CLOCK 200 // 任务中断节拍,单位Hz
#define TASK_MAX 4 // 任务数目
// 设置系统任务执行频度
#define TASK_DELAY0 TASK_CLOCK/1 // 每秒1次
#define TASK_DELAY1 TASK_CLOCK/2 // 每秒2次
#define TASK_DELAY2 TASK_CLOCK/4 // 每秒4次
#define TASK_DELAY3 TASK_CLOCK/8 // 每秒8次
/************** LED DEFINES ***********************/
sbit LED0 = P0^0;
sbit LED1 = P0^1;
sbit LED2 = P0^2;
sbit LED3 = P0^3;
/****************** Function defines **************/
void OS_Timer0_Init( void );
void OS_Task_Run( void (*ptask)() );
void OS_Run( void );
void task0( void );
void task1( void );
void task2( void );
void task3( void );
// 任务指针
void ( *const task[] )() = { task0,task1,task2,task3 };
// 系统任务执行频度参数
UINT8 Task_Delay[TASK_MAX];
/*
* 函数名:void main()
* 描 述:主函数
* 输 入:无
* 输 出:无
*/
void main()
{
// 端口初始化
LED0 = 1;
LED1 = 1;
LED2 = 1;
LED3 = 1;
// 开总中断
EA = 1;
OS_Timer0_Init(); // 系统定时器初始化
while(1)
{
OS_Run();
}
}
/*
* 函数名: void OS_Timer0_Init( void )
* 描 述:T/C0初始化函数
* 输 入:无
* 输 出:无
*/
void OS_Timer0_Init( void )
{
UINT8 i;
for( i=0;i<TASK_MAX;i++ )
{
Task_Delay[i] = 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)() )
* 描 述:系统任务调度函数
* 输 入:无
* 输 出:无
*/
void OS_Task_Run( void (*ptask)() )
{
(*ptask)();
}
/*
* 函数名:void OS_Run( void )
* 描 述:系统运行函数
* 输 入:无
* 输 出:无
*/
void OS_Run( void )
{
UINT8 i;
for ( i=0; i<TASK_MAX; i++ )
{
if ( Task_Delay[i] == 0 )
{
OS_Task_Run( task[i] );
break;
}
}
}
/*
* 函数名:void task0( void )
* 描 述:任务0函数
* 输 入:无
* 输 出:无
*/
void task0( void )
{
Task_Delay[0] = TASK_DELAY0;
LED0 = ~LED0;
}
/*
* 函数名:void task1( void )
* 描 述:任务1函数
* 输 入:无
* 输 出:无
*/
void task1( void )
{
Task_Delay[1] = TASK_DELAY1;
LED1 = ~LED1;
}
/*
* 函数名:void task2( void )
* 描 述:任务2函数
* 输 入:无
* 输 出:无
*/
void task2( void )
{
Task_Delay[2] = TASK_DELAY2;
LED2 = ~LED2;
}
/*
* 函数名:void task3( void )
* 描 述:任务3函数
* 输 入:无
* 输 出:无
*/
void task3( void )
{
Task_Delay[3] = TASK_DELAY3;
LED3 = ~LED3;
}
/*
* 函数名:void Timer0IRQ(void)
* 描 述:定时器T/C0中断函数
* 输 入:无
* 输 出:无
*/
void Timer0IRQ(void) interrupt 1
{
UINT8 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[i])
{
Task_Delay[i]--;
}
}
}
/*************** end of file *************************/