网站建设二次开发免费技能培训网
一、时基的介绍
如下图,每一个标志(Flag_1ms)就代表一个时基,在不同的时基下可以做不同的事情。
以下是对不同时基的处理,通过1ms进而生成1s的时基。
// 1ms处理if( Flag_1ms ){ // 1ms标志==1 1ms的时间到了Flag_1ms = 0; // 标志清零Cnt_1ms++;if( Cnt_1ms >= 10 ){ // 计数够10次Cnt_1ms = 0; // 计数器清零Flag_10ms = 1; // 置10ms的标志}}// 1ms处理结束// 10ms处理if( Flag_10ms ){ // 10ms标志==1 10ms的时间到了Flag_10ms = 0; // 标志清零Cnt_10ms++;if( Cnt_10ms >= 10 ){ // 计数够10次Cnt_10ms = 0; // 计数器清零Flag_100ms = 1; // 置100ms的标志}}// 10ms处理结束// 100ms处理if( Flag_100ms ){ // 100ms标志==1 100ms的时间到了Flag_100ms = 0; // 标志清零Cnt_100ms++;if( Cnt_100ms >= 10 ){ // 计数够10次Cnt_100ms = 0; // 计数器清零Flag_1s = 1; // 置1s的标志}// 指示灯的 左移 右移 输出函数// 每100ms调用一次funLED(); // }// 100ms处理结束// 1s处理if( Flag_1s ){ // 1s标志==1 1s的时间到了Flag_1s = 0; // 标志清零Cnt_1s++;Cnt_mode++;if( Cnt_mode >= 10 ){Cnt_mode = 0;mode = ~mode;}}// 1s处理结束
二、时基的应用
这种情况下的延时,CPU是不能做其他事情的。
但是如果放到时基里面去,每100ms执行一次,然后可以继续进行不同的事情。因此,用时基也可以达到软件延时一样的效果。
三、应用实例
/*======================================================================功能需求1、P1.5-P1.0指示灯左移或右移控制2、模式可随时切换 或 外部可修改 工作模式
======================================================================*/
/*======================================================================时基1、时基的基本概念2、时基下实现时序控制的方法3、任务拆解或打散4、控制接口实现的方法
======================================================================*/#include "STC12C5A60S2.H"
#include "c51_stdint.h"// 输出表
uint8_t code LED_TAB[ ] = { // 右移表 索引号加 // 索引号减 左移(uint8_t)(1 << 5), // 0(uint8_t)(1 << 4), // 1(uint8_t)(1 << 3), // 2(uint8_t)(1 << 2), // 3(uint8_t)(1 << 1), // 4(uint8_t)(1 << 0) // 5
};// 索引号
uint8_t Index = 0;// 模式 // 10秒切换一次
uint8_t mode = 0; // 0:右移// 1:左移uint8_t Cnt_mode = 0;uint8_t Cnt_LED = 0;// 指示灯的 左移 右移 输出函数
// 每100ms调用一次
void funLED( void ){P1 = ~LED_TAB[ Index ];Cnt_LED++;if( Cnt_LED >= 5 ){Cnt_LED = 0;if( mode ){ // 左移Index--; // 0-1 = 255 Index是无符号的数if( Index > 5 ){ // 越界处理Index = 5; // }}else{ // 右移Index++; if( Index > 5 ){ // 越界处理Index = 0; } }}
}延时
//void D100ms( void ){
// uint16_t i = 0;
// for( i = 0; i < 60000; i++ ){
//
// }
//}uint8_t Flag_1ms = 0;
uint8_t Cnt_1ms = 0;uint8_t Flag_10ms = 0;
uint8_t Cnt_10ms = 0;uint8_t Flag_100ms = 0;
uint8_t Cnt_100ms = 0;uint8_t Flag_1s = 0;
uint8_t Cnt_1s = 0;void Timer0_Init(void) //1000微秒@12.000MHz
{AUXR |= 0x80; //定时器时钟1T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0x20; //设置定时初始值TH0 = 0xD1; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时
}// 主程序
void main(void){ // 调用 定时器0 初始化Timer0_Init();// 开定时器T0 的中断ET0 = 1; // 开总中断EA = 1; while(1){ // 1ms处理if( Flag_1ms ){ // 1ms标志==1 1ms的时间到了Flag_1ms = 0; // 标志清零Cnt_1ms++;if( Cnt_1ms >= 10 ){ // 计数够10次Cnt_1ms = 0; // 计数器清零Flag_10ms = 1; // 置10ms的标志}}// 1ms处理结束// 10ms处理if( Flag_10ms ){ // 10ms标志==1 10ms的时间到了Flag_10ms = 0; // 标志清零Cnt_10ms++;if( Cnt_10ms >= 10 ){ // 计数够10次Cnt_10ms = 0; // 计数器清零Flag_100ms = 1; // 置100ms的标志}}// 10ms处理结束// 100ms处理if( Flag_100ms ){ // 100ms标志==1 100ms的时间到了Flag_100ms = 0; // 标志清零Cnt_100ms++;if( Cnt_100ms >= 10 ){ // 计数够10次Cnt_100ms = 0; // 计数器清零Flag_1s = 1; // 置1s的标志}// 指示灯的 左移 右移 输出函数// 每100ms调用一次funLED(); // }// 100ms处理结束// 1s处理if( Flag_1s ){ // 1s标志==1 1s的时间到了Flag_1s = 0; // 标志清零Cnt_1s++;Cnt_mode++;if( Cnt_mode >= 10 ){Cnt_mode = 0;mode = ~mode;}}// 1s处理结束 }}// 中断服务程序 T0的
// 关键字 中断号 关键字 工作寄存器组
void ISR_T0( void ) interrupt 1 using 0
{Flag_1ms = 1; // 置1ms标志
}
提示:
!和~均表示取反,这两个的区别在于:
! :代表逻辑取反,即:把非0的数值变为0,0变为1;
~ :表示按位取反,即在数值的二进制表示方式上,将0变为1,将1变为0;