[代码随想录2]51单片机1T/12T到底怎么选?

本文探讨了51单片机的发展历程,从传统的12T模式到市场推动下的6T和1T模式,比较了它们在稳定性与速度上的差异,强调选择取决于具体应用需求。

为什么说51单片机怎么选?

时至今日,44年来51单片机自强不息,怎么描述它,堪称控制芯片中的王者!!!

假设你21岁大学毕业进入社会,交社保交到今天恭喜你成功退休了21+44=65


传统即标准51单片机,是12T模式的。12T是指机器周期,机器周期主要针对与汇编来说。

后来因为市场的需要(自己体会就像你的手机十年前和十年后的发展需求),大量单片机厂家的介入,开始对单片机进行提速,于是就出现了 6T、1T模式的单片机。


有些人可能要站出来问了,稳定不稳定,好用不好用。

这相当于问从北京去广州坐绿皮车好稳定,还是高铁快舒服呢?

一切都取决于你手上的马内,毕竟马内能够解决世上99%的问题。


单片机的提速就像是手机的更新换代和交通工具的快速发展

XT单片机的指令周期公式为:

T   =   1/晶振周期*X

例如: 使用12M晶振的1T单片机的指令周期为:  T = 1 / 12 * 1 = 1 / 12 u

都2024年了,能用有的用早用早享受

一个机器周期就等于1个时钟周期(1T单片机)。

#include "reg52.h" #include "intrins.h" // ?????????(0-9) code unsigned char tab[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; // ??????? #define DIGIT_NUM 8 // ??????(??:10ms) const unsigned char time_config[] = {50, 10, 5, 2, 1}; // 0.5s, 0.1s, 0.05s, 0.02s, 0.01s unsigned char time_idx = 0; // ?????? unsigned char time_cnt = 0; // ????? unsigned char move_cnt = 0; // ????? // ??????? unsigned char display_pos = 0; // ????(0-7) bit move_direction = 1; // ????: 1=????, 0=???? // ????? void cls_buzz() { P2 = (P2 & 0x1F | 0xA0); P0 = 0x00; P2 &= 0x1F; } // ????(ms) void delay_ms(unsigned int ms) { unsigned int i, j; for(i = 0; i < ms; i++) for(j = 0; j < 113; j++); } // ??????????? void display_digit(unsigned char pos, unsigned char num) { // ?? P2 = ((P2 & 0x1f) | 0xe0); P0 = 0xff; P2 &= 0x1f; // ?? P2 = ((P2 & 0x1f) | 0xc0); P0 = 1 << pos; // ???pos???? P2 &= 0x1f; // ???? P2 = ((P2 & 0x1f) | 0xe0); P0 = tab[num]; // ????8 P2 &= 0x1f; } // ??????0(??8051??,12T??) void init_timer0() { // ??AUXR??,????8051?12T?? TMOD &= 0xF0; // ?????0??? TMOD |= 0x01; // ?????0?16???????? // ????10ms@12T????? // 11.0592MHz?,12T????????12/11.0592˜1.085µs // 10ms????:10ms/1.085µs˜9216? // 65536 - 9216 = 56320 = 0xDCC0 TL0 = 0xC0; // ?8??? TH0 = 0xDC; // ?8??? TF0 = 0; TR0 = 1; ET0 = 1; EA = 1; } void main(void) { cls_buzz(); init_timer0(); // ?????? display_digit(0,6); while(1) { // ?????? if(move_direction && display_pos >= DIGIT_NUM - 1) { move_direction = 0; // ??????? time_idx = (time_idx + 1) % 5; // ?????? } else if(!move_direction && display_pos <= 0) { move_direction = 1; // ??????? time_idx = (time_idx + 1) % 5; // ?????? } } } // ???0?????? void timer0_isr() interrupt 1 { // ????10ms?? TL0 = 0xC0; TH0 = 0xDC; time_cnt++; if(time_cnt >= time_config[time_idx]) { time_cnt = 0; // ?????????? if(move_direction) display_pos++; // ???? else display_pos--; // ???? // ????8????? display_digit(display_pos, 6); } }这是我的代码。 (1)把学号末位数字在数码管上依次轮流显示,由左-右-左间隔0.5秒循环显示。(2)把学号末位数字在数码管上依次轮流显示,由左-右-左间隔0.1秒循环显示。(3)把学号末位数字在数码管上依次轮流显示,由左-右-左间隔0.05秒循环显示。(4)把学号末位数字在数码管上依次轮流显示,由左-右-左间隔0.02秒循环显示。(5)把学号末位数字在数码管上依次轮流显示,由左-右-左间隔0.01秒循环显示,这是要求。我想要显示一个来回后再改变速度,帮我改个完美的代码
06-19
#include <reg52.h> #include <intrins.h> sfr AUXR = 0x8E; sfr T1MCR = 0xC9; sfr AUXR1 = 0xFF; sbit clk = P1^3; sbit dio = P1^2; sbit P2_4 = P2^4; void Delay_us(unsigned int i) { while(i--) _nop_(); } void I2CStart(void) { clk = 1; dio = 1; Delay_us(2); dio = 0; Delay_us(2); clk = 0; } void I2CAck(void) { clk = 0; Delay_us(2); while(dio); clk = 1; Delay_us(2); clk = 0; } void I2CStop(void) { dio = 0; clk = 1; Delay_us(2); dio = 1; Delay_us(2); } void I2CWrByte(unsigned char oneByte) { unsigned char i; for(i = 0; i < 8; i++) { clk = 0; dio = (oneByte & 0x01) ? 1 : 0; Delay_us(3); oneByte >>= 1; clk = 1; Delay_us(3); } } // ??????(??????) unsigned char code smg_code[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F // 9 }; unsigned long pinlv = 0; unsigned long times = 0; // ????????? unsigned char mode = 0; void key() { static unsigned char key_flag = 0; if(P2_4 == 0) { Delay_us(10000); if(P2_4 == 0 && !key_flag) { mode = (mode + 1) % 3; key_flag = 1; } } else { key_flag = 0; } } void SmgDisplay() { unsigned char digit[4]; unsigned char display_codes[4]; unsigned char has_dot = 0; // ??????? unsigned char i; // ????(???) // ??????????? if (pinlv < 10000) { // ??10kHz:??Hz(??) digit[0] = (pinlv / 1000) % 10; digit[1] = (pinlv / 100) % 10; digit[2] = (pinlv / 10) % 10; digit[3] = pinlv % 10; has_dot = 0; // ???? } else { // ????10kHz:??kHz(?????) unsigned long khz_val = pinlv; // ????????? unsigned int khz = khz_val / 1000; // kHz???? unsigned int fraction = (khz_val % 1000) / 100; // ????(0-9) unsigned int second_frac = (khz_val % 100) / 10; // ?????(??????) digit[0] = khz / 10; // ?? digit[1] = khz % 10; // ?? digit[2] = fraction; // ??? // ?????????? if (second_frac >= 5) { digit[2]++; if (digit[2] > 9) { digit[2] = 0; digit[1]++; if (digit[1] > 9) { digit[1] = 0; digit[0]++; if (digit[0] > 9) { digit[0] = 9; } } } } // ?????????? if (digit[0] > 9) { digit[0] = 9; digit[1] = 9; digit[2] = 9; } digit[3] = 0; // ?????? has_dot = 1; // ????????? } // ??????(?????) display_codes[0] = smg_code[digit[0]]; display_codes[1] = smg_code[digit[1]]; display_codes[2] = smg_code[digit[2]]; display_codes[3] = smg_code[digit[3]]; if (has_dot) { display_codes[1] |= 0x80; // ?????(?????) } // ?????? I2CStart(); I2CWrByte(0x40); // ????? I2CAck(); I2CStop(); I2CStart(); I2CWrByte(0xC0); // ?????? I2CAck(); // ??4????? - ?????? for (i = 0; i < 4; i++) { // ??????i?? I2CWrByte(display_codes[i]); I2CAck(); } I2CStop(); I2CStart(); I2CWrByte(0x8F); // ????+???? I2CAck(); I2CStop(); } void Timer0Init() { AUXR |= 0x80; // T0 1T?? TMOD &= 0xF0; // ??T0?? TMOD |= 0x01; // ??1(16????) TL0 = 0x20; // 1ms????@22.1184MHz TH0 = 0xD1; TR0 = 1; // ??T0 ET0 = 1; // ??T0?? } void Timer1Init() { TMOD &= 0x0F; // ??T1?? TMOD |= 0x50; // T1??????(??1) T1MCR = 0x03; // ??T1??????? AUXR1 |= 0x40; // T1?????P3.5 TH1 = 0x00; // ????? TL1 = 0x00; TR1 = 1; // ??T1 ET1 = 1; // ??T1?? } void timer0_ISR(void) interrupt 1 { static unsigned int cnt = 0; TL0 = 0x20; // ???? TH0 = 0xD1; if (++cnt >= 1000) { // 1??? cnt = 0; TR1 = 0; // ????? // ?????(????) EA = 0; // ?????????? pinlv = (times * 65536UL) + (TH1 << 8) + TL1; times = 0; // ?????? TH1 = 0; // ????? TL1 = 0; EA = 1; // ??? TR1 = 1; // ????? } } void timer1_ISR(void) interrupt 3 { times++; // ???????+1 } void main(void) { // ????? pinlv = 0; times = 0; mode = 0; // ????? Timer1Init(); Timer0Init(); EA = 1; // ?????? while(1) { key(); // ???? SmgDisplay(); // ???? Delay_us(1000); // ???? } }逐行解释上述代码
07-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值