完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
0x00 前言
6月份实验室考核,考核的内容我也不知道(估计是 51,c,加点电分,或者数据结构?不知道),虽然是一些入门的东西,不过为了万无一失(谁也不敢说会不会出一些犄角旮旯的东西),还是从头捋一遍。(菜鸡瑟瑟发抖),先51看一下吧。我就拿 普中-51-A3的举例了 本文全当博主的复习,主要是结合 小蜜蜂51和普中51 0x01 最小系统板: 1.电源电路 2.复位电路 3.时钟电路 4.下载电路 MCU 4个广角,P0 P1 P2 P3 对应就行。 复位 RST 网络标号 跟上述单片机的9脚相连, 1)当按键按下后,电源会经过按键,接入RST引脚进行复位(51单片机是进行高电频复位) 2)不按的化,通过R与电容组成的RC充放电电路,进行复位 晶振电路 可以看出来是采用12兆晶振,两边c12 c13电容,接在单片机的18 19 脚。 电源电路 && 下载电路 通过下面的u***接口,接入电源,经过滤波电容进行滤波(图中红框处),紧接这连接D5V的开关,送到VCC,之后各部分才有电,当没有按下开关时,这个DIN5VS(5伏)只是和 CH340 这个芯片来识别串口,并没有供电 P5短接板 CH340用的也是12兆晶振 下载时就利用RTS 和DTR高低电频的变化,进行下载复位(STM就需要人为了) 注意:CH340的位置一定要接地,不然会发烫。 0x02 LED 1.定义:LED,即发光二极管,是一种半导体固体发光器件。(写上吧,万一考呢) 2.LED的工作原理。 LED的符号为: LED的工作是有方向性的,只有当正级接到LED阳极,负极接到LED的阴极的时候才能工作,如果反接LED是不能正常工作的。3.原理图 正入负出,所以阳极都接到了VCC(高电平)上,阴极串联一个电阻接到了P2口,所以点亮的话把对应的P2口拉低就行。 流水: #include #include typedef unsigned char u8; typedef unsigned int u16; void delay(u16 i) { while(i--);//ͨ¹ýËÀÑ»·Õ¼ÓÃcpuÔËËãʱ¼äÀ´ÑÓʱ } void LED_WATER() { int i; for (i = 0 ; i < 7; i++) { P2 = ~(0x01 << i); delay(25000); } for (i = 0 ; i < 7; i++) { P2 = ~(0x80 >> i); delay(25000); } } void main() { P2 = ~(0x01); delay(25000); while(1) { LED_WATER(); } } (下面的代码只写关键部分) 0x03 蜂鸣器 有电路板的是无源蜂鸣器,没有电路板的是有缘蜂鸣器(用黑胶封闭) 有源:在IO里输出一个电平就行 无源:电平 + 一定频率脉冲 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。 接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。 接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。 多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。声音 改变单片机引脚输出波形的频率,就可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音。 大小 改变输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小。、 原理图 可以看到蜂鸣器BEEP接到了ULN2003D上,对应的是P2^5 ULN2003 放大电路,放大驱动电流 (下面是套话) ULN2003 是高耐压、大电流达林顿陈列,由七个硅NPN 达林顿管组成。 ULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。可直接驱动蜂鸣器、继电器等负载 。代码 ***it bee = P2 ^ 5; //因为是无源,所以要 脉冲+电平void main(){ bee = ~bee; //产生脉冲 delay(10);} 0x04 数码管 (因为是复习,就不分静态和动态了) 显示器&&接口 LED显示器有两种:段显示(7段,米字型等)和点阵显示 LED数码管根据LED的不同接法可分为2类:共阴和共阳。 (A3里没有单个的,这是别人的图) 共阴就是阴极接地,所以要是亮就得输入高电平 共阳就是阳极接vcc,所以要是亮就得输入低电平 共阳极数码管编码表:unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};共阴极数码管编码表:unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 原理图: 引脚对应着 P0,看一眼P0口: 共阳,低电平有效 注意:P0口是露底开路的,如果不加上拉电阻(VCC)的话,对P0无法进行输入输出的控制。 使能 锁存器:74HC245 (一般是74HC573,这个普中A3的板子有点神奇) 简单地说锁存器就是一个缓存器,它能保存上一次的状态,自带使能端口,清零端口。当使能端有效时,则左右两端导通,否则断开。74HC245: 7HC573 :通常配合或非门(74HC02)使用 138译码器 74HC138 简单地说138译码器将一个特殊的编码翻译成一个状态。 代码:(因为普中这个板子,138译码器,接的是P2^2,P2^3,P2^4,有些麻烦,为了直观代码如下) ***it lsa=P2^2; ***it l***=P2^3; ***it lsc=P2^4; void wei_poc(u8 poc) { switch(poc) { case 0: lsa=1;l***=1;lsc=1;break; case 1: lsa=0;l***=1;lsc=1;break; case 2: lsa=1;l***=0;lsc=1;break; case 3: lsa=0;l***=0;lsc=1;break; case 4: lsa=1;l***=1;lsc=0;break; case 5: lsa=0;l***=1;lsc=0;break; case 6: lsa=1;l***=0;lsc=0;break; case 7: lsa=0;l***=0;lsc=0;break; } } 在蓝桥杯里有方便的写法。 动态数码管 动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。说白了就是利用视觉残留,让多个静态数码管循环亮起。 代码 u8 code DUANXUAN[]={ //标准字库 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71, //black - H J K L N o P U t G Q r M y 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e, 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. void SMC_Bit(u8 dat, u8 poc) { P0 = ~DUANXUAN[dat];//段 wei_poc(poc);//位 } void SMC_Display() { SMC_Bit(1,0); delay(500); SMC_Bit(0,0);//消影 SMC_Bit(2,1); delay(500); SMC_Bit(0,1);//消影 SMC_Bit(3,2); delay(500); SMC_Bit(0,2);//消影 SMC_Bit(4,3); delay(500); SMC_Bit(0,3);//消影 SMC_Bit(5,4); delay(500); SMC_Bit(0,4);//消影 SMC_Bit(6,5); delay(500); SMC_Bit(0,5);//消影 SMC_Bit(7,6); delay(500); SMC_Bit(0,6);//消影 SMC_Bit(8,7); delay(500); SMC_Bit(0,7);//消影 } (代码要结合前文,注意一下自己的是共阴还是共阳) 0x05 独立按键 按键的两个引脚,一端通过电阻上拉到高电平,另一端接地。 没有按键按下时,输入引脚为高电平。 有按键按下时,输入引脚为低电平。 扫描:通过反复读取按键输入引脚的信号,然后识别高低电平来判断是否有按键触发。 去抖动 (别人的图) 首次检测到输入引脚有低电平后,稍做延时,再次读取该引脚,如果确实是低电平,则触发,否则就是干扰信号。 原理图: 代码: ------------------------------------- 按键按下,L1灯亮; 按键松开,L1灯灭; ------------------------------------- ***it K1 P3^1; ***it L1 P2^0; void ScanKeys_Alone() { if (K1 == 0) { delay(100); if(K1 == 0) { L1 = 0; //按键按下,L1灯亮 while(K1 == 0); //分界线 L1 = 1; //按键松开,L1灯灭 } } } 要注意,按下和松开的位置。 0x06 矩阵按键 小蜜蜂老师这篇写得很仔细:https://www.cnblogs.com/ALittleBee/p/8411771.html 下面是我摘抄的一些: 与独立按键不同的是,按键的两个引脚都分别连接的单片机的I/O端口,一个作为行信号,另外一个作为列信号。我们以4X4的矩阵键盘为例,试着探讨其工作方式和扫描思路。 在上面的矩阵键盘中,要识别出黄色按键的按下状态,应该怎么做呢?代码: 原理图: ***it R1 = P1^7; ***it R2 = P1^6; ***it R3 = P1^5; ***it R4 = P1^4; ***it C1 = P1^3; ***it C2 = P1^2; ***it C3 = P1^1; ***it C4 = P1^0; void ScanKeys() { keyNum = 16;//黑屏 R1 = 0; R2 = R3 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1 == 0) { while(C1 == 0); keyNum = 0; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C2 == 0) { while(C2 == 0); keyNum = 1; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C3 == 0) { while(C3 == 0); keyNum = 2; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C4 == 0) { while(C4 == 0); keyNum = 3; ShowKeyNum(SMG_NoDot[keyNum]); } R2 = 0; R1 = R3 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1 == 0) { while(C1 == 0); keyNum = 4; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C2 == 0) { while(C2 == 0); keyNum = 5; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C3 == 0) { while(C3 == 0); keyNum = 6; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C4 == 0) { while(C4 == 0); keyNum = 7; ShowKeyNum(SMG_NoDot[keyNum]); } R3 = 0; R2 = R1 = R4 = 1; C1 = C2 = C3 = C4 = 1; if(C1 == 0) { while(C1 == 0); keyNum = 8; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C2 == 0) { while(C2 == 0); keyNum = 9; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C3 == 0) { while(C3 == 0); keyNum = 10; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C4 == 0) { while(C4 == 0); keyNum = 11; ShowKeyNum(SMG_NoDot[keyNum]); } R4 = 0; R2 = R3 = R1 = 1; C1 = C2 = C3 = C4 = 1; if(C1 == 0) { while(C1 == 0); keyNum = 12; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C2 == 0) { while(C2 == 0); keyNum = 13; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C3 == 0) { while(C3 == 0); keyNum = 14; ShowKeyNum(SMG_NoDot[keyNum]); } else if(C4 == 0) { while(C4 == 0); keyNum = 15; ShowKeyNum(SMG_NoDot[keyNum]); } } 按键扫描有很多种写法,这是一种好理解,引脚比较灵活,但是笨笨的写法。 下面这种,需要引脚比较规则时比较方便: void KeyDown() { io_Key=0x0f; //行 if(io_Key !=0x0f) //判断是否按下 { delay(1000); //去抖动 if(io_Key !=0x0f) { io_Key =0x0f; //行 switch(io_Key) { case 0x07: KeyValue=0;break; case 0x0b: KeyValue=1;break; case 0x0d: KeyValue=2;break; case 0x0e: KeyValue=3;break; } io_Key =0xf0; //列 switch(io_Key) { case 0x70: KeyValue=KeyValue;break; case 0xb0: KeyValue=KeyValue+4;break; case 0xd0: KeyValue=KeyValue+8;break; case 0xe0: KeyValue=KeyValue+12;break; } while((a<50) && io_Key!=0xf0) { delay(1000); a++; } } } } 0X07 中断系统 参考文章https://bbs.21ic.com/icview-2477100-1-1.html(小蜜蜂老师赛高) 在执行cpu当前程序时,由于系统中出现了某种急需处理的情况,cpu暂停正在执行的程序,转而去执行另外一段特殊的程序来处理出现的紧急事务,处理结束后,CPU自动返回到原来暂停的程序中去继续执行。这种程序在执行过程中由于外界的原因而被中间打断的情况,成为中断。图解: 引起CPU中断的根源,称为中断源。中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统。 中断服务函数:内核响应中断后执行的相应处理程序。 中短向量:中断服务函数的入口地址。每个中断源都对应一个固定的入口地址。当内核响应中断请求时,就会暂停当前的程序执行,然后跳转到该入口地址执行代码。 注意:有中断请求不一定能打断主程序。 随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与慢速I/O设备的数据传送问题,而且还具有如下优点: 分时操作。CPU可以分时为多个I/O设备服务,提高了计算机的利用率;(以上看一眼了解一下,万一考呢,下面说正事) 中断系统 一般来说,51单片机有5个中断源(忽略定时/计数器2),分2个优先级,这个5个中断源按照自然优先级从高到低依次为: 外部中断0:INT0 定时/计数器0:TF0 外部中断1:INT1 定时/计数器1:TF1 串口中断:RI/TI (图一) 每个中断源都对应着一个固定的入口地址,也就是中断向量,它们依次是: 0 0x0003: INT0 1 0x000B: TF0 2 0x0013: INT1 3 0x001B: TF1 4 0x0023: RI/TI 也就是说,不管主程序执行到什么地方,只要外部中断1产生请求,内核要响应该中断,就会到0x0013这个地址去执行代码。如果你是在使用汇编语言进行程序开发的时候,你需要记住每个中断源对应的地址;如果你使用的是C语言,你只需要记住中断源的顺序就可以了,也就是最左边的中断号。 寄存器 中断相关的寄存器有4个,每个寄存器都是可以位寻址的,这该编程带来了方便。 其中2个为控制寄存器:IE寄存器与IP寄存器: 另外2个为中断请求标志:TCON寄存器与SCON寄存器: 代码 /==中断0==///void Init_INT0()//触发方式{ IT0 = 1;//下降沿触发 EX0 = 1;//中断使能打开 EA = 1;//总中断打开}void ServiceINT0() interrupt 0{ ......//终端服务函数的编写}///==中断0_end== (Init_INT0()函数结合 图一 去看) 0x08 定时/计数器 参考文章:https://bbs.21ic.com/icview-2477676-1-1.html 作为定时器时,计数信号的来源选择周期性的内部时钟脉冲;用作计数器时,计数信号的来源选择非周期性的外部输入信号。 本质上都是计数器 计算: 51单片机有两个定时/计数器T0和T1,为16位加法计数器,由低8位TLx和高8位THx两个寄存器组成,最大计数值为65535个计数脉冲。 原理: 每接收到一个计数脉冲,计数器就会加1,当计数值累计至全为1时(8位255,13位8191,16位65535),再输入一个计数脉冲,计数器便会溢出回零,并且计数器的溢出是TCON寄存器的TF0或TF1位置1,同时向内核提出中断请求。如果定时/计数器工作于定时模式,则表示间隔定时时间到,如果工作与计数模式,则表示计数值已满。 假设单片机的外部晶振为12MHz,那么,经过12分频后输入计数器的计数脉冲为1MHz,即每个脉冲的周期为1us。因此定时器T0的16位工作模式最大的定时时间为65535us,65.5ms。如果要定时10ms的话,计数器就不能够从0开始计数了,必须给它一个计数初值。怎么计算这个初值呢? 要定时10ms,则相当于计数10000个脉冲后计数器的值就到达65535了,那么开始计数的这个地方就是计数初值。 65535 - 10000 = 55535 = 0xd8ef 把这个计算得到的初值写入TH0和TL0寄存器即可: TH0 = 0xd8;或者 TH0 = (65535 - 10000) / 256; TL0 = 0xef; 或者 TL0 = (65535 - 10000) % 256; 当然明白了,上述文章中还有个例题,也是同样的计算方法(具体见上述文章)。 寄存器 除了除了计数初值寄存器THx和TLx之外,还有TMOD寄存器和TCON寄存器 (小蜜蜂的图) TCON:见上段落(中断)所写。 代码: /==中断0==/// void Init_INT0()//触发方式 { IT0 = 1;//下降沿触发 EX0 = 1;//中断使能打开 EA = 1;//总中断打开 } void ServiceINT0() interrupt 0 { ......//终端服务函数的编写 } ///==中断0_end== (定时器通常与全局变量相结合来编写) 0x09 串口通信 串口通信的概念有很多,这里只讲述博主认为重要的(重要的意思就是感觉能考的(手动滑稽)) 一些概念: 串行 && 并行: 串行通信:是将数据字节分成一位一位的形式在 一条传输线上逐个地传送。 串行通信的特点:传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂。 并行通信:通常是将数据字节的各位用多条数据线同时进行传送 。 并行通信的特点:并行通信控制简单、传输速度快;由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难。 通信种类: 在51中一般是串行,在此不谈并行,串行通信有SPI,IIC,UART,大多数,串行通信指的就是UART. 传输方向: 单工是指数据传输仅能沿一个方向,不能实现反向传输。 半双工是指数据传输可以沿两个方向,但需要分时进行。 全双工是指数据可以同时进行双向传输。 通信方式: 异步通信:通信中双方的比特率要保持一致。以字符为单位进行数据帧传输,一次一帧。 同步通信:需要同一个时钟,以数据块传输。 比特率: 串口每秒传输的位数。 在51中有4种模式: 模式1,3,由定时器1的溢出率决定,波特率可变 通常用模式2 因为是由定时器1的8位自动重装载产生,当TH1溢出时,自动装到TL1去。 波特率怎么算的就大致看一下把(了解为主)主要是图中后两行话 串口通信有2个缓冲寄存器SBUF,一个发送,一个接收,物理上完全独立,字节寻址(99h). 发送:自动发完之后,TI标志位置1。 SBUF = 0x00; //发送 接收:自动接收之后,RI标志位置1。 变量 = SBUF; //接收到一个变量里 SCON (小蜜蜂的图) 记住SCON = 0x50,类似蓝桥杯的板子还需要设置AUXR,普中A3就不用了。 代码: void Init_T0()//需要配置TMOD THX TLX ET0 EA TR0 { //TMOD: GATE = 0; c/t = 0; M1,M0 = 0x01 TMOD = 0X01; //初值5ms * 100 = 0.5s TH0 = (65535 - 50000) / 256;//高8位 TL0 = (65535 - 50000) % 256;//低8位 //打开使能 ET0 = 1; //总中断 EA = 1; TR0 = 1; } void ServiceT0() interrupt 1 { //因为没有打开自动重装载,所以要重新配置 TH0 = (65535 - 50000) / 256;//高8位 TL0 = (65535 - 50000) % 256;//低8位 ......//编写服务函数 } 0x0A 总结 因为篇幅的原因,51单片机的外设芯片,pwm之类的放到下一章去写,本文是博主的复习,借用了小蜜蜂和普中的一些素材。 因为是复习,所以点了一些博主觉得会考的知识点,放了一些博主用惯了的代码。如有不正确的地方,请路过的大佬斧正,希望可以帮助到各位看官,(下一篇是外设芯片篇)。 |
|
|
|
只有小组成员才能发言,加入小组>>
2308 浏览 0 评论
834浏览 2评论
476浏览 1评论
1354浏览 0评论
240浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-20 11:52 , Processed in 1.160646 second(s), Total 48, Slave 40 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号