蓝桥杯笔记:单片机原理图和手册完美搭配
错误与改正
写代码一个模块一个模块做好验证
复用模块(如P0数据的现场保护)
引用函数:SelectHC138(); //曾将void粘贴,不执行,不报错
缺少分号
== 与 =
代码设置与isp配置同步:如比特率,定时器初值用的9600注意isp也要选择9600,串口助手,Delay配置,比特率计算,com选择,芯片选择都要注意
SMG_duanma[valu];//数组名称不用加unsigned char
sbit:sbit S4 = P3^3;
sfr AUXR = 0x8e;
比特率9600的初值为0xfd
显示维持用的Delay
MM
J15!!
absacc.h
XBYTE[ ] =
0x8000……
矩阵键盘不要用(P3_6)
IO
J15(2,3gnd)
void SelectHC138() CBA P2^7-P2^5
经验:
避免P0的值被赋值错误:先关闭锁存器(若先改P0,则P0的值会进入到上一锁存器),再改P0,再改锁存器,再马上关闭锁存器。
LED
0、控制原理
1、循环+移位
2、0控制与1控制
如果是IO控制模式:先Select,再改写P0
蜂鸣器,继电器
0、控制原理 (低电平有效,非门,RELAY5,BUZZ7)
数码管
0、控制原理(共阳,数字及字母段码)
1、静态显示(和LED一样差不多0.5s的间隔,可以选中多位显示相同的内容,如跑马管)
2、动态显示(每次位显示之间间隔1ms,500–)
a.消影
b.切换
独立按键和矩阵键盘
J5(2,3为独立按键)(行从上到下:P3^0—P3^3,列从左到右:P4^4 P4^2 P3^5 P3^4)
消抖(5-10ms,1000–)
维持数码管的显示
等待按下状态结束
长按短按判断:
外部中断
中断优先级:外部0,定时器0,外部1,定时器1,串口
J5(2,3)
中断Init配置
IT0 =1下降沿触发 =0低电平触发
外部中断相关引脚:INT0对应P3^2(S5),INT1对应P3^1(S4)
定时器
中断函数内做的是变量值的更改而不是显示代码的运行
串口
串口收发字符:在串口助手要更改模式(默认hex)
PWM
以一个利用按键调节LED亮度的案例解释PWM的实现方式
按键按下时,在发亮模式下打开定时器(TR1 = 1)定时器内为LED一次闪烁的亮度周期,通过控制这个周期内,LED低电平时长占比来控制LED亮度
24CO2
设备地址高四位固定为a,后四位前三位均已接地,只剩读写位可改写
0xa0,0xa1
DCF8591
设备地址高四位固定为9,后四位前三位均已接地,只剩读写位可改写
0x90,0x91
关于控制寄存器,暂时只需要直到低二位是控制通道的(0x01,0x03),第六位为1时是DAC模拟电压,如AIN3的DAC(0x43)
555定时器(测量频率)
DS18B20
如何引用onewire
如何使用onewire内的函数(复位,读写)读取温度值
判断是否需要改动onewire内函数(1T 12T)
检查底层代码是否有定义引脚,是否有声明
在整合LSB和MSB时,懂得判断正负,了解每位含义,分辨率0.0.625使用的注意!!
DS1302
两类寄存器:31字节大小的静态ram和日历时钟寄存器
日历时钟寄存器每个寄存器每位的含义
日历时间寄存器中读写保护寄存器的最高位为1保护,为0允许读写
秒寄存器最高位为1时钟开始振荡,为0停止振荡
DS1302数据格式是BCD码,BCD码的转换
控制字格式和数据定义
引用模块时:(特别注意SDA)
超声波
TX引脚(P1_0)发射,RX引脚(P1_1)接收
#include "reg52.h"
#include "absacc.h"
#include "intrins.h"
sbit TX = P1^0;
sbit RX = P1^1;
unsigned int distance = 0;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
void DelaySMG(unsigned int t)
{
while(t–);
}
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
XBYTE[0xE000] = 0xFF;
XBYTE[0xC000] = 0x01 << pos;
XBYTE[0xE000] = value;
}
void Display_Distance()
{
if(distance == 999)
{
DisplaySMG_Bit(0, SMG_duanma[15]); //超出测量范围标志:F
DelaySMG(500);
}
else
{
DisplaySMG_Bit(5, SMG_duanma[distance / 100]);
DelaySMG(500);
DisplaySMG_Bit(6, SMG_duanma[(distance % 100) / 10]);
DelaySMG(500);
DisplaySMG_Bit(7, SMG_duanma[distance % 10]);
DelaySMG(500);
}
}
void Delay12us() //@12.000MHz 延时12us
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (–i);
}
void Send_Wave() //产生8个40KHx超声波信号
{
unsigned char i;
for(i = 0; i < 8; i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void Measure_Distance() //超声波测距
{
unsigned int time = 0;
TMOD &= 0x0f; //定时器1模式0,13位,最大8192个计数脉冲
TL1 = 0x00;
TH1 = 0x00;
Send_Wave(); //发送超声波信号
TR1 = 1; //启动定时器
while((RX == 1) && (TF1 == 0)); //等待超声波信号返回或者等到测量超出范围
TR1 = 0; //停止定时器
if(TF1 == 0) //正常测量范围
{
time = TH1;
time = (time << 8) | TL1;
distance = ((time / 10) * 17) / 100 + 3;
}
else //超出测量范围
{
TF1 = 0;
distance = 999;
}
}
void Delay(unsigned char n) //数码管显示增强
{
while(n–)
{
Display_Distance();
}
}
void main()
{
while(1)
{
Measure_Distance();
Delay(10);
}
}
TMOD&=0x0f
TL1与TH1 0x00
启动while关闭(TF1 = 1为溢出)