从左到右的流水灯的制作(重点)
#include <reg51.h>
#include <intrins.h> //移位函数的头文件
unsigned int j;
void Delay(unsigned int i) // 延时函数
{while(i--) // 注意这里是i--{for(j = 0;j < 120;j++); // 注意这里是120}
}void main()
{P1 = 0xFE;while(1){P1 = _crol_(0,1); //数据每次左移一位// crol函数是循环左移函数,即把挪出去的那一位补在后面空的一位//<<是左移函数,会在空的那一位补0Delay(100);}
}
左到右的来回流水灯的制作
#include <reg51.h>
#include <>
void Delay(unsigned int i)
{while(i--){for(j=0;j<120;j++);}
}unsigned int x;
unsigned int y;void main()
{P1 = 0xFE;while(1){for(x=0;x<8;x++){P1 = _crol_(0,1);Delay(100);}for(y=0;y<8;y++){P1 = _cror_(0,1);Delay(100);}}
}
开关量检测指示器
#include <reg51.h>
void Delay(unsigned int i)
{while(i--){for(int j=0;j<120;j++);}
}
void main()
{while(1){if(P1_4 == 0){Delay(20);while(P1_4==0);Delay(20);P1_0 = 0;}if(P1_5 == 0){Delay(20);while(P1_5==0);Delay(20);P1_1 = 0;}if(P1_6 == 0){Delay(20);while(P1_6==0);Delay(20);P1_2 = 0;}if(P1_7 == 0){Delay(20);while(P1_7==0);Delay(20);P1_3 = 0;}}
}
单一外中断的应用
#include <reg51.h>
void Delay(unsigned int i)
{while(i--){for(j=0;j<120;j++);}
}void EX0_Init()
{EA = 1;EX0 = 1;IT0 = 1; // 负跳沿触发IT = 1 低电平触发IT = 0
}void do_EX0() interrupt 0
{EX0 = 0;while(1){P1 = 0xF0;Delay(100);P1 = 0x0F;Delay(100);}EX0 = 1;
}void main()
{P1 = 0x00;EX0_Init();while(1);
}
两个外中断的应用
#include <reg51.h>
void Delay(unsigned int i)
{while(i--){for(j=0;j<120;j++);}
}void EX_Init()
{EA = 1;EX0 = 1;EX1 = 1;IT0 = 1;IT1 = 1;IP1 = 1;IP0 = 1; // 两个中断都设置为高优先级
}void do_EX0() interrupt 0
{while(1){P1 = 0xF0;Delay(100);P1 = 0x0F;Delay(100);}
}void do_EX1() interrupt 2
{P1 = 0x00;
}void main()
{EX_Init();while(1){//流水灯代码}
}
ps:这个代码因为设置了同级中断,所以在进入任何一个中断后,另一个中断不会被响应
中断嵌套(重点)
#include <reg51.h>
void Delay(unsigned int i)
{while(i--){for(j=0;j<120;j++);}
}void EX_Init()
{EA = 1;EX0 = 1;EX1 = 1;IT0 = 1;IT1 = 1; // 设置触发方式IP0 = 0;IP1 = 1; //设置优先级
}void do_EX0() interrupt 0
{while(1){P1 = 0xF0;Delay(100);P1 = 0x0F;Delay(100);}
}void do_EX1() interrupt 2
{P1 = 0x00;Delay(100);P1 = 0xFF;Delay(100);
}void main()
{EX_Init();while(1){//流水灯代码}
}
多外部中断源系统设计(非重点)
#include <reg51.h>
void EX_Init()
{EA = 1;EX0 = 1;EX1 = 1;IT0 = 1;IT1 = 1;IP0 = 1; // 将外部中断0设置为最高优先级IP1 = 0;
}void do_EX0() interrupt 0
{P1 = 0xFF; // 进入外部中断0,熄灭所有灯
}void do_EX1() interrupt 2
{if(P1_0 == 0){P1_4 = 0;}if(P1_1 == 0){P1_5 = 0;}if(P1_2 == 0){P1_6 = 0;}if(P1_3 == 0){P1_7 = 0;}
}void main()
{EX_Init();while(1);
}
P1口外接的8只LED每0.5s闪亮一次
#include <reg51.h>
//计算初值
//公式:定时时间 = (2^16-初值X)*(12/fos) 其中(2^16-初值X)即为TH0和TL0的值
//定时时间为0.5s 也就是5000us 即初值X≈60927
void Timer0_Init()
{TMOD = 0x01;TH1 = 60927/256;TL1 = 60927%256;EA = 1;ET0 = 1;TR0 = 1;
}void do_Timer0() interrupt 1
{P1 = ~P1;TH1 = 60927/256;TL1 = 60927%256;
}void main()
{Timer0_Init();while(1);
}
计数器的应用(重点)
#include <reg51.h>
void Delay(unsigned int i)
{while(i--){if(j=0;j<120;j++);}
}void Timer1_Init()
{TMOD = 0x50; //0101 0000TH1 = 0xFF;TL1 = 0xFC;EA = 1;ET1 = 1;TR1 = 1;
}void do_Timer1() interrupt 3
{while(1){P1 = 0xFF;Delay(100);P1 = 0x00;Delay(100);}
}void main()
{Timer1_Init();while(1);
}
扩展一个外部中断源(非重点)
#include <reg51.h>
void Timer0_Init()
{TMOD = 0x06;TH0 = 0xFF;TL0 = 0xFF;ET0 = 1;TR0 = 1;TF0 = 0; //溢出标志位清零
}void main()
{Timer0_Init();while(1);
}
在P1.0上产生周期为2ms的方波
#include <reg51.h>
//计算初值
//产生周期为2ms的方波,即要要让P1.0口每1ms翻转一次,所以定时器1需要定时1ms
//定时时间 = (2^16-X)*(12/fos)
//此时的定时时间为1ms,即1000us
// X = 65536-1000
void Timer1_Init()
{TMOD = 0x10;//0001 0000TH1 = (65536-1000)/256;TL1 = (65536-1000)%256;EA = 1;ET1 = 1;TR1 = 1;
}void do_Timer1() interrupt 3
{P1_0 = !P1_0;TH1 = (65536-1000)/256;TL1 = (65536-1000)%256; //重置初值
}void main()
{Timer1_Init();P1_0 = 0;while(1);
}
在P1.1上产生周期为1s的方波
多次中断法(推荐)
#include <reg51.h>
//这个题目的定时时间应该是1s/2 = 0.5s 0.5s = 500ms
//定时时间比较长,我们此时采用多次中断的方式来定时
//还是采用定时1的方式1来定时,可以让定时器1一次产生50ms的定时 一共定时10次
//50ms = 50000us
//X = 65536-50000
void Timer1_Init()
{TMOD = 0x10;TH1 = (65536-50000)/256;TL1 = (65536-50000)%256;EA = 1;ET1 = 1;TR1 = 1;
}unsigned int count;
void do_Timer1() interrupt 3
{count++;if(count == 10){count = 0;P1_1 = !P1_1;}TH1 = (65536-50000)/256;TL1 = (65536-50000)%256;
}void main()
{Timer1_Init();P1_1 = 0;while(1);
}
双定时器法(不推荐)
T1控制发出1KHZ的音频信号(重点)
#include <reg51.h>
//书上写的计算初值是错误的,以下面注释为准
//产生1KHZ的音频信号,也就是产生音频信号的周期为1ms 所以需要定时的时间为0.5ms
//由0.5ms = 500us 500/1.08 = 460
// X = (65536-460)
void Timer1_Init()
{TMOD = 0x10;TH1 = (65536-460)/256;TL1 = (65536-460)%256;EA = 1;ET1 = 1;TR1 = 1;
}void do_Timer1() interrupt 3
{P1_7 = !P1_7;TH1 = (65536-460)/256;TL1 = (65536-460)%256;
}void main()
{P1_7 = 0;Timer1_Init();while(1);
}
测量脉冲宽度——门控位GATEx的应用(非重点)
#include <reg51.h>
unsigned count_high; // 读取TH0
unsigned count_low; // 读取TL0
//最后INT1的正脉冲宽度以机器周期数的形式读入到上面俩变量中
//正脉冲是一个周期信号中高电平的信号
void read_count()
{do{count_high = TH1;count_low = TL1;...//可进行显示或其他处理}while(count_high!=TH1)
}void main()
{TMOD = 0x90; // 1001 0000//需要注意的是:当单片机的GATE为1的时候,如果要打开定时器,除了TR1=1以外还需要INT1=1才可以真正开启定时器TH1 = 0;TL1 = 0;TR1 = 1;while(P3_3 == 1); //等待P3_3为低电平TR1 = 1; //P3_3为低电平的时候,TR1=1,但是此时定时器并未被真正开启,还需要INT1=1while(P3_3 == 0);//等待P3_3为高电平while(P3_3 == 1); //P3_3为高电平后,真正打开定时器,开始计数TR1 = 0;//读取函数read_count();
}
串口 方式0输出输入(非重点)
例题
#include <reg51.h>
#include <stdio.h>
unsigned char nIndex;
unsigned char nSendByte;void Delay()
{static int i = 100;static int j = 0;while(i--){for(j=0;j<120;j++);}
}void Serial_Init()
{SCON = 0x00; // 串口为方式0EA = 1;ES = 1; // 开启串口中断
}void dp_Serial() interrupt 4
{if(TI == 1) //发送中断标志位{P1_0 = 1;Delay();P1_0 = 0;nSendByte << 1;if(nSendByte == 0){nSendByte = 1;}SBUF = nSendByte;}TI = 0;RI = 0;
}void main()
{Serial_Init();nIndex = 1;SBUF = nSendByte;P1_0 = 0; //使能位while(1);
}
#include <reg51.h>
unsigned char nRxData;void Serial_Init()
{SCON = 0x00;EA = 1;ES = 1;
}void do_Serial() interrupt 4
{if(RI == 1) //接收到了数据{nRxData = SBUF;}TI = 0;RI = 0;
}void main()
{while(1){if(P1_0 == 0){P1_1 = 0;P1_1 = 1;}}
}
方式1的应用
#include <reg51.h>
//甲机发送程序
unsigned char temp;void Serial_Init()
{PCON = 0x00; // 波特率不倍增SCON = 0x40; // 0100 0000 SM2位只能在方式二和方式三多机通信//串口的方式一专门是为了双机通信设置的TMOD = 0x20;// 0010 0000TH1 = 0xFD;TL1 = 0xFD; // 波特率9600TR1 = 1;P1 = 0xFF; //P1口输入的时候,需要拉高电平
}void main()
{while(1){temp = P1;SUBF = temp;//查询方式,无需申请中断while(TI == 0); //TI = 1 说明一帧数据发送完毕TI = 0;}
}//乙机接收程序
unsigned char temp;
void Serial_Init()
{PCON = 0x00;SCON = 0x50;//0101 0000TMOD = 0x20;//0010 0000TH1 = 0xFD;TL1 = 0xFD;TR1 = 1;
}void main()
{while(1){//查询方式while(RI == 0);RI = 0;temp = SBUF;P1 = temp;}
}
方式2和方式3的应用
#include <reg51.h>
sbit p = PSW_0;
//甲机发送程序
unsigned char Tab[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水灯显示数据void Delay()
{unsigned int i = 100;unsigned int j;while(i--){for(j=0;j<120;j++);}
}void Serial_Init()
{SCON = 0xC0;//1100 0000 注意这里的SM2位不需要为1PCON = 0x00;TMOD = 0x20;//0010 0000TH1 = 0xFD;TL1 = 0xFD; //波特率9600EA = 1;ES = 1;TR1 = 1;
}void Send(unsigned char data)
{ACC = data; //把data数据暂存到ACC寄存器中TB8 = p; //奇偶校验位SBUF = data; //准备发送数据while(TI == 0); //等待数据发送TI = 0;
}unsigned int count;
void main()
{Serial_Init();while(1){for(count=0;count<8;count++){Send(Tab[count]);Delay(); //等待一段时间再发送}}
}//乙机接收程序
sbit p = PSW_0;unsigned char Receive()
{unsigned char data;while(RI == 0); // 等待接收 查询方式RI = 0;ACC = SBUF;if(RB8 == p) //奇偶校验{data = ACC;return data;}
}void Serial_Init()
{SCON = 0xD0; // 1101 0000 注意这里需要把REN位也置为1PCON = 0x00;TMOD = 0x20;TL0 = 0xFD;TH0 = 0xFD; //波特率9600EA = 1;ES = 1;TR1 = 1;
}void main()
{while(1){P1 = Receive();}
}
单片机向计算机发送数据(重点)
#include <reg51.h>
unsigned char Tab[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水灯显示数据void Send(unsigned char data)
{SBUF = data;while(TI == 0); // 等待单片机发送数据结束TI = 0;
}void Delay()
{unsigned int i = 100;unsigned int j;while(i--){for(j=0;j<120;j++);}
}void Serial_Init()
{SCON = 0x40;//0100 0000PCON = 0x00;TMOD = 0x20;TH1 = 0xFD;TL1 = 0xFD; //波特率9600EA = 1;ES = 1;//EA和ES可以不写,因为这里用的是查询方式TR1 = 1;
}unsigned int count;
void main()
{Serial_Init();while(1){for(count=0;count<8;count++){Send(Tab[count]);Delay();}}
}
单片机接收计算机发送的数据(重点)
#include <reg51.h>
void Serial_Init()
{SCON = 0x50;//0101 0000PCON = 0x00;TMOD = 0x20;TL1 = 0xFD;TH0 = 0xFD; //波特率9600EA = 1;ES = 1; //EA和ES可以不写,因为这里用的是查询方式TR1 = 1;
}unsigned char Recevive()
{unsigned char data;while(RI == 0); //接收数据RI = 0;data = SBUF;return data;
}void main()
{Serial_Init();while(1){P1 = Receive();}
}
数码管的实现(重点)
#include <reg51.h>
unsigned char Nixie_Table[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};void Delay(unsigned int i)
{unsigned int j;while(i--){for(j=0;j<120;j++);}
}void Nixie(unsigned location,unsigned number)
{switch(location){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 9:P2_4=0;P2_3=0;P2_2=0;break;}P0 = Nixie_Table[number];Delay(1);P0 = 0x00; // 消影子
}
矩阵键盘的实现(重点)
#include <reg51.h>void Delay(unsigned int i)
{unsigned int j;while(i--){for(j=0;j<120;j++);}
}unsigned char MartrixKey()
{unsigned char KeyNumber;P1 = 0xFF;P1_3 = 0;if(P1_7 == 0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}if(P1_6 == 0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}if(P1_5 == 0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}if(P1_4 == 0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}P1 = 0xFF;P1_2 = 0;if(P1_7 == 0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}if(P1_6 == 0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}if(P1_5 == 0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}if(P1_4 == 0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}P1 = 0xFF;P1_1 = 0;if(P1_7 == 0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}if(P1_6 == 0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}if(P1_5 == 0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}if(P1_4 == 0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}P1 = 0xFF;P1_0 = 0;if(P1_7 == 0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}if(P1_6 == 0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}if(P1_5 == 0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}if(P1_4 == 0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}return KeyNumber;
}
DAC0832输出锯齿波
#include <reg51.h>
#include <absacc.h>
#define DAC0832 XBYTE[0x7FFF]void stair()
{unsigned char i;for(i=0;i<255;i++){DAC0832 = i;}
}
DAC0832输出三角波
#include <reg51.h>
#include <absacc.h>
#define DAC0832 XBYTE[0x7FFF]void triangle()
{unsigned char i;for(i=0;i<255;i++){DAC0832 = i; //上升沿}for(i=255;i>0;i--){DAC0832 = i; // 下降沿}
}
DAC0832输出矩形波
#include <reg51.h>
#include <absacc.h>
#define DAC0832 XBYTE[0x7FFF]void rectangular()
{DAC0832 = 0xAF; //上限电平Delay();DAC0832 = 0x10; //下限电平Delay()
}
ADC转换
#include <reg51.h>
#include <absacc.h>
#define ADCstart 0x7FFF
#define ADCdata 0x2000unsigned char i;
void main()
{i = 8; //8路模拟信号EA = 1;EX1 = 1;IT1 = 1;XBYTE[ADCstart] = i;while(i);
}void int1() interrupt 2
{unsigned char temp;temp = XBYTE[ADCstart];i--;XBYTE[ADCdata+i] = temp;XBYTE[ADCstart] = i;
}