|
- /*
- 定时器驱动扫描数码管
- T1扫描数码管
- T0 负责计时
- 全程未使用延时函数
- */
- #include <reg52.h>
- #define Ulong unsigned long
- #define Uint unsigned int
- #define Uchar unsigned char
- sbit DU = P2 ^ 6; // 数码管段选
- sbit WE = P2 ^ 7; // 位选
- double code Crystal = 11.0592; // 晶振频率 设定
- double code Clock_Cycle = 12; // 时钟周期
- double Machine_Cycle; // 机器周期
- Ulong Need_time_US; // 微秒总数量
- Ulong Need_time_MS; // 计算溢出的毫秒
- Ulong Need_time_S; // 计算溢出的微秒
- Ulong Need_time; // 定时器0溢出的总数量计算
- Ulong Need_time2; // 定时器1溢出的总数量计算
- Ulong display_count = 0, display_count1 = 0;
- int val[8]; ///*存储每个位的数字数组变量*/
- Uchar code DUtabel[] = {
- 0x3F,
- 0x06,
- 0x5B,
- 0x4F,
- 0x66,
- 0x6D,
- 0x7D,
- 0x07,
- 0x7F,
- 0x6F,
- 0x77,
- 0x7C,
- 0x39,
- 0x5E,
- 0x79,
- 0x71,
- 0x76,
- 0x38,
- 0x40,
- 0x00,
- };
- Uchar code WEtabel[] = {
- 0x00, // 全亮,补位选空位
- 0xFE,
- 0xFD,
- 0xfb,
- 0xf7,
- 0xef,
- 0xdf,
- 0xbf,
- 0x7f,
- };
- void Sys_init();
- void showval(Uchar val, Uchar WEval);
- void display(int Z);
- void T0_Timer_Init(Ulong U_time, int mod, int type);
- void T1_Timer_Init(Ulong U_time, int mod, int type);
- void delay(Uchar z, int mod);
- ///////////////main/////////////////////
- void main()
- {
- Sys_init(); // 系统初始化
- T1_Timer_Init(5, 2, 0); // T1扫描数码管
- T0_Timer_Init(1, 3, 0); // T0 负责计时
- while (1) {
- // display(display_count);
- }
- }
- ////////////函数区域//////////////////
- /*初始化参数*/
- void Sys_init()
- {
- Machine_Cycle = 1 / Crystal * Clock_Cycle; // 初始化 机器周期
- }
- void showval(Uchar val, Uchar WEval)
- {
- WE = 1; // 打开位选锁存
- P0 = WEtabel[WEval]; // 选择位选
- WE = 0; // 位锁存
- DU = 1; // 打开段选锁存器
- P0 = DUtabel[val]; // 送数据
- DU = 0; // 段锁存
- }
- void display(int Z)
- {
- static int i;
- if (i == Z) {
- i = 0;
- return;
- }
- P0 = 0XFF; // 清除段码
- showval(val[i], 8 - i);
- i++;
- }
- /*
- 设置定时器
- 参数1数量: 时间数量
- 参数2单位: 1.微秒 2.毫秒 3.秒
- 参数3模式: 0.定时器 1.计数器
- #说明:引脚 计数器0引脚P3*4
- */
- void T0_Timer_Init(Ulong U_time, int mod, int type)
- {
- if (type == 1) // 如果选择计数模式
- {
- TR0 = 1;
- TMOD |= 0X05;
- TH0 = 0;
- TL0 = 0;
- } else { // 如果为定时器模式
- /*时间转换*/
- if (mod == 3) {
- Need_time_US = U_time * 1000 * 1000;
- } else if (mod == 2) {
- Need_time_US = U_time * 1000;
- } else if (mod == 1) {
- Need_time_US = U_time;
- }
- /*设置定时器*/
- Need_time = (Ulong)(Need_time_US / Machine_Cycle) / 65535; // 获得溢出总量
- // 设置中断
- EA = 1; // 打开总中断
- ET0 = 1; // 打开定时器0中断
- TR0 = 1; // 启动定时器0
- TMOD = 0X01; // 定时器工作模式1,16位定时模式
- TH0 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) / 256; //(Need_time_US/Machine_Cycle)%65535 排除溢出位
- TL0 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) % 256;
- }
- }
- void T0_Time() interrupt 1
- {
- static Ulong use_count; // 已经执行的数量
- if (Need_time == use_count) // 判断Need_time总耗微秒数 是不是消耗完 如果消耗完 进入重置阶段
- {
- TH0 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) / 256; //(Need_time_US/Machine_Cycle)%65535 排除溢出位
- TL0 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) % 256;
- use_count = 0; // 重置已消耗的数量
- display_count++; // 记录消耗完毕的次数
- } else { // 如果没消耗完 继续进入下一轮定时中断触发消耗
- use_count++; // 已消耗的数量加1
- TH0 = 0; // 清0
- TL0 = 0; // 清0
- }
- }
- /*
- 设置定时器
- 参数1数量: 时间数量
- 参数2单位: 1.微秒 2.毫秒 3.秒
- 参数3模式: 0.定时器 1.计数器
- #说明:引脚 计数器1引脚P3*5
- */
- void T1_Timer_Init(Ulong U_time, int mod, int type)
- {
- if (type == 1) // 如果选择计数模式
- {
- TR1 = 1;
- TMOD |= 0X50;
- TH1 = 0;
- TL1 = 0;
- } else { // 如果为定时器模式
- /*时间转换*/
- if (mod == 3) {
- Need_time_US = U_time * 1000 * 1000;
- } else if (mod == 2) {
- Need_time_US = U_time * 1000;
- } else if (mod == 1) {
- Need_time_US = U_time;
- }
- /*设置定时器*/
- Need_time2 = (Ulong)(Need_time_US / Machine_Cycle) / 65535; // 获得溢出总量
- // 设置中断
- EA = 1; // 打开总中断
- ET1 = 1; // 打开定时器0中断
- TR1 = 1; // 启动定时器0
- TMOD = 0X10; // 定时器工作模式1,16位定时模式
- TH1 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) / 256; //(Need_time_US/Machine_Cycle)%65535 排除溢出位
- TL1 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) % 256;
- }
- }
- void T1_Time() interrupt 3
- {
- Ulong use_count1; // 已经执行的数量
- int Zlen = 0;
- if (Need_time2 == use_count1) // 判断Need_time总耗微秒数 是不是消耗完 如果消耗完 进入重置阶段
- {
- TH1 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) / 256; //(Need_time_US/Machine_Cycle)%65535 排除溢出位
- TL1 = (Ulong)(65535 - (Ulong)(Need_time_US / Machine_Cycle) % 65535) % 256;
- use_count1 = 0; // 重置已消耗的数量
- display_count1 = display_count;
- while (display_count1 != 0) {
- // 提取n的各个数位上的数
- val[Zlen++] = display_count1 % 10;
- display_count1 /= 10;
- }
- display(Zlen);
- // display_count1++; // 记录消耗完毕的次数
- } else { // 如果没消耗完 继续进入下一轮定时中断触发消耗
- use_count1++; // 已消耗的数量加1
- TH1 = 0; // 清0
- TL1 = 0; // 清0
- }
- }
- /*
- 延迟函数.
- 参数1:z为数量
- 参数2:mod为模式
- 1:毫秒
- 2:秒
- */
- void delay(Uchar z, int mod)
- {
- Ulong i;
- if (mod == 1) {
- for (i = 0; i < z; i++) {
- unsigned char a, b;
- for (b = 102; b > 0; b--)
- for (a = 3; a > 0; a--)
- ;
- }
- }
- else if (mod == 2) {
- for (i = 0; i < z * 1000; i++) {
- // 10000us //误差 -0.000000000002us
- unsigned char a, b;
- for (b = 102; b > 0; b--)
- for (a = 3; a > 0; a--)
- ;
- }
- }
- }
复制代码 |
|