1.电路板电路原理
“擎天柱Ai8051U转89C52-DIP40核心板”,用AI8051U-34k64单片机的timer0产生100us中断,作查理复用方式的LED的底层驱动,timer1中断产生1s计时,累加计时产生1s时间,制作0~99.9计时器,P33外接按键控制定时器启动、暂停、清零,单排6脚3位8.8.8.数码管显示。
2. 6引脚8.8.8.数码管的电路结构
3.源代码
- //主程序文件 main.c
- //AI8051U驱动三位8.8.8数码管显示的999s计时器 下载成功 32bit模式
-
- /**********************************************************
- 三位8.8.8数码管,共6个引脚,引脚组合
- --- PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 列/阳极
- PIN1 -- DP1 DP2 -- -- --
- PIN2 -- -- F1 G1 C1 --
- PIN3 -- A1 -- F2 G2 E2
- PIN4 -- B1 D2 -- A2 D3
- PIN5 G3 E1 B2 C2 -- F3
- PIN6 A3 D1 B3 E3 C3 --
- 行/阴极
- ********************************************************/
-
-
- #include "AI8051U.h" //调用头文件 手册 AI8051U.PDF
- #include "stc32_stc8_usb.h" //调用头文件
- #include "intrins.h" //调用头文件
- #include "led.h" //调用led扫描头文件
- #include "timer.h" //调用timer初始化头文件
- #include "key.h" //调用按键扫描头文件
- //#include "def.h" //调用定义数据类型头文件main.c里包含该头文件
-
- #define MAIN_Fosc 24000000UL //时钟24MHZ
-
- //全局变量声明
- volatile u8 T1_1Sflag=0; //timer1溢出标志
- volatile bit key_stime_ok; //10ms按键时间标志
- volatile u8 T1_100ms,T1_1S = 0; //100ms,1s计时单元
- volatile u8 buff[3]; //显存
-
- void main(void)
- {
- u16 T1_1S=0,T1_cnt=0; //T1秒计时,及10ms计时
- u8 times = 0,Key_value = 0; //按键次数,键值
-
- WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
- P_SW2 |= EAXFR; //扩展寄存器(XFR)访问使能
- CKCON = 0; //提高访问XRAM速度
-
- P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
- P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
- //P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
- P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
- P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
- P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
- P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
-
- Timer0_init( ); //timer0初始化函数
- Timer1_init( ); //timer1初始化函数
- EA = 1; // 开总中断
- ET0 = 1; // 定时/计数器0允许中断
- ET1 = 1; // 定时/计数器1允许中断
- while (1)
- {
-
- if(key_stime_ok) //10s按键扫描时间到
- {
- key_stime_ok = 0; //10ms按键时间标志清0
- if(read_key()) //读取键值
- {
- times++; //按键次数加1
- if(3 == times) //按键次数达3次
- times = 0; //按键次数清0
- switch (times) //根据按键次数执行不同的动作
- {
- case 1:
- TR1 = 1; //T0开始运行
- break;
- case 2:
- TR1 = 0; //T0暂停运行
- break;
- case 0:
- TR1 = 0; //T0停止运行
- T1_100ms = 0; //100ms计时单元清0
- T1_1S = 0; //1s计时器清0
- break;
- }
- }
- }
- if(1==T1_1Sflag) //如果timer1定时1s溢出标志为1
- {
- T1_1Sflag = 0; // 必须声明为volatile,防止编译器优化,后面可以省略延时
- //DG_Display(buff[0],0,buff[1],0,buff[2]); //显示xx.x
- if(++T1_cnt == 100) //10ms*100=1s
- {
- T1_cnt = 0;
- //P2^=0xff; //调试用
- T1_1S++;
- if(T1_1S > 99)
- T1_1S = 0;
-
- }
- }
- //DG_Display(buff[0],0,buff[1],1,buff[2]); //显示xx.x 放此处无法显示100ms
- buff[0] = T1_1S / 10; buff[1] = T1_1S % 10; buff[2] = T1_100ms;
- }
- }
-
- //========================================================================
- // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
- // 描述: timer0中断函数.
- // 参数: none.
- // 返回: none.
- // 版本: V1.0, 2015-1-12
- //========================================================================
- void timer0_int (void) interrupt 1 //100us中断一次
- {
- static u8 T0_cnt = 0;
- Led_under_deal( ); //数码管灯阵扫描函数
- if(++T0_cnt == 100) //满100us*100=10ms
- {
- T0_cnt = 0;
- key_stime_ok = 1; //按键扫描标志置1
- DG_Display(buff[0],0,buff[1],1,buff[2]); //显示xx.x
- }
-
- }
- //========================================================================
- // 函数: void timer1_int (void) interrupt TIMER1_VECTOR
- // 描述: timer1中断函数.
- // 参数: none.
- // 返回: none.
- // 版本: V1.0, 2015-1-12
- //========================================================================
- void timer1_int (void) interrupt 3
- {
- static u8 T1_cnt = 0;
- if(++T1_cnt == 50) //满2ms*50=100ms
- {
- T1_cnt = 0;
- T1_100ms++; //T1定时100ms单元加1
- if(10 == T1_100ms)
- {
- T1_100ms = 0;
- T1_1Sflag = 1; //timer1定时1s溢出标志置1
- }
- }
- }
复制代码
- //按键扫描C文件 key.c
- #include "key.h" //调用按键扫描头文件
- #include "AI8051U.h" //调用头文件 手册 AI8051U.PDF
-
- //======基于状态机的按键处理程序=============================
- sbit KWIN = P3^3; //单按键位置INT1
- #define key_state_0 0 //状态0,初态,无按键按下
- #define key_state_1 1 //状态1,按键确认态
- #define key_state_2 2 //状态2,计时1
-
- unsigned char read_key(void)
- {
- static unsigned char key_state = 0;
- unsigned char key_press, key_return = 0;
- P3M1 &= ~(1 << 3); P3M0 &= ~(1 << 3); //P33设置为准双向口
- P3 |= 1 << 3; //P33写1
- key_press = KWIN; // 读按键I/O电平
- switch (key_state)
- {
- case key_state_0:// 按键初始态
- if (!key_press) key_state = key_state_1;// 键被按下,状态转换到键确认态
- break;
- case key_state_1:// 按键确认态
- if (!key_press)
- {
- key_return = 1;// 输出"1"
- key_state = key_state_2;// 按键仍按下,状态转换到计时1
- }
- else
- key_state = key_state_0;// 按键已抬起,转换到按键初始态
- break;
- case key_state_2:
- if (key_press)
- key_state = key_state_0;// 按键已释放,转换到按键初始态
- break;
-
- }
- return key_return;
- }
-
复制代码
复制代码
复制代码
- //timer初始化C文件
- #include "timer.h" //调用timer初始化头文件
- #include "AI8051U.h" //调用头文件 手册 AI8051U.PDF
-
-
- #define MAIN_Fosc 24000000UL //时钟24MHZ
-
- //24MHZ,1T,一条指令耗时1/24us,定时100us,初值2400
- //Timer 0 中断频率, 10000次/秒,定时100us,1/100us=10000HZ
- #define Timer0_Reload (MAIN_Fosc / 10000) //定时100us
- #define Timer1_Reload (MAIN_Fosc / 48000) //定时2ms
-
-
- //官方文件
- void Timer0_init(void)
- {
- TR0 = 0; //停止计数
-
- #if (Timer0_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
- #error "Timer0设置的中断过快!"
-
- #elif ((Timer0_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
- ET0 = 1; //允许中断
- // PT0 = 1; //高优先级中断
- TMOD &= ~0x03;
- TMOD |= 0; //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
- // T0_CT = 1; //计数
- T0_CT = 0; //定时
- // T0CLKO = 1; //输出时钟
- T0CLKO = 0; //不输出时钟
-
- #if (Timer0_Reload < 65536UL)
- T0x12 = 1; //1T mode
- TH0 = (u8)((65536UL - Timer0_Reload) / 256);
- TL0 = (u8)((65536UL - Timer0_Reload) % 256);
- #else
- T0x12 = 0; //12T mode
- TH0 = (u8)((65536UL - Timer0_Reload/12) / 256);
- TL0 = (u8)((65536UL - Timer0_Reload/12) % 256);
- #endif
-
- TR0 = 1; //开始运行
-
- #else
- #error "Timer0设置的中断过慢!"
- #endif
- }
-
- //========================================================================
- // 函数: void Timer1_init(void)
- // 描述: timer1初始化函数.
- // 参数: none.
- // 返回: none.
- // 版本: V1.0, 2015-1-12
- //========================================================================
- void Timer1_init(void)
- {
- TR1 = 0; //停止计数
-
- #if (Timer1_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
- #error "Timer1设置的中断过快!"
-
- #elif ((Timer1_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
- ET1 = 1; //允许中断
- // PT1 = 1; //高优先级中断
- TMOD &= ~0x30;
- TMOD |= (0 << 4); //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
- // T1_CT = 1; //计数
- T1_CT = 0; //定时
- // T1CLKO = 1; //输出时钟
- T1CLKO = 0; //不输出时钟
-
- #if (Timer1_Reload < 65536UL)
- T1x12 = 1; //1T mode
- TH1 = (u8)((65536UL - Timer1_Reload) / 256);
- TL1 = (u8)((65536UL - Timer1_Reload) % 256);
- #else
- T1x12 = 0; //12T mode
- TH1 = (u8)((65536UL - Timer1_Reload/12) / 256);
- TL1 = (u8)((65536UL - Timer1_Reload/12) % 256);
- #endif
-
- //TR1 = 1; //开始运行
-
- #else
- #error "Timer1设置的中断过慢!"
- #endif
- }
复制代码
复制代码 4.视频效果
|