我是大二开始进入学校电子设计实验室的,从SST89E516到现在stm32f4。以前没有系统的整理过自己的项目,现在由于疫情期间在家有空,就把这些学习成长经历给总结和分享出来,也去自己从新走一遍自己的路,温故而知新。
我们在实验室的是按老师上节课把题目讲下后我们自己做(实验室有单独的教室和专门负责的老师),做完找老师验收(验收的时候还会提问,当初最怕的就是这个了)
0. 89E51的 流水灯 按键 数码管 时钟 液晶 adc dac
1. 模电的 放大器 300-3.4kHz带通滤波器 低频功率放大器
2. stm32f4语音存储回放
3. 电子秤
4. 帆板
5. 平衡车
6. 纸张测量(19年8月参加全国大学生电子设计大赛,获得省2奖)
7. 倒立摆
8. 手势识别
9. 红外通信
10.风力摆 (未做完 开始调参数了)
我们实验室用的是SST89E516RD
SST89E516RD片内有两块SuperFlashEEPROM。
SST89E516RD是一款8位单片机。SST89E516RD含有1k的RAM和64k+8k的内置可擦除程序存储器ROM
SST89E516RD在5V电压时可工作在0~40MHz和3V。
主要特性:·
· 兼容80C51 系列,内置超级FLASH 存储器的单片机·
· SST89E5XXRD工作电压 VDD=4.5~5.5V5 伏工作电压时0-40MHz 的频率范围
· SST89V5XXRD工作电压 VDD=2.7~3.6V在3 伏工作电压下,原厂保证0~25 MHz的工作频率 ,实际最高可达40MHz
· 1K*8 的内部RAM(256Bytes+768Bytes)
· 最大片外程序/数据地址空间为64K*8(当然也可以通过I/O 口进行块切换,实现超64K 扩展)
· 三个16 位定时器/计数器
· 9 个中断源,四个中断优先级
· 四个8 位I/O 口(32 根输入输出线)
实验要求: 实现8个LED灯轮流循环被点亮,将6只数码管按指定字符点亮
设计思路:
流水灯:先点亮最右边的LED,延时,再点亮下一盏灯,循环点亮
数码管:先将位选给高电平,在逐一给低电平,将段选逐一赋值,延时时间要短,让视觉效果上是一起亮
电路图:
//流水灯程序
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H
MOV TH0,#HIGH(65536-50000) //50毫秒定时
MOV TL0,#LOW(65536-50000)
SETB TR0
SETB ET0
SETB EA
MOV A,#0FEH
MOV P1,A
MOV R2,#20
SJMP $
T0ISR:
CLR TR0
MOV TH0,#HIGH(65536-50000)
MOV TL0,#LOW(65536-50000)
SETB TR0
DJNZ R2,T0E //1秒未到直接退出
MOV R2,#20
RL A
MOV P1,A //秒一变的花样流水灯。
T0E:
RETI
END
//数码管程序
ORG 0000H
AJMP 0030H
ORG 0030H
MAIN:
CLR P2.0
MOV P1,#0F9H //1
ACALL DELAY1MS
MOV P1,#0FFH //P1口赋值FFH,即P1口全部置1 #0FFH, 转换为二进制是11111111
SETB P2.0
CLR P2.1
MOV P1,#0A4H //2
ACALL DELAY1MS
MOV P1,#0FFH
SETB P2.1
CLR P2.2
MOV P1,#0B0H //3
ACALL DELAY1MS
MOV P1,#0FFH
SETB P2.2
CLR P2.3
MOV P1,#099H //4
ACALL DELAY1MS
MOV P1,#0FFH
SETB P2.3
CLR P2.4
MOV P1,#092H //5
ACALL DELAY1MS
MOV P1,#0FFH
SETB P2.4
CLR P2.5
MOV P1,#082H //6
ACALL DELAY1MS
MOV P1,#0FFH
SETB P2.5
AJMP MAIN
DELAY1MS: ;//误差 0us
MOV R6,#04H
DL:
MOV R5,#0F8H
DJNZ R5,$
DJNZ R6,DL
RET
END
总结
复位电路:
复位条件:两个机器周期以上的高电平(2us)
前提:足够的电压启动晶振,频率越低,启动时间越长
据查SST89E516RD文档知RC电路是使用时,应确保VDD的上升时间不超过1ms,振荡器启动时间不超过10ms,因此复位时应保证有足够的时间保证振荡器启动,因此时间应大于等于10ms,所以
Urst=Vcc*e^(-t/RC)=0.77 Vcc
t=R1Cln0.7>10ms R1>2.8k
R1/(R1+R2)Vcc R2<3/7R
定时:单片机的定时器是一个16位的定时器,则能从0~65536计数,一次最多能计时65.5ms,定时要先定一个时间,然后执行n次
例如:计时1s
MOV R4,#20
MOV TMOD,#01H
MOV TH0,#030H
MOV TL0,#0B0H
定时有4种工作模式:
模式0为13位计数器;
模式1为16位计数器;
模式2为自动再装入8位计数器;
模式3为定时器0:分成二个8位计数器
定时器1:停止计数
实验要求:构建44的16位矩阵键盘,从左至右,从上至下分别代表“0-F”,按任意键时,数码管都能显示出与之相对应的字符,并通过蜂鸣器来实现按键音;实现一电子时钟,6位数码管从左至右分别代表时,分,秒,并可以通过44的矩阵键盘实现时钟的调时功能。
如上图可知按键1,2脚导通;3,4脚导通。按下按键时1,3或1,4或2,3或2,4导通
(2)矩阵的连接
本实验连接4*4矩阵键盘其连接图如下。在控制的过程中矩阵键盘采用的是行列扫描法。因为我们的矩阵按键接的是单片机的P0口,且矩阵的行接P0.0-P0.3,列接P0.4-0.7,所以其扫描原理为:将接P0.0口的行变为低电平,其余行为高电平,然后读取列线的电平;在这一行上如果有某一按键被按下,则相应的列被拉到低电平,则此行与此列相交的按键被按下;若没有任何一列被拉为低电平则表示没有按键被按下。以此方法类推其他按键的定位。
ORG 0000H ;//伪指令,指定一下程序汇编后代码在入程序存储器0000H单元开始的连续单元中,不占有内存
AJMP MAIN ;//短转移指令,转到主程序开始处
ORG 0050H ;//伪指令,指定一下程序是从0050H之后连续单元存储
MAIN:
MOV P0,#0F0H ;//给P0口赋值,使得低四位为低电平,所有行为低电平,全扫描 高四位列
ONE:MOV A,P0 ;//将P0口值赋值给寄存器A,读取列值
XRL A,#0F0H ;//将A中的值与11110000异或
JZ ONE ;//判断A的值是否为0,为0则没有键按下,继续判断,有则进行下面程序
ACALL DELAY ;//延时20ms去除按压时的抖动
MOV A,P0 ;//再将P0口的值赋值给寄存器A
XRL A,#0F0H ;//与11110000异或
JZ ONE ;//判断若A=0则PC+ONE的地址跳转
MOV A,#00H ;//若不为0,PC值继续向下运行,给A赋值0
JNB P0.4,TWO ;//判断P0.4引脚是否为0,若不为0跳转TWO,继续下面的判断键值
INC A ;//若为0,将A 值加1
JNB P0.5,TWO ;//继续判断P0.5位是否为0,舨晃?跳转TWO,继续下面的判断键值
INC A ;//若为0,将A 值加1
JNB P0.6,TWO ;//继续判断P0.6位是否为0,舨晃?跳转TW,继续下面的判断键值
INC A ;//若为0,将A 值加1
JNB P0.7,TWO ;//继续判断P0.7位是否为0,舨晃?跳转TW,继续下面的判断键值
TWO:MOV R1,A ;//将判断列值的A赋值与R1,暂存于此
MOV R2,#00H ;//R2赋值0将作为行值
MOV R3,#0FEH ;//R3赋值为11111110,作为后面提取行
FOUR:
MOV A,R3 ;//将R3的值赋给寄存器A
MOV P0,A ;//将A赋值给P0口,将第一行给低电平
MOV A,P0 ;//再将P0口的值赋值给A
XRL A,R3 ;//与R3做异或,若某一位不一样,则该位赋值于1
JNZ THREE ;//判断A是否不为0,若不为0则证明该行有键按下,若为0 ,继续下一行的判断
MOV A,R3 ;//将R3的值给A
RL A ;//循环左移一位,将第二行赋于低电平
MOV R3,A ;//将A的值给R3,暂存
MOV A,R2 ;//将R2的值给R2
INC A ;//由于上一行无键按下,则自加1
MOV R2,A ;//再将A 的值赋值给R2暂存
AJMP FOUR ;//挑战FOUR循环判断
THREE:
MOV A,R2 ;//判断到具体的某行时,将暂存行数的R2值,赋值给A
MOV B,#04H ;//给寄存器B赋值4
MUL AB ;//A*B=A,两者相乘赋值给A
ADD A,R1 ;//再将列值相加就得到了该键所对应的具体值
MOV P2,#0FEH ;//将P2口赋值0FE,唤醒数码管第一位,作为显示
MOV DPTR,#TAB ;//寄存器间接寻址,采用数据指针(DPTR)作为间接寻址寄存器,将表TAB赋值于DPTR,以查表方式赋值
MOVC A,@A+DPTR ;//以查表的方式将DPTR中数值赋值于A
MOV P1,A ;//将P1口赋值A中的所查值,P1口控制数码管段选
AJMP MAIN ;//跳转至MAIN,继续下一次判断
DELAY: ;//延迟程序20ms
MOV R6,#40 ;//该语句占1个机器周期
D1: MOV R5,#246 ;//该语句占1个机器周期
D2: DJNZ R5,D2 ;//该语句占2个机器周期共执行246*40次
DJNZ R6,D1 ;//该语句占2个机器周期共执行40次
RET ;//该语句占2个机器周期
TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH
;//表,伪指令DB,通知汇编程序从当前ROM地址开始保留一字节或字节串的存储单元,并存入DB后面的数据
END ;//伪指令,表示END后面所有的汇编语言指令均不予以汇编
蜂鸣器接的是单片机的P3.7口,且连接了一个限流电阻。如上面电路图接法给三级管接5V电源满足发射结正偏,集电结正偏,8550工作在饱和导通状态。蜂鸣器的另一端接地。蜂鸣器用延时程序使谐振装置转化为声音信号,其程序如下。
ORG 0000H
LJMP MAIN
ORG 000BH
MAIN: MOV P3, #0FFH
LCALL DELAY
MOV P3, #00H
LCALL DELAY
LJMP MAIN
DELAY:
MOV R7, #250
D1: MOV R6, #250
D2: DJNZ R6, D2
DJNZ R7, D1
RET
END
//如上程序可知其延时时间为[1+(1+2*250+2)*250+2]*1us.~
//电子时钟
STRT EQU P0.0 ;等价代换
SEC EQU P0.1
MIN EQU P0.2
HOUR EQU P0.3
CL EQU P2.0
ORG 0000H
SJMP MAIN
ORG 000BH ;TO溢出时的中断程序入口地址
AJMP T0INT0 ;TO溢,跳到T0INT0
ORG 0100H
MAIN:CLR P0.4
MOV P2,#0FFH ;初值
MOV R4,#20
;20*0.05=1s
MOV TMOD,#01H ;TO为模式1
MOV TH0,#03CH
MOV TL0,#0B0H ; 即:t=0.05后,TO溢出
SETB ET0 ;T0中断允许位
SETB EA ;开中断
MOV 30H,#00H ;清零30H-32H地址单元:
MOV 31H,#00H
MOV 32H,#00H
KS:LCALL DISP ;作用:无任何按键,动态显示
JB SEC, KM ;检查 秒键 按否?
KSS:LCALL DISP
LCALL DALY2 ;显示
JNB SEC,KSS ;当前地址,产生中断
AJMP SINC ;松秒键(秒+1)
KM: LCALL DISP
JB MIN,KH ;分调整按键(按,不管)
KMM:LCALL DISP
LCALL DALY2
JNB MIN,KMM
AJMP MINC;(分+1)
KH:LCALL DISP
JB HOUR,K1 ;时调整按键 (按,不跳)
KHH:LCALL DISP
LCALL DALY2
JNB HOUR,KHH
AJMP HINC ;(时+1)
SINC:LCALL DISP
LCALL CLO
LCALL DISP
INC 30H ;秒调整 30H单元的数据+1
MOV A,30H
CJNE A,#60,SINC0 ;A=60时,不管 , 否则跳
MOV 30H,#0 ;A=60 30H单元的数据清零60/10=6.0(6与0)59/10=(5与9)
SINC0:AJMP KS
MINC:LCALL DISP
LCALL CLO
LCALL DISP
INC 31H ;31H单元的数据+1
MOV A,31H
CJNE A,#60,MINC0
MOV 31H,#0
MINC0:AJMP KM ;返回"主跳"
HINC:LCALL DISP
LCALL CLO
LCALL DISP
INC 32H
MOV A,32H
CJNE A,#24,HINC0
MOV 32H,#0
HINC0:AJMP KH
k1: LCALL DISP
JB STRT,KS ;检查开始键
K11:LCALL DISP
LCALL DALY2
JNB STRT,K11
AJMP START
START:LCALL DISP
LCALL CLO
LCALL DISP
CPL TR0
AJMP K1
DISP:MOV A,30H ;单元中的数据/10,分离个位与十位
MOV B,#10
DIV AB
MOV 40H,B ;余数(秒个位数)
MOV 41H,A ;商(秒十位数)
MOV A,31H
MOV B,#10
DIV AB
MOV 42H,B ;余数(分个位数)
MOV 43H,A ;商(分十位数)
MOV A,32H
MOV B,#10
DIV AB
MOV 44H,B ;余数(时个位数)
MOV 45H,A ;商(时十位数)
MOV A,40H ;秒个位
ACALL SEG7
MOV P1,A
CLR P2.5
ACALL DLY
SETB P2.5
MOV A,41H ;秒十位
ACALL SEG7
MOV P1,A
CLR P2.4
ACALL DLY
SETB P2.4
MOV A,42H ;分个位
ACALL SEG7
MOV P1,A
CLR P2.3
ACALL DLY
SETB P2.3
MOV A,43H ;分十位
ACALL SEG7
MOV P1,A
CLR P2.2
ACALL DLY
SETB P2.2
MOV A,44H ;时个位
CALL SEG7
MOV P1,A
CLR P2.1
ACALL DLY
SETB P2.1
MOV A,45H ;时十位
ACALL SEG7
MOV P1,A
CLR P2.0
ACALL DLY
SETB P2.0
RET
T0INT0:PUSH ACC
PUSH PSW
CLR TR0
MOV A,#0B5H
ADD A,TL0
MOV TH0,#03CH ;定时中断子程序。重装定时常数
MOV TL0,A
SETB TR0
DJNZ R4,T0INTR
MOV R4,#20
INC 30H ;1S,秒存储单元内数+1
MOV A,30H
CJNE A,#60,T0INTR ;未满60S,跳出中断。
MOV 30H,#0 ;满60S,秒单元清零
INC 31H ;分+1
MOV A,31H
CJNE A,#60,T0INTR
MOV 31H,#0
INC 32H
MOV A,32H
CJNE A,#24,T0INTR
MOV 32H,#0
T0INTR: POP PSW
POP ACC
RETI
CLO:CLR CL
LCALL DALY1
SETB CL
RET
DALY2: ;误差 0us
MOV R6,#01H
DL0:
MOV R5,#2FH
DJNZ R5,$
DJNZ R6,DL0
RET
DLY:MOV R7,#2
D1:MOV R6,#40
DJNZ R6,$
DJNZ R7,D1
RET
DALY1: ;误差 0us
MOV R6,#0D7H
DL3:
MOV R5,#2DH
DJNZ R5,$
DJNZ R6,DL3
NOP
NOP
RET
SEG7:INC A
MOVC A,@A+PC
RETI
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90
(1) 按键扫描的工作原理
将接P0.0口的行变为低电平,其余行为高电平,然后读取列线的电平;在这一行上如果有某一按键被按下,则相应的列被拉到低电平,则此行与此列相交的按键被按下;若没有任何一列被拉为低电平则表示没有按键被按下
。其他行的按键判断都是以此方法进行,将该行置为低电平,其余行为高电平,然后读取列的电平来判断哪个按键被按下。
(2)为什么按键接P0口时要接上拉电阻
因为P0口的内部接构中没有上拉电阻,加了上拉电阻可以很好的控制按键的电平的状态,使按键按下后能很好的回复为初始状态。
(3)定时和中断
T0INT0:PUSH ACC
PUSH PSW
CLR ETO
CLR TR0
MOV A,#0B7H (7是补从CLR TR0到MOV TH0,A用时)
ADD A,TL0 (TL0值从50ms后到TR0所有用时,弥补中断响应时间)中断响应的时间不能确定因此用定时器补误差)
MOV TH0,#03CH ;定时中断子程序。重装定时常数
MOV TL0,A
MOV A,#3CH
ADDC A,TH0 (当前面的ADD中A+TL0高八位有溢出时ADD会进位使初值精确)
MOV
TH0,A
TB TR0
①中断请求Interrupt Request
②Interrupt Enable中断使能 (中断总开关,允许其它中断的前提)
③Interrupt Priority中断优先级
④breakpoint address断点地址
⑤Vector address
①②③④⑤构成中断响应
我们当初的时候是零基础进的实验室,开始的时候都要求用汇编写程序,以此打好基础(建议零基础的同学也这样),每次做完一个项目时要好好作报告和总结,每一封耕耘都会有一份收获 下一篇写89E51的LCD1602液晶、ADC0809、DAC0832