AT89S52语言常用程序

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

一、闪烁灯
#include <reg52.h>//
sbit gate=P2^0;// 定义P2-0口
void main(void)
{
unsigned int i,j;
while(1)
{
for(i=500;i>0;i--)
for(j=500;j>0;j--);// 双重循环,延时约1秒
gate=!gate;// 对P-0口取反,控制小灯的亮灭
}
}
#include <reg52.h>
#define uint unsigned int
sbit gate1=P2^0; // 定义P2-0口
sbit gate2=P2^1; // 定义P2-1口
sbit gate3=P2^2; // 定义P2-2口
sbit gate4=P2^3; // 定义P2-3口
void main(void)
{
uint i,j;
while(1)
{
for(i=250;i>0;i--)
for(j=250;j>0;j--); // 双重循环,延时约0.2秒
gate1=!gate1; // 对P-0口取反,控制小灯的亮灭 gate2=!gate2; // 对P-1口取反,控制小灯的亮灭 gate3=!gate3; // 对P-2口取反,控制小灯的亮灭 gate4=!gate4; // 对P-3口取反,控制小灯的亮灭
}
}
#include <reg52.h>
#include <absacc.h>
#define unit unsigned int
#define uchar unsigned char
sbit L0=P2^0;
sbit L1=P2^1;
sbit L2=P2^2;
sbit L3=P2^3;
uchar data BUFFER[1]={0}; /*定时器计数变量*/
void main(void)
{
P2=0x0f; // 初始化端口
EA=1; IT1=1; ET0=1;
TMOD=0x01; /* T0方式1计时0.01秒 */
TH0=-5000/256;
TL0=-5000%256;
TR0=1; /* 开中断,启动定时器 */
for (;;);
}
/* 定时计数器0的中断服务子程序 */
void intserv1(void) interrupt 1 using 1
{
TH0=-5000/256; // 定时器T0的高四位赋值
TL0=-5000%256;
BUFFER[0]=BUFFER[0]+1; // 定时器T0的低四位赋值
if (BUFFER[0]==100) // 百分秒进位
{
L3=!L3;
L2=!L2;
L1=!L1;
L0=!L0;
}
}
二、串口的简单测试程序
# include <reg52.h>
void main(void)
{
unsigned char astring;
/*在11.0592MHz晶振下,设置串行口9600数据传输率,方式3*/ TMOD=0x20;
TL1=0xfd;TH1=0xfd;
SCON=0xd8;PCON=0x00; /*串口接收字符RI置位,允许串口接收*/ TR1=1;
while(1)
{
while(RI==0);
RI=0; /*串口接收标志位的软件清零*/
astring=SBUF;
}
}
三、行列键盘的输入例程
#include <reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
void delays(void);
uchar kbscan(void);
void main(void)
{
uchar key;
while(1)
{
key=kbscan(); /*键扫描函数*/
delays(); /*键消抖的延时函数*/
}
}
// 键消抖的延时函数
void delays(void)
{
uchar i;
for(i=300;i>0;i--);
}
// kbscan(void) 键扫描函数
uchar kbscan(void)
{
uchar sccode,recode;
P1=0xf0; /*发全"0"行扫描码,列线输入*/
if((P1&0xf0)!=0xf0) /*若有键按下*/
{
delays(); /*延时去抖动*/
if((P1&0xf0)!=0xf0)
{
sccode=0xfe; /*逐行扫描初值*/
while((sccode&0x10)!=0)
{
P1=sccode; /*输出行扫描码*/
if((P1&0xf0)!=0xf0) /*本行有键按下*/
{
recode=(P1&0xf0)|0x0f;
return((~sccode)+(~recode)); /*返回特征字节码*/
}
else sccode=(sccode<<1)|0x01;/*行扫描码左移一位*/
}
}
}
return(0); /*无键按下,返回值为0*/
}
四、锁定键盘的程序
#include <reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
void delays(void);
uchar kbscan(void);
main()
{
bit CRT; /*密码正确标志,=1密码正确*/
bit PRT; /*密码部分输入标志,=1密码部分输入*/
uchar COUNT; /*计数单元,存放密码正确的位数*/
uchar KEY; /*被按下的键的编码*/
CRT=0;
PRT=0;
COUNT=0;
KEY=kbscan(); /*键扫描函数*/
delays(); /*键消抖的延时函数*/
switch (KEY)
{
case 0xb7: /*0键*/
{
if (CRT)
{
}
else /*密码不正确时*/
{
if (PRT) /*部分密码正确时*/
{
COUNT=COUNT+1; /*密码正确的位数加1*/
if (COUNT==3) /*密码所有位都正确*/
{
CRT=1;
PRT=0;
COUNT=0;
}
}
}
}; break;
case 0x7e: /*1键*/
{
if (CRT)
{
/*密码正确时的操作内容*/
}
else /*密码不正确时*/
{
PRT=0;
COUNT=0;
}
}; break;
case 0xbe: /*2键*/
{
if (CRT)
{
/*密码正确时的操作内容*/
}
else /*密码不正确时*/
{
if (PRT) /*部分密码正确时,说明密码错误*/
{
PRT=0;
COUNT=0;
}
else /*密码正确位数为0时,说明密码第一位正确*/
{
PRT=1;
COUNT=1;
}
}
}; break;
case 0xd7: /*#键*/
{
if (CRT) /*密码正确时,锁定键盘*/
{
CRT=0;
PRT=0;
COUNT=0;
}
}; break;
}
}
// 键消抖的延时函数
void delays(void)
{
uchar i;
for(i=300;i>0;i--);
}
// kbscan(void) 键扫描函数
uchar kbscan(void)
{
uchar sccode,recode;
P1=0xf0; /*发全"0"行扫描码,列线输入*/
if((P1&0xf0)!=0xf0) /*若有键按下*/
{
delays(); /*延时去抖动*/
if((P1&0xf0)!=0xf0)
{
sccode=0xfe; /*逐行扫描初值*/
while((sccode&0x10)!=0)
{
P1=sccode; /*输出行扫描码*/
if((P1&0xf0)!=0xf0) /*本行有键按下*/
{
recode=(P1&0xf0)|0x0f;
return((~sccode)+(~recode)); /*返回特征字节码*/
}
else sccode=(sccode<<1)|0x01; /*行扫描码左移一位*/
}
}
}
return(0); /*无键按下,返回值为0*/
}
五、单片机中的多路模拟开关例程
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define adch0 XBYTE[0x0000]
sbit P1_3=P1^3;
sbit P1_2=P1^2;
uint ch0datal,ch0datah,i,light;
void main(void)
{
EA=1; PT0=1; // 开外中断,并设置定时器;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
TH0=0xB9; // 设置定时器的初值;
TL0=0xB0;
TR0=1;
TI=1;
ch0datah=0;
ch0datal=0;
P1_3=0; // 设置控制端口的初值;
P1_2=0;
while(1){} // 等待外部的控制信号;
}
void intsvr1(void) interrupt 1 // 定时器1模拟外部控制信号的进入{
TH0=0xB9;
TL0=0xB0;
TR0=1;
light=light+1;
if (light>1000)
{
P1_3=!P1_3; // MAX333的控制信号取反,工作方式变化;
P1_2=!P1_2;
light=0; // 标志位显示当前的工作状态;
}
}
六、单片机控制的数码管显示
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#define DIGPORT XBYTE [0x8000] /* 定义字位口 */
#define WORDPORT XBYTE [0x4000] /* 定义字型口 */
#define uchar unsigned char
/* 定义共阴极字型编码表(数字0~9)*/
uchar code TABLE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 显示:得到字型和字位口的地址后,向不同的字位送数据,进行数据的显示。

