单片机编程培训

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机编程培训
〔可用C语言/汇编语言〕
要求:每周做一个实验〔共六周〕,做完后要写好实验总结〔侧重于对实验内容的认识与心得〕并提交。

实验有用编程软件〔如KEIL〕做,然后用仿真软件〔如proteus〕或单片机〔如情况允许〕调试仿真;实验要自己独立完成,可参考一些例程。

1.I/0口控制:P1口接八个独立按键,P3口接八个LED 灯。

当P1口有按键按下时,P3口对应的灯亮。

2.流水灯:循环控制八个LED灯。

3.数码管动态扫描:八个数码管,每位显示不同的数字。

4.独立按键与数码管显示:对假设干个独立按键赋予不同的数值,当键盘按下时,数码管显示数字。

5.矩阵键盘:掌握行列扫描方法,和去抖方法;
6.定时器/中断:
主程序:自己设计〔如点亮LED1灯〕;
定时器0中断程序:自己设计〔如主程序的LED1灯熄灭,点亮另外一盏LED2灯。

〕;
要求中断过后〔LED2灯灭〕,主程序正常执行〔LED1灯亮〕;
03. IO口信号输入
while (1)
{
P1=P3;
}
04. IO读写操作程序
按下P3口的按键,P1显示相应的位置#include<reg52.h>
sbit KEY = P3^0;//定义按键的接口
sbit LED = P1^0;//定义灯的接口
void main (void)
{
P1 = 0xFF; //所有的灯灭
while (1)
{
LED = KEY; //灯的状态由按键的状态决定
}
}
#include<reg52.h>
void delay(unsigned int cnt)
{
while(--cnt);
}
main()
{
P1=0xfe; //给初始化值换算成二进制是1111 1110
while(1)
{
delay(3000);//延时程序
P1<<=1; //左移一位该语句等效于P1=P1<<1
P1|=0x01; //最后一位补1,该语句等效于P1=P1|0x01 符号"|"表示"或"
if(P1==0x7f) //检测是否移到最左端?"=="表示检测符号2端的值是否相等{
delay(30000);
P1=0xfe; //重新赋值
}
}
}
06.
//按下P3口的按键,P1显示相应的位置,IO读写操作程序
sfr P1 = 0x90; /* SFR definition for Port 1 */
sfr P3 = 0xB0; /* SFR definition for Port 3 */
void main (void)
{
unsigned char pval;
P1 = 0xFF;
while (1)
{
pval = P3; /* Read P1 into pval */
P1 = pval; /* Write pval to P3 */
}
}
#include<reg52.h>
Unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值01234567
unsigned char code seg[]={0,1,2,3,4,5,6,7};//分别对应相应的数码管点亮,即位码
void delay(unsigned int cnt)
{
while(--cnt);
}
main()
{
unsigned char i;
while(1)
{
P0=dofly[i];//取显示数据,段码
P2=seg[i]; //取位码
delay(200); //扫描间隙延时,时间太长会闪烁,太短会造成重影
i++;
if(8==i) //检测8位扫描完全?
i=0;
}
}
内容:切换到独立按键模式,通过按键在数码管显示对应的数字
#include<reg52.h>
sbit key1=P3^0; //定义按键位置
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
void delay(unsigned int cnt)
{
while(--cnt);
}
main()
{
P2=0x00;
while(1)
{
if(!key1) //按下相应的按键,数码管显示相应的码值
P0=0x06;//数码管显示"1"
if(!key2)
P0=0x5B;//2
if(!key3)
P0=0x4F;//3
if(!key4)
P0=0x66;//4
}
}
//如果有干扰请加去抖程序
//红外接收头局部用黑色物质遮光,防止干扰按键,因为红外接收和按键使用同一个端口
独立按键
#include<reg52.h>sbit key1=P3^0; //定义按键位置
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
void delay(unsigned int cnt)
{
while(--cnt);
}
main()
{
P2=0x00;
while(1)
{
if(!key1)
{ //按下相应的按键,数码管显示相应的码值
delay(1000);
if(!key1)
{
P0=0x06;//数码管显示"1"
}
}
if(!key2)
{ //按下相应的按键,数码管显示相应的码值
delay(1000);//去抖动
if(!key2) //检测按键确实按下,进行按键处理
{
P0=0x5B;//数码管显示"2"
//这里可以添加按键按下所需要的操作,如数据加减乘除,蜂鸣器等设备开关
}
}
if(!key3)
{ //按下相应的按键,数码管显示相应的码值
delay(1000);
if(!key3)
{
P0=0x4F;//数码管显示"3"
}
}
if(!key4)
{ //按下相应的按键,数码管显示相应的码值
delay(1000);
if(!key4)
{
P0=0x66;//数码管显示"4"
}
}
}
}
矩阵键盘
//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍
#include <reg52.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
uchar keyscan(void);
void delay(uint i);
void main()
{
uchar key;
P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符
while(1)
{
key=keyscan();//调用键盘扫描,
switch(key)
{
case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
void delay(uint i)//延时函数
{
while(i--);
}
*This sample is used for Timer0 16bit timer mode. #include<reg52.h>
sbit LED=P1^2;
void Init_Timer0(void)
{
TMOD |= 0x01;
TH0=0x00; /* Init value */
TL0=0x00;
EA=1; /* interupt enable */
ET0=1; /* enable timer0 interrupt */
TR0=1;
}
main()
{
Init_Timer0();
while(1);
}
void Timer0_isr(void) interrupt 1 using 1
{
TH0=0x00; /* Init value */
TL0=0x00;
LED=~LED;//指示灯反相
}
*This sample is used for Timer1 16bit timer mode. #include<reg52.h>
sbit LED=P1^2;
void Init_Timer1(void)
{
TMOD |= 0x10;
TH1=0x00; /* Init value */
TL1=0x00;
EA=1; /* interupt enable */
ET1=1; /* enable timer1 interrupt */
TR1=1;
}
main()
{
Init_Timer1();
while(1);
}
void Timer1_isr(void) interrupt 3 using 1
{
TH1=0x00; /* Init value */
TL1=0x00;
LED=~LED;
}
20.
外部中断0电平触发
内容:通过中断接口P3.2连接的独立按键测试,按一次P1口的LED灯反向,这里使用电平触发,所以一直按键不松开和一次按键效果不相同,按下会看到灯全部亮,说明中断一直在作用
#include<reg52.h>
main()
{
P1=0x55; //P1口初始值
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=0; //电平触发
while(1)
{
//在此添加其他程序
}
}
外部中断程序
void ISR_Key(void) interrupt 0 using 1
{
P1=~P1;
}
内容:通过中断接口P3.2连接的独立按键测试,按一次P1口的LED灯反向,这里使用边沿触发,所以一直按键不松开和一次按键效果相同,区别于电平触发
#include<reg52.h>
main()
{
P1=0x55; //P1口初始值
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=1; //边沿触发
while(1)
{
//在此添加其他程序
}
}
外部中断程序
void ISR_Key(void) interrupt 0 using 1
{
P1=~P1; //s3按下触发一次,P1取反一次,这里需要切换跳帽到独立按键模式}。

相关文档
最新文档