元器件参数计算
最后一位是倍率
例:
- 473 = 47 * 10 ^ 3 = 47000
- 102 = 10 * 10 ^ 2 = 1k
- 1001 = 100 * 10 ^ 1 = 1k
单片机型号
- STC89C52RC系列
- keil5中单片机版本多为国外版本,无STC,所以选择AT89C52
- 在keil5中写的代码要创建为HEX文件才能供stc-isp.exe使用
延时器的制作
- 在stc-isp中找到软件延时器
- 将系统频率调至12
- 加入头文件<intrins.h>
- 通过循环将一毫秒的转化为x毫秒
keil5编程的有关注意事项
- 局部变量要写在函数的开头
- 头文件的大小写无影响
- P2用于控制LED灯,P2_0 = 0代表只操作一个灯
- P3用于控制独立按键K1,K2,K3,K4 对应1 0 2 3
- 使用独立按键时,要将红外插口上的插帽拔出
有关数码管
一位数码管
多位数码管
注:
- 断码从下往上读
- P0控制138编码
- P2_432控制CBA
数码管的消影
成因:
位选和段选的不断循环
办法:
void display(unsigned char Led, num){ // 输入LED的序号和显示数据
unsigned char l = Led - 1, cnt = 0;
unsigned char ans[3] = {0, 0, 0};
while(l){
ans[cnt]= l % 2;
l /= 2;
cnt ++;
} // 二进制转化
P2_2 = ans[0];
P2_3 = ans[1];
P2_4 = ans[2];
// 对应ABC,编码时以CBA顺序编
P0 = nums[num];
// 消影
Delay(1);
P0 = 0x00;
}
LCD1602调试
注:
需要将点阵屏左上角的接线帽接到OE 和 VCC
矩阵按键
P1_0~P1_3代表列
P1_4~P1_7代表行
// 按列扫描
unsigned char MatrixKey(){
unsigned char KeyNumber = 0;
P1 = 0xff;
P1_3 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);KeyNumber = 1;}
if(P1_6 ==0){Delay(20);while(P1_6 == 0);KeyNumber = 5;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);KeyNumber = 9;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);KeyNumber = 13;}
P1 = 0xff;
P1_2 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);KeyNumber = 2;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);KeyNumber = 6;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);KeyNumber = 10;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);KeyNumber = 14;}
P1 = 0xff;
P1_1 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);KeyNumber = 3;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);KeyNumber = 7;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);KeyNumber = 11;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);KeyNumber = 15;}
P1 = 0xff;
P1_0 = 0;
if(P1_7 == 0){Delay(20);while(P1_7 == 0);KeyNumber = 4;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);KeyNumber = 8;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);KeyNumber = 12;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);KeyNumber = 16;}
return KeyNumber;
}
定时器
stc-isp.exe定时器制作(以定时器T0的中断为例)
void Timer0Init(void) //1毫秒@12.000MHz
{
// AUXR &= 0x7F; //定时器时钟12T模式
// 单片机本身就使用12T模式,不需要定义
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志,定时器溢出后,会被置1
TR0 = 1; //定时器0开始计时
ET0 = 1; //T0中断允许标志
EA = 1; //中断允许的总开关
PT0 = 0;
}
注:
- 定时器模式:16位
- 定时器时钟:12T
- 定时频率12MHz
关于TMOD
注:
- 高四位置0,使用定时器1;低四位置0,使用定时器0
中断执行的条件
中断函数模版
void Timer0Routine() interrupt 1 // 1为中断号
{
static unsigned int T0Count; // 静态局部变量,初值为0
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
// 每进入一次中断函数都要重新初始化定时器计数
T0Count ++;
if(T0Count >= 1000){
T0Count = 0;
}
}
注: 中断函数有可能在主函数执行到任意一条语句时被响应
串口通信
初始化串口
注:
- 此处用到的是定时器1,允许控制位是ET1
- IE中的ES是串口中断允许控制位
串口原理图
关于SCON
注:
- SM2,TB8,RB8通常置为0
- TI在数据发送后要置0
- RI在数据接收后要置0
关于PCON
只有最高位与串口中断有关
最高位置0,波特率不翻倍;最高位置1,波特率翻倍
常用波特率初值表
代码实现
void UART_Init(){
SCON = 0x50;
PCON &= 0x7f;
TMOD &= 0x0f; // 启用定时器T1
TMOD |= 0x20; // 设置定时器模式为8位自动重载
TL1 = 0xfd; // 定时器设置初值
TH1 = 0xfd; // 定时器设置初值
TR1 = 1; // 定时器1开始计时
ET1 = 0; // 禁止定时器1中断
ES = 1; // 串口通信开关
EA = 1; // 总开关
}
LED点阵屏
关于特殊声明
有关74HC595
注:
- RCLK 写成 RCK
- SCLK 写成 SCK
- 将点阵屏左侧的GND 和 OE通过插线帽相连
点阵屏控制
DS1302时钟
时序定义
命令字对应
注:
前面两列对应命令字
有关BCD码
蜂鸣器
接口
P2^5
振动方式
取反使高低电频转换
关于AT24C02和I2C总线
存储器
- 易失性存储器(ram):存储速度快
- 非易失性存储器(rom):可断电保存
I2C时序结构
AT24C02数据帧
关于LCD1602
引脚配置
引脚及应用电路
时序结构
LCD1602操作流程
存储器结构
单片机字模表
产生PWM方法(PWM 脉冲宽度调制)
注:该方法产生为LED的PWM输出,电机由于电频而与LED的不同