// 数码管显示计数值个位
uchar digit;
uchar disp,delay; // 对计数值取余数
main()
{
TMOD=0x60; /* T0方式1计时0.01秒 */ TH1=0;
TL1=0;
EA=1; ET1=0; TR1=1; /* 开中断,启动定时器 */
for (;;)
{
/* 数码管显示计数值低位 */ digit=0x08;
disp=TL1%10;
DIGPORT=digit;
WORDPORT=TABLE[disp];
for (delay=0;delay<=200;delay++);
//…显示其它位的数据
}
}
七、单片机的数字时钟例程
#include <reg52.h>
#include <absacc.h>
#define unit unsigned int
#define uchar unsigned char
/*定义字型字位口*/
#define DIGPORT XBYTE [0x8000]
#define WORDPORT XBYTE [0x4000]
/*定义P1口各管脚*/
sbit K0=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
sbit BEEP=P1^3;
sbit L0=P1^4;
sbit L1=P1^5;
sbit L2=P1^6;
sbit L3=P1^7;
uchar data BUFFER[2]={0,0}; /*显示缓冲区(依次为低位,高位)*/
uchar data CLOCK[4]={0,0,0,0}; /*存放时钟时间(依次为百分秒,秒,分和时位)*/ uchar data SECOND[2]={0,0}; /*存放秒表时间(依次为百分秒,秒)*/
uchar data REVERSE[4]={0,0,0,0}; /*存放倒计时时间(依次为百分秒,秒,分和时位)*/
/*定义运行状态*/
uchar data STATE=0;
/*STATE=0,秒表*/
/*STATE=1,倒计时分调整*/
/*STATE=2,倒计时小时调整*/
/*STATE=3,倒计时运行*/
/*STATE=4 or 7,时钟运行*/
/*STATE=5,时钟分调整*/
/*STATE=6,时钟时调整*/
bit bdata SND=0; /*秒表START*/
bit bdata RST=0; /*秒表RESET*/
bit bdata STP=0; /*倒计时STOP*/
/*数码管显示编码"0"-"9","A","-"*/
uchar code TABLE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x40};
void display(void)
{
uchar i; /*显示缓冲区首址*/
uchar delay; /*显示延时*/
uchar disp; /*显示内容*/
uchar digit; /*定义数码管显示位*/
digit=0x08;
for (i=0;i<2;i++) /*秒表,显示百分秒和秒*/
{
if (BUFFER[i]>100) disp=BUFFER[i]%10+10;
else disp=BUFFER[i]%10;
DIGPORT=digit;
WORDPORT=TABLE[disp];
for (delay=0;delay<=200;delay++);
digit=digit>>1;
disp=BUFFER[i]/10;
DIGPORT=digit;
WORDPORT=TABLE[disp];
for (delay=0;delay<=200;delay++);
digit=digit>>1;
}
}
void timer0(void) interrupt 1 using 1 {
/*重置定时初值*/
TH0=-5000/256;
TL0=-5000%256;
/*时钟处理*/
CLOCK[0]=CLOCK[0]+1;
if ((CLOCK[0]==50) && (STATE>=4))
{
L0=!L0;
}
if (CLOCK[0]==100)
{
if (STATE>=4) L0=!L0;
CLOCK[0]=0;
CLOCK[1]=CLOCK[1]+1;
if (CLOCK[1]==60)
{
CLOCK[1]=0;
CLOCK[2]=CLOCK[2]+1;
if (CLOCK[2]==60)
{
CLOCK[2]=0;
CLOCK[3]=CLOCK[3]+1;
if (CLOCK[3]==24)
{
CLOCK[3]=0;
}
}
}
}
}
void timer2(void) interrupt 5 using 3 {
TF2=0;
TH2=-5000/256;
TL2=-5000%256;
/*秒表处理*/
if (STATE==0)
{
SECOND[0]=SECOND[0]+1;
if (SECOND[0]==50)
{
L1=!L1;
}
if (SECOND[0]==100)
{
L1=!L1;
SECOND[0]=0;
SECOND[1]=SECOND[1]+1;
if (SECOND[1]==100)
{
SECOND[1]=0;
}
}
}
/*倒计时处理*/
if (STATE==3)
{
REVERSE[0]=REVERSE[0]+1;
if (REVERSE[0]==50)
{
L2=!L2;
}
if (REVERSE[0]==100)
{
L2=!L2;
REVERSE[0]=0;
REVERSE[1]=REVERSE[1]+1;
if (REVERSE[1]==60)
{
REVERSE[1]=00;
REVERSE[2]=REVERSE[2]-1;
if ((REVERSE[2]==0) && (REVERSE[3]==0)) {
TR2=0;
STP=1;
BEEP=0;
}
else if (REVERSE[2]==0xff)
{
REVERSE[2]=59;
REVERSE[3]=REVERSE[3]-1;
}
}
}
}
}
void intsvr1(void) interrupt 2 using 2 {
if (STATE==5)
{
CLOCK[2]=CLOCK[2]+1;
if (CLOCK[2]==60) CLOCK[2]=0;
}
if (STATE==6)
{
CLOCK[3]=CLOCK[3]+1;
if (CLOCK[3]==24) CLOCK[3]=0;
}
}
void timer1(void) interrupt 3 using 3 {
if (STATE==0)
{
if (RST)
{
SECOND[0]=0;
SECOND[1]=0;
L1=1;
RST=0;
}
else
{
if (SND) TR2=1;
else
{
L1=1;
TR2=0;
RST=1;
}
SND=!SND;
}
}
else if (STATE==1)
{
REVERSE[2]=REVERSE[2]+1;
if (REVERSE[2]==60) REVERSE[2]=0;
}
else if (STATE==2)
{
REVERSE[3]=REVERSE[3]+1;
if (REVERSE[3]==24) REVERSE[3]=0;
}
else
{
if (STP)
{
BEEP=1;
L2=1;
STP=0;
}
else TR2=0;
}
}
void main(void)
{
uchar stabak; /*上一次程序运行的状态*/
P1=0x0f;
EA=1; IT1=1; ET0=1;
TMOD=0x61; /*T1方式2计数,T0方式1计时*/ TH0=-5000/256; TL0=-5000%256;
TH1=0xff; TL1=0xff;
T2CON=0; TH2=-5000/256; TL2=-5000%256;
K0=1; K1=1; K2=1;
STATE=P1&0x07;
stabak=STATE;
for (;;)
{
switch (STATE)
{
case 0: /*STATE=0,秒表*/
{
EX1=0; ET1=1; ET2=1; TR1=1; SND=1;
L1=1; L0=0; L2=0;
SECOND[0]=0;
SECOND[1]=0;
} break;
case 1: /*STATE=1,倒计时分调整*/
{
EX1=0; ET1=1; ET2=1; TR1=1; TR2=0;
L2=1; L0=0; L1=0;
REVERSE[0]=0;
REVERSE[1]=0;
} break;
case 2: /*STATE=2,倒计时小时调整*/ {
EX1=0; ET1=1; ET2=1; TR1=1; TR2=0;
L2=1; L0=0; L1=0;
REVERSE[0]=0;
REVERSE[1]=0;
} break;
case 3: /*STATE=3,倒计时运行*/
{
EX1=0; ET1=1; ET2=1; TR1=1;
if ((REVERSE[2]==0)&&(REVERSE[3]==0)) L2=1;
else TR2=1;
L0=0; L1=0;
} break;
case 5: /*STATE=5,时钟分调整*/
{
IE1=0; EX1=1; ET1=0; ET2=1; TR0=0;
L0=1; L1=0; L2=0;
} break;
case 6:/*STATE=6,时钟时调整*/
{
IE1=0; EX1=1; ET1=0; ET2=1; TR0=0;
L0=1; L1=0; L2=0;
} break;
default: /*STATE=4 or 7,时钟运行*/ {
EX1=0; ET1=0; ET2=1; TR0=1;
L1=0; L2=0;
}
}
while (STATE==stabak)
{
switch (STATE)
{
case 0: /*STATE=0,秒表*/
{
BUFFER[0]=SECOND[0];
BUFFER[1]=SECOND[1];
} break;
case 1: /*STATE=1,倒计时分调整*/
{
BUFFER[0]=REVERSE[2];
BUFFER[1]=101;/*A-*/
} break;
case 2: /*STATE=2,倒计时小时调整*/
{
BUFFER[0]=110;/*-A*/
BUFFER[1]=REVERSE[3];
} break;
case 3: /*STATE=3,倒计时运行*/
{
BUFFER[0]=REVERSE[2];
BUFFER[1]=REVERSE[3];
} break;
case 5: /*STATE=5,时钟分调整*/
{
BUFFER[0]=CLOCK[2];
BUFFER[1]=101;/*A-*/
} break;
case 6: /*STATE=6,时钟时调整*/
{
BUFFER[0]=110;/*-A*/
BUFFER[1]=CLOCK[3];
} break;
default: /*STATE=4 or 7,时钟运行*/
{
BUFFER[0]=CLOCK[2];
BUFFER[1]=CLOCK[3];
}
}
display();
K0=1; K1=1; K2=1;
STATE=P1&0x07;
}
stabak=STATE;
}
}
八、微型打印机和单片机的接口程序
# include <reg52.h>
# include <absacc.h>
# define CW8155 0XEF00
# define B8155 0XEF02
# define C8155 0XEF03
# define uchar unsigned char
uchar datap;
void pchar(uchar i)
{
XBYTE[B8155]=i;
XBYTE[C8155]=0X00;
XBYTE[C8155]=0X01;
}
main(void)
{
EA=1; PT0=1; // 开外中断,并设置定时器;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
datap='*'; // 输出打印字符
pchar(datap);
}
九、DS1820温度测量程序
#include <reg51.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
sbit P3_5=P3^5;
uchar TEMP; // 温度值的变量;
uchar flag1; // 结果为负和正的标志位。

