- 打卡等级:常住居民III
- 打卡总天数:120
- 最近打卡:2025-05-01 07:02:40
中级会员
- 积分
- 212
|
主文件;
#include "TM1652.h"
#include "AI8051U.h"
#define MAIN_Fosc 11059200L // 定义主时钟
#define Timer0_Reload (65536UL -(MAIN_Fosc / 1000)) // Timer 0 中断频率, 1000次/秒
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
// 定义变量
unsigned long count = 0; // 用于计数脉冲个数
unsigned int time_count = 0; // 用于计时
unsigned long frequency = 0; // 保存频率值(Hz)
unsigned int timer0_reload; // 定时器 0 重载值
// 共阴 LED 0--F 段码,包含小数点
const u8 CODE[16] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
// 延时 10ms 函数
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
i = 18;
j = 235;
do
{
while (--j);
} while (--i);
}
// 数码管显示函数,显示 Hz 频率
void TM_Digtal_Display(long frequency)
{
unsigned char wan, qian, bai, shi, ge;
// 计算变量值
wan = frequency / 10000;
qian = (frequency % 10000) / 1000;
bai = (frequency % 1000) / 100;
shi = (frequency % 100) / 10;
ge = frequency % 10;
// 发送显示命令
tm1652_send_data(0x08); // 可能是设置显示模式相关命令
// 显示万位
tm1652_send_data(CODE[wan]);
// 显示千位
tm1652_send_data(CODE[qian]);
// 显示百位
tm1652_send_data(CODE[bai]);
// 显示十位
tm1652_send_data(CODE[shi]);
// 显示个位
tm1652_send_data(CODE[ge]);
// 空位补零
tm1652_send_data(CODE[0]);
Delay10ms();
tm1652_send_data(0x18); // 显示控制命令
tm1652_send_data(0xFE); // 设置占空比15/16,段驱动电流8/8,最大亮度。
}
// 定时器 0 中断服务函数
void timer0_isr() interrupt 1
{
TH0 = (unsigned char)(timer0_reload / 256);
TL0 = (unsigned char)(timer0_reload % 256);
time_count++;
if (time_count >= 1000) { // 定时 1s
time_count = 0;
// 读取计数值
frequency = count; // 保存频率值(Hz)
count = 0; // 清零计数值
// 在中断服务程序中调用显示函数
TM_Digtal_Display(frequency);
}
}
// 外部中断 0 服务函数,用于计数脉冲
void int0_isr() interrupt 0
{
count++;
}
void main()
{
P_SW2 |= EAXFR;
// 提高访问XRAM速度
CKCON = 0;
// 配置端口模式为标准 I/O 模式(具体根据实际需求调整)
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
// 定时器 0 初始化
timer0_reload = Timer0_Reload;
TH0 = (unsigned char)(timer0_reload / 256);
TL0 = (unsigned char)(timer0_reload % 256);
// 设置定时器 0 为模式 1(16 位定时器)
TMOD &= 0x0F;
TMOD |= 0x01;
// 使能定时器 0 中断
ET0 = 1;
// 启动定时器 0
TR0 = 1;
// 外部中断 0 初始化
// 设置为下降沿触发
IT0 = 1;
// 使能外部中断 0
EX0 = 1;
// 定时器 1 初始化,用于计数脉冲
// 设置定时器 1 为模式 1(16 位计数器)
TMOD &= 0xF0;
TMOD |= 0x50;
TH1 = 0;
TL1 = 0;
// 启动定时器 1
TR1 = 1;
// 全局中断使能
EA = 1;
// 开机显示 00000
TM_Digtal_Display(0);
while(1)
{
// 主循环中不需要重复调用显示函数,显示在定时器中断中完成
}
}
TM1652头文件:
#ifndef __TM1652_H__
#define __TM1652_H__
#include "AI8051U.h"
sbit D_out = P4^3; //模拟UART输出,至TM1652数据输入脚D_in
void Delay52us();
//void Delay5ms();
void Delay104us();
void tm1652_send_data(unsigned char sdat) ;
#endif
TM1652 C文件:
#include "TM1652.h"
#include "AI8051U.h"
void Delay52us() //@11.0592MHz
{
unsigned char i;
i = 21;
while (--i);
}
void Delay104us() //@11.0592MHz
{
unsigned char i;
i = 45;
while (--i);
}
void tm1652_send_data(unsigned char sdat) //向TM1652发送数据
{
unsigned char i = 0, sfalg = 0;
//
D_out = 0;
Delay52us(); //延迟52us
//??8???
for (i = 0; i < 8; i++)
{
if (sdat & 0x01)
{
D_out = 1;
sfalg++;
}
else
{
D_out = 0;
}
Delay52us();
sdat >>= 1;
}
//校验
if (sfalg % 2 == 0)
{
D_out = 1;
}
else
{
D_out = 0;
}
Delay52us();
//
D_out = 1;
Delay104us();
}
现在头都大了,移植到AI8051U,连开机00000都不显示了
|
|