资源描述
广州周立功单片机发展有限公司面试题集锦(考生整理)
试题一:对 80C51单片机内部RAM低128字节存储单元清零,请用汇编语言编程(12分)。
答题分析:这是一道非常基础的题目,具有良好习惯的程序员编写的第一段程序就是对单片机上电进行初始化。单片机内部低128字节即就是0~127,转换为16进制数值则表示为0~7FH。如果用循环语句的话,那么计数器的初始值应该为7FH,假设R0=7FH。程序设计如下:
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:MOV R0,#7FH
CLR A
LOOP:MOV @R0,A
DJNZ R0,LOOP
AJMP $
;
END
R0在此既作为循环程序计数器,又作为内部存储单元的动态地址指针(计数器)。当计数器R0为7FH时,那么R0所对应的存储单元的地址为7FH;当计数器R0减1时,则R0所对应的存储单元地址相应地减1;当计数器R0减为0时,则R0所对应的存储单元地址也减为0,即就是00H单元。
如果选用R1作为计数器的话,即便将R1减为0,也不能将00H单元清0,因为R1在内部存储器的实际地址为01H,那么最后还需要单独对00H单元进行清0才能完成初始化。
试题二:用MCS-51单片机的I/O口直接驱动8个发光二极管,回答以下问题(12分):
(1) 试画出实现原理图,给出合适的电路参数;
(2) 用“汇编语言或C语言编程”,将这8个发光管循环点亮,每次只有一个亮,用肉眼能看见其循环。
试题三:用你最熟悉单片机的I/O口直接驱动一个七段字形LED数码管,回答以下问题(12分):
(1) 试画出实现原理图,给出合适的电路参数,得到合适的笔形码;
(2) 用“汇编语言或C语言编程”,让数码管循环显示0~9,用肉眼能看见其循环。
试题四:算放大器:求放大倍数,何时输入电阻最大;555定时口器接成的多谐振荡器:工作原理,波形图,振荡周期;74HC594的用法:用74HC594来驱动一位七段数码管,要求循环显示0~9
硬件A(本科)有七题:
1、运放,用到虚短虚断的知识
2、三极管设计成的电源控制电路,用到三极管电流电压基本计算
3、串联电路转换成并联电路,用到阻抗变换的计算
4、运放电路放大倍数的计算及输入电阻的计算
5、555多谐振荡电路,数电课本的例题
6、单片机程序设计题:用74HC594来驱动一位七段数码管,要求循环显示0-9
7、C语言程序设计题:涉及数据结构与队列
试题五:
试题六:用任意一单片机设计一个4X4的键盘并编出程序得到键值,要求有去抖,去抖时单片机可以做其它事情,按一下键盘蜂鸣器叫一下,蜂鸣器叫过程中也要单片机可以做其它事情。(提示:用定时器产生基本节拍)
题目是我做后记下来的,当时在做得时候写的很乱,被老师评为编程不怎么样。回来后想想其实很简单就一个中断函数搞定:
void time1_sv() interrupt 5 using 2{
EA=0;
TF2=0; //清中断标志位
if((spcnt--)==0){spcnt=0;SPEAK=0x00;}
if(scankey()){count++;
if(count>8){getkeyval();count=0;spcnt=30;SPEAK=0xff;}
}
else {count=0;}
EA=1;
}
思路是:连续n次进入中断时都检测到有按键,那就去取按键值,并使蜂鸣器叫,蜂鸣器叫多长时间由spcnt的值决定。
试验源程序:
#include "mydef.h"
//定义外围器件地址
#define SPEAK XBYTE[0xC000]
#define KEYIN XBYTE[0xE000]
#define KEYOUT XBYTE[0xF000]
#define PORTA XBYTE[0xa000]
#define PORTB XBYTE[0xb000]
#define LEDD XBYTE[0x9000]
//3000个机器周期中断一次
#define TIME_H (65535-3000)/256
#define TIME_L (65535-3000)%256
//LED显示译码
uchar code table[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90,0x88,0x83,0x0C6,0x0A1,0x86,0x8E,0x7F,0x89};
//全局变量
uchar key_value,count,spcnt;
//判断有无按键
uchar scankey()
{ KEYOUT=0x00;
if(((~KEYIN)&0x0f)!=0) return(1); //有键按下
else return(0);
}
//得到键值
void getkeyval(void)
{
KEYOUT=0x0e;
switch(KEYIN&0x0f)
{ case 14:key_value=0;break;
case 13:key_value=1;break;
case 11:key_value=2;break;
case 7:key_value=3;break;
default:break;
}
KEYOUT=0x0d;
switch(KEYIN&0x0f)
{ case 14:key_value=4;break;
case 13:key_value=5;break;
case 11:key_value=6;break;
case 7:key_value=7;break;
default:break;
}
KEYOUT=0x0b;
switch(KEYIN&0x0f)
{ case 14:key_value=8;break;
case 13:key_value=9;break;
case 11:key_value=10;break;
case 7:key_value=11;break;
default:break;
}
KEYOUT=0x07;
switch(KEYIN&0x0f)
{ case 14:key_value=12;break;
case 13:key_value=13;break;
case 11:key_value=14;break;
case 7:key_value=15;break;
default:break;
}
}
//定时T2中断 89c52,w78e58之类的单片机都有定时器2
void time1_sv() interrupt 5 using 2{
EA=0;
TF2=0; //清中断标志位
if((spcnt--)==0){spcnt=0;SPEAK=0x00;}
if(scankey()){count++;
if(count>8){getkeyval();count=0;spcnt=30;SPEAK=0xff;}
}
else {count=0;}
EA=1;
}
//粗劣延时mS级
void msec(uint x)
{
unsigned int j;
while((x--)!=0)
{
for(j=0;j<=123;j++)
{;}
}
}
//数码管显示
void dir(uchar leddat)
{
ORTA=0x00;
ORTB=0xff;
LEDD=table[leddat];
msec(2);
ORTA=0xff;
LEDD=table[leddat];
ORTB=0x00;
msec(2);
ORTB=0xFF;
}
//主函数
main()
{
C_T2=0; //T2工作在定时器
CP_RL2=0; //自动装栽
RCAP2H=TH2=TIME_H;
RCAP2L=TL2=TIME_L;
EA=1;
ET2=1;
TR2=1;
while(1)
{ dir(key_value);
}
}
展开阅读全文