void delay (unsigned int count)
{
unsigned int i;
while (count)
{
i =200;
while (i>0) i--;
count--;
}
}
void tmreset (void) // 发送复位和初始化
{
unsigned int i;
P3_5 = 0;
i = 103;
while (i>0) i--; // 延时
P3_5 = 1;
i = 4;
while (i>0) i--;
}
bit tmpread (void) // 读取数据的一位{
unsigned int i;
bit dat;
P3_5 = 0; i++;
P3_5 = 1; i++; i++; //延时
dat = P3_5;
i = 8; while (i>0) i--; // 延时
return (dat);
}
unsigned char tmpread2 (void) //读一个字节{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
j = tmpread ();
dat = (j << 7) | (dat >> 1);
}
return (dat);
}
void tmpwrite (unsigned char dat) //写一个字节{
unsigned int i;
unsigned char j;
bit testb;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
P3_5 = 0; // 写0
i++; i++;
P3_5 = 1;
i = 8; while (i>0) i--;
}
else
{
P3_5 = 0; // 写0
i = 8; while (i>0) i--;
P3_5 = 1;
i++; i++;
}
}
}
void tmpchange(void) // ds1820 开始转换{
tmreset (); // 复位
//tmpre (); // 等待存在脉冲
delay (1); // 延时
tmpwrite (0xcc); // 跳过序列号命令tmpwrite (0x44); // 发转换命令 44H,
}
void tmp (void) // 读取温度
{
unsigned char a,b;
tmreset (); // 复位
delay (1); // 延时
tmpwrite (0xcc); // 跳过序列号命令
tmpwrite (0xbe); // 发送读取命令
a = tmpread2 (); // 读取低位温度
b = tmpread2 (); //读取高位温度
flag1=b; //若b为1则为负温
if(flag1)
{
TEMP=~a+1; //如果为负温则去除其补码}
else
{
TEMP=a;
}
}
rom() // 读取器件序列号子程序{
tmreset (); //复位
delay (1); //延时
tmpwrite(0x33); //发送读序列号子程序
}
main()
{
do{
tmpchange(); // 开始温度转换
delay(200); // 读取延时
tmp(); //读取温度
}while(1);
}
十、单片机的电流检测程序
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define adch0 XBYTE[0x0000]
sbit P1_6=P1^6;
sbit P1_7=P1^7;
uint ch0datal,ch0datah,i,light;
void main(void)
{
EA=1; PT0=1; // 开外中断,并设置定时器;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
TH0=0xB9; // 设置定时器的初值;
TL0=0xB0;
TR0=1;
TI=1;
ch0datah=0;
ch0datal=0;
P1_6=0; // 设置控制端口的初值;
P1_7=0;
while(1){} // 等待外部的控制信号;
}
void intsvr1(void) interrupt 1 // 定时器1模拟外部控制信号的进入{
TH0=0xB9;
TL0=0xB0;
TR0=1;
light=light+1;
if (light>1000)
{
P1_6=!P1_6; // 控制信号取反,工作方式变化;
P1_7=!P1_7;
light=0; // 标志位显示当前的工作状态;
}
}
十一、单片机驱动直流电机的例程
#include <reg52.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
bit gate; // 定时标志位
bit direct; /*设置电机正反转标志,0-正转;1-反转*/
sbit motor1=P1^2;
sbit motor2=P1^3; /*10-正转;01-反转*/
uchar data BUFFER[1]={0}; /*定时器计数变量*/
// 主程序,定义中断源和串口工作方式。

void main (void)
{
P2=0x0f; // 初始化端口
EA=1; IT1=1; ET0=1;
TMOD=0x01; /* T0方式1计时1秒 */
TH0=-5000/256;
TL0=-5000%256;
TR0=1; /* 开中断,启动定时器 */
gate=1; // 依据转向状态决定电机的动作
for (;;)
{
if (gate)
{
motor1=1;
motor2=0;
}
else
{
motor1=0;
motor2=1;
}
}
}
/* 定时计数器0的中断服务子程序 */
void timer0(void) interrupt 1 using 1
{
TH0=-5000/256; // 定时器T0的高四位赋值
TL0=-5000%256;
BUFFER[0]=BUFFER[0]+1; // 定时器T0的低四位赋值
if (BUFFER[0]==100) // 百分秒进位
{
gate=! gate; // 转向标志取反
}
}
十二、单片机数模输出控制LED亮度的例程
#include<reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define addatal XBYTE[0xBFFF]
#define addatah XBYTE[0xDFFF]
uint datal,datah ;
uchar data BUFFER[1]={0}; /*定时器计数变量*/
//设置P1.1,查询MAX526的工作状态
sbit P1_1=P1^1;
main()
{
EA=1; IT1=1; ET0=1;
TMOD=0x01; /* T0方式1计时1秒 */ TH0=-5000/256;
TL0=-5000%256;
TR0=1; /* 开中断,启动定时器 */
for (;;);
}
/* 定时计数器0的中断服务子程序 */
void timer0(void) interrupt 1 using 1
{
TH0=-5000/256; // 定时器T0的高四位赋值TL0=-5000%256;
BUFFER[0]=BUFFER[0]+1; // 定时器T0的低四位赋值
if (BUFFER[0]==100) // 百分秒进位
{
// 使用查询的方法读MAX526的LDAC,检测MAX526是否完成了信号的采集while(P1_1!=0)
{
// 当数据采集完成时,先读低位;
P1_1=0;
}
datal=addatal;
// 当数据采集完成时,再读高位;
P1_1=1;
datah=addatah;
P1_1=0;
}
}
十三、基于单片机的信号发生器例程
#include<reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
void delays(void);
uchar kbscan(void);
sbit A0=P2^1;
sbit A1=P2^2;
uchar key;
void delays(void)
{
uchar i;
for(i=300;i>0;i--);
}
// kbscan(void) 键扫描函数
uchar kbscan(void)
{
uchar sccode,recode;
P1=0xf0; /*发全"0"行扫描码,列线输入*/ if((P1&0xf0)!=0xf0) /*若有键按下*/
{
delays(); /*延时去抖动*/
if((P1&0xf0)!=0xf0)
{
sccode=0xfe; /*逐行扫描初值*/
while((sccode&0x10)!=0)
{
P1=sccode; /*输出行扫描码*/
if((P1&0xf0)!=0xf0) /*本行有键按下*/
{
recode=(P1&0xf0)|0x0f;
return((~sccode)+(~recode)); /*返回特征字节码*/
}
else sccode=(sccode<<1)|0x01; /*行扫描码左移一位*/
}
}
}
return(0); /*无键按下,返回值为0*/
}
void main(void)
{
uchar key;
while(1)
{
key=kbscan(); /*键扫描函数*/
delays(); /*键消抖的延时函数*/
if (key==0x7e) // 正弦波
{
A0=0;
A1=1;
}
if (key==0xbe) // 矩形波
{
A0=0;
A1=0;
}
if (key==0xbe) // 三角波
{
A0=1;
A1=0;
}
}
}
十四、低频信号发生器的例程
#include<reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
uint FREQ; /*定时器计数变量*/
uint FREQ_out; /*输出频率变量*/
uint delay;
sbit SEL0=P3^0;
sbit SEL1=P3^1;
sbit FSGN=P3^5; //设置P3.5,作为信号输出引脚;
/* 定时计数器0的中断服务子程序 */
void timer0(void) interrupt 1 using 1
{
TH0=-1000/256; // 定时器T0的高四位赋值
TL0=-1000%256;
FREQ=FREQ+1; // 定时器T0的低四位赋值
if (FREQ==FREQ_out) // 周期时间长短的判断{
FREQ=0;
FSGN=!FSGN; // 信号输出端口取反
}
}
/* 外中断0的中断服务子程序 */
void intsvr0(void) interrupt 0 using 1
{
TR0=1; // 开始输出方波
}
/* 外中断0的中断服务子程序 */
void intsvr1(void) interrupt 2 using 1
{
FREQ_out = FREQ_out +5000; // 输出的方波频率减1;
}
main()
{
EA=1; ET0=1;
IT0=1; IT1=1; EX0=1;EX1=1; // 开外中断和定时中断
TMOD=0x01; /* T0方式1计时5秒 */
TH0=-1000/256; // 1ms的初值
TL0=-1000%256;
TR0=0; /* 开中断,启动定时器 */
FREQ=0;
FREQ_out=5000;
FSGN=1;
while(1)
{
for (delay=0;delay<=200;delay++); // 延时程序
//disp( ); // 显示程序
}
}
十五、方波频率的检测和倍频的程序
#include <reg52.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
/*输出给舵机的控制信号:周期18ms,脉宽由原始控制信号输入脉宽和陀螺反馈输入脉宽计算得到的
方波*/
sbit P1_2=P1^2;
//sbit EXF2=T2CON^6; /*T2外中断标志位*/
uchar flag_int0; // 外中断输入的标志位
uint HELMNUM=0; /*存放输出给舵机的控制信号的脉宽时间*/
uchar N; // 定时器溢出次数
uchar time_sgn; // 输入方波的周期变量
uchar T1H,T1L; // 定时器T1的高低位变量
main()
{
/*初始化:打开INT0、INT1和T2,设置T2的优先级为最高*/
// 这是因为T2所记录的中断是输出信号的控制周期,所以其优先有必要设为最高。

EA=1; IT0=1; IT1=1;
EX0=1; EX1=1; ET2=1;
T2CON=0x08; /*设置T2工作方式:允许接收P1.1引脚的下降沿中断,计数器停止*/
TMOD=0x99; /*设置T0、T1工作方式:门控方式1定时*/
TR0=1; TR1=1;
for (;;);
}
// 外中断0的控制T1计数子程序
void int0svr(void) interrupt 0 using 1
{
if (flag_int0==1)
{
flag_int0=0;
T1H=TH1;
T1L=TL1;
time_sgn=N*65536+T1H*256*T1L;
TH1=0;
TL1=0;
}
if (flag_int0==0)
{
flag_int0=1;
TH1=0;
TL1=0;
TR1=1;
}
}
// T1计数子程序
void timer1(void) interrupt 3 using 1
{
TH1=0; // 定时器T1的高四位赋值
TL1=0; // 定时器T1的低四位赋值
N=N+1; // 定时器的溢出次数
}
/* 定时计数器2的中断服务子程序 */
void timer2(void) interrupt 5 using 3
{
// 判断中断类型:EXF2=1时为P1.1引脚下降沿触发的中断;TF2=1为T2定时时间到触发的中断
if (TF2)
{
TF2=0;
TH2=- (time_sgn /4)/256;
TL2=- (time_sgn /4)%256;
T2CON=0x0c;
}
P1_2=!P1_2;
}
十六、电机转速信号的单片机测量程序
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
// 定义8253的寄存器地址
#define COM XBYTE[0x6000] // 定义8253的控制字寄存器地址
#define C0 XBYTE[0x0000] // 定义8253的计数器0寄存器地址
#define C0I XBYTE[0x1000]
sbit P1_7=P1^7;
uint BUF810;
uchar h,l,a,b,c,sendflag,FREQ;
//主函数,初始化定时器和片外寄存器
void main(void)
{
EA=1; PT0=1;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21; //用定时器0产生2s的中断信号,为8253计数提供门控。

TH0=-1000/256;
TL0=-1000%256;
// 向8253R中的控制字寄存器中选择计数器0,并对其幅初值0;
COM=0x30;
C0=0;C0=0;
TR0=1;
sendflag=1;
while(1){}
}
/* 定时计数器0的中断服务子程序 */
void timer0(void) interrupt 1 using 1
{
TH0=-1000/256; // 定时器T0的高四位赋值
TL0=-1000%256;
FREQ=FREQ+1; // 定时器T0的低四位赋值
if (FREQ==1000) // 1秒判断
{
FREQ=0;
P1_7=!P1_7; // 信号输出端口取反
COM=0x00; //计数器0闩锁操作
l=C0; //分别读取高、低8位的数据
h=C0;
BUF810=-(h*256+l);
COM=0x30;
C0=0;C0I=0;
}
}
十七、单片机间的RS232串行通信程序
#include<reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
uchar FREQ; /*定时器计数变量*/
void main(void)
// 以下是设置中断和定时器
EA=1; PT0=1;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
// 定时器0为产生1ms的中断,定时器1为9600bit/s 的波特率发生器TH0=-1000/256;
TL0=-1000%256;
TL1=0xfd;
TH1=0xfd;
SCON=0x50;
PCON=0x80;
// 开定时器
TR1=1;
TR0=1;
TI=1;
while(1){}
}
// 定时器0的中断服务程序,向串口发送姿态数据。

void intsvr1(void) interrupt 1
{
// 重新装入定时器0的初值;
TH0=-10000/256;
TL0=-10000%256;
FREQ=FREQ+1; // 定时器T0的低四位赋值
if (FREQ==1000) // 1秒判断
{
FREQ=0;
printf("*"); // 发送字符
}
}
十八、单片机和PC之间的串行通信程序
#include<reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
uchar FREQ; /*定时器计数变量*/ void main(void)
// 以下是设置中断和定时器
EA=1; PT0=1;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
// 定时器0为产生1ms的中断,定时器1为9600bit/s 的波特率发生器TH0=-1000/256;
TL0=-1000%256;
TL1=0xfd;
TH1=0xfd;
SCON=0x50;
PCON=0x80;
// 开定时器
TR1=1;
TR0=1;
TI=1;
while(1){}
}
// 定时器0的中断服务程序,向串口发送姿态数据。

void intsvr1(void) interrupt 1
{
// 重新装入定时器0的初值;
TH0=-10000/256;
TL0=-10000%256;
FREQ=FREQ+1; // 定时器T0的低四位赋值
if (FREQ==1000) // 1秒判断
{
FREQ=0;
printf("*"); // 发送字符
}
}
十九、单片机的无线数据传输例程
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
//sbit EXF2=T2CON^6;
#define COMI XBYTE[0x3100] // 定义8253R的控制字寄存器地址
#define C0I XBYTE[0x0100] // 定义8253R的计数器0寄存器地址#define C1I XBYTE[0x1100] // 定义8253R的计数器1寄存器地址#define C2I XBYTE[0x2100] // 定义8253R的计数器2寄存器地址
uint i,sendflag;
uint BUF810,BUF811,BUF812;
uint BUF810H,BUF810L;
uint BUF811H,BUF811L;
uint BUF812H,BUF812L;
uchar h,l,a,b,c,yawh,yawl,yaw,pitchh,pitchl,pitch,rollh,rolll,roll;
// 主程序,定义中断源,并对定时器赋初值,以及向8253寄存器写控制字。

void main(void)
{
// 以下是设置中断和定时器
EA=1; PT0=1;
ET0=1;
IT0=1;IT1=1;
EX0=1;EX1=1;ET2=1;
T2CON=0x08;
TMOD=0x21;
// 定时器0为产生18ms的中断,定时器1为9600bit/s 的波特率发生器TH0=0xB9;
TL0=0xB0;
TL1=0xfd;
TH1=0xfd;
SCON=0x50;
PCON=0x80;
// 向8253中写入控制字,门控的方式1计数方式
COMI=0x30;
C0I=0;C0I=0;
COMI=0x70;
C1I=0;C1I=0;
COMI=0xB0;
C2I=0;C2I=0;
// 开定时器
TR1=1;
TR0=1;
TI=1;
sendflag=1;
while(1){}
}
// 中断0的服务子程序,单片机读入8253计数器0中的计数值
void intsvrex0(void) interrupt 0
{
// 中断0到来,单片机读入8253计数器0中的计数值
COMI=0x00;
l=C0I;
h=C0I;
BUF810=-(h*256+l);
COMI=0x30;
C0I=0;C0I=0;
}
// 中断1的服务子程序,单片机读入8253计数器1中的计数值。

void intsvrex1(void) interrupt 2
{
// 中断1到来,单片机读入8253计数器1中的计数值
COMI=0x40;
l=C1I;
h=C1I;
BUF811=-(h*256+l);
COMI=0x70;
C1I=0;C1I=0;
}
// 中断3的服务子程序,单片机读入8253计数器2中的计数值。

void intsvr2(void) interrupt 5
{
// 中断3到来,单片机读入8253计数器2中的计数值
EXF2=0;
COMI=0x80;
l=C2I;
h=C2I;
BUF812=-(h*256+l);
COMI=0xB0;
C2I=0;C2I=0;
}
// 定时器0的中断服务程序,产生18ms的计数中断,读取姿态数据,并向串口发送姿态数据。

void intsvr1(void) interrupt 1
{
// 读取姿态数据
yawh=XBYTE[0x6000];
yawl=XBYTE[0x1000];
yaw=yawh*256+yawl;
pitchh=XBYTE[0x2000];
pitchl=XBYTE[0x3000];
pitch=pitchh*256+pitchl;
rollh=XBYTE[0x4000];
rolll=XBYTE[0x5000];
roll=rollh*256+rolll;
// 重新装入定时器0的初值;
TH0=0xB9;
TL0=0xB0;
switch(sendflag)
{
// 向串口发送8253的计数值;
case 1:
{
printf("$%d,%d,%d,%d*",BUF810,BUF811,BUF812);
sendflag=0;
}break;
// 向串口发送姿态反馈的数值;
case 0:
{
printf("$%d,%d,%d,%d*",yaw,pitch,roll); sendflag=1;
}break;
}
}。

相关文档
最新文档