搜档网
当前位置:搜档网 › C51单片机模块驱动程序参考

C51单片机模块驱动程序参考

C51单片机模块驱动程序参考
C51单片机模块驱动程序参考

一、引用外部头文件:

#include "SST89x5x4.H"

该头文件定义了SST89x5x4系列芯片所用到的关键变量,包括端口、各个寄存器等。

#include

该头文件定义了C51单片机的几个关键操作。

这两个头文件可在“……\Keil\C51\INC”文件夹中找到。

二、按键模块:

void Key_Init(void);

unsigned char GetScanKey(void);

unsigned char GetKey(void);

函数功能描述:键盘初始化,将标志位置1;

void Key_Init(void)

{

bKeyUp_Flag=1;//标志(全局变量)位置1

}

函数功能描述:键盘扫描函数,得到键的行列位置;

unsigned char GetScanKey(void)

{

unsigned char key, i, temp;

unsigned char xdata * ptr;

key=0xff;

for (i=1; i<0x10; i<<=1) //i的低4位为行数位,行依次检测循环4次

{

ptr=0x8fff;

* ptr =i;

temp = * ptr; //取键盘IO口的值

temp &= 0x0f; //屏蔽高四位

if (temp!=0x00) //是否有有效键值

{

key = i<<4; //取行数位的值并将其放入返回值高4位

key|=temp; //列数位的值放入返回值低4位

break;

}

}

return key; //返回行位(高四)和列位(低四)}

函数功能描述:取键值,长按无效;

unsigned char code Key_Value_Table[16]={0xff,0x00,0x01,0xff,0x02,0xff,0xff,0xff, 0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

说明:计算因子,定义在函数外部。此数组在计算键值的中间过程起作用。比如右下方键按下(行列值为0x88),通过查找数组得到行对应的中间值0x03,列对应的中间值0x03。

unsigned char GetKey(void)

{

unsigned char key, temp;

if (!bKeyUp_Flag) //判断标志,是0执行

/*按键程序执行一次后会将bKeyUp_Flag标志位清零,执行此段程序,长按键无效返回无效值,直至按键无效返回无效按键值,置"1"标志位。按键输入恢复有效。屏蔽这部分则长按键有效*/

{

key=GetScanKey();

if (key==0xff) //没有按键,置标志位

bKeyUp_Flag=1;

else //保持按键

return 0xff; //因为0xff大于15,故为无效键值,实现长按键无效}

key=GetScanKey();

if (key==0xff) //没有按键

return key;

else //有按键有效

temp=key; //取键值

Delay_ms(20); //延时20ms 消抖

key=GetScanKey(); //键盘扫描

if(key!=temp) //判断两次键值是否相同,排除干扰信号影响确认有效信号

{

key=0xff;

return key;

}

else //取键值

{

/*这部分主要作用是软件抗干扰*/

temp=Key_Value_Table[key>>4]; //见说明

/*行值有效位(键盘的4个行SEL返回的值含有的有效位"1")有且只有一位键值才有效否则返回无效键值*/

if (temp==0xff)

{

key=0xff;

return key;

}

temp=Key_Value_Table[key&0x0f];

/*列值有效位(键盘的4个列RL返回的值含有的有效位"1")有且只有一位键值才有效否则返回无效键值*/

if (temp==0xff)

{

key=0xff;

return key;

}

key=Key_Value_Table[key>>4]*4+Key_Value_Table[key&0x0f];//行对应的中间值的四倍与列对应的中间值之和即为按键编号0~15

/*行列组合后的值大于15无效*/

if (key>15)

{

key=0xff;

return key;

}

bKeyUp_Flag=0;

return key;

}

}

三、LCD模块:

详细资料请字符点阵说明书.pdf

器件资料请参考“字符点阵说明书.pdf”中有关EDM1602部分;

void LCD_Init(void);

void LCD_Init2(void);

void WriteW(uint a);

void CheckBF(void);

unsigned char Key_ASC2(unsigned char);

void WritD(unsigned char);

函数功能描述:检查忙标志位BF;

void CheckBF(void)

{

uint i;

while(1)

{

ptr=0xAFF1;//RS=0,R/W=1

i=*ptr;

i &= 0x80;

if(i==0)

break;

}

}

函数功能描述:向1602指令寄存器写指令;

void WriteW(uint a)

{

ptr=0xAFF0; //RS=0,R/W=0

*ptr=a;

}

函数功能描述:LCD初始化;

void LCD_Init(void)

{

CheckBF();

WriteW(0x38);

CheckBF();

WriteW(0x01);

CheckBF();

WriteW(0x06);

CheckBF();

WriteW(0x0F);

CheckBF();

WriteW(0x80);

}

函数功能描述:十六进制码转换为ascii码;

说明:unsigned char code ASC2_Value_Table[16]= {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,

0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46

}; 定义在函数外部

unsigned char Key_ASC2(unsigned char key)

{

unsigned char key_asc2;

key_asc2=ASC2_Value_Table[key];

return key_asc2;

}

函数功能描述:换行后的初始化;

void LCD_Init2(void)

{

CheckBF();

WriteW(0x0F);

CheckBF();

WriteW(0xC0);

}

函数功能描述:显示字符;

void WritD(unsigned char key_asc2)

{

CheckBF();

ptr=0xAF02;

*ptr=key_asc2;

}

四、LED模块:

void Led_Init(unsigned char *show);

void display(uchar n);

函数功能描述:给显示数组赋初始值;

void Led_Init(uchar *show)

{

unsigned char i;

for (i=0;i<8;i++)

{

//在此处给显示数组赋值

show++;

}

}

函数功能描述:在LED上显示;

void display(void)

{

unsigned char i=1,j;

unsigned char xdata *ptr;

for (j=0; j<8; j++)//八个数码管全部显示

{

ptr=0x8fff;//段选地址

*ptr=i;

ptr=0x9fff;//位选地址

//在此给*ptr赋值送字形码

Delay_us(50);

*ptr=0x00;

i<<=1;//下一位

}

}

五、I2C模块:

详细资料请参考I2C_bus.pdf文件

void WriteI2C(uchar *Wdata,uchar RomAddress,uchar number);

void ReadI2C(uchar *RamAddress,uchar RomAddress,uchar bytes); void StartI2C(void);

void StopI2C(void);

bit Write8Bit(uchar);

uchar Read8Bit(void);

void Ack(void);

bit ChackAck(void);

void NoAck(void);

函数功能描述:启动I2C总线;

void StartI2C(void)

{

SDA=1;

Delay_ns(1);

SCL=1;

Delay_ns(1);

SDA=0;

Delay_ns(1);

SCL=0;

Delay_ns(1);

}

函数功能描述:应答动作;

void Ack()

{

SDA=0;

Delay_ns(1);

SCL=1;

Delay_ns(1);

SCL=0;

Delay_ns(1);

SDA=1;

Delay_ns(1);

}

函数功能描述:无应答动作;

void NoAck(void)

{

SDA=1;

Delay_ns(1);

SCL=1;

Delay_ns(1);

SCL=0;

Delay_ns(1);

}

函数功能描述:停止i2c总线;

void StopI2C(void)

{

SCL=0;

Delay_ns(1);

SDA=0;

Delay_ns(1);

SCL=1;

Delay_ns(1);

SDA=1;

Delay_ns(1);

}

函数功能描述:向器件发送8位数据;bit Write8Bit(uchar input)

{

uchar temp;

for(temp=8;temp!=0;temp--)

{

SDA=(bit)(input&0x80);

Delay_ns(1);

SCL=1;

Delay_ns(1);

SCL=0;

Delay_ns(1);

input=input<<1;

}

return 1;

Delay_ns(1);

}

函数功能描述:读取8位数据;uchar Read8Bit(void)

{

uchar temp,rbyte=0;

for(temp=8;temp!=0;temp--)

{

SCL=1;

Delay_ns(1);

rbyte=rbyte<<1;

Delay_ns(1);

rbyte=rbyte|((uchar)(SDA));

SCL=0;

Delay_ns(1);

}

return rbyte;

}

函数功能描述:向器件发送多字节数据;

void WriteI2C(uchar *Wdata,uchar RomAddress,uchar number) {

StartI2C();

Write8Bit(0xA2);

ChackAck();

Write8Bit(RomAddress);

ChackAck();

for(;number!=0;number--)

{

Write8Bit(*Wdata);

ChackAck();

Wdata++;

}

StopI2C();

Delay_ns(1);

}

函数功能描述:读取多字节数据;

void ReadI2C(uchar *RamAddress,uchar RomAddress,uchar bytes) {

StartI2C();

Write8Bit(0xA2);

ChackAck();

Write8Bit(RomAddress);

ChackAck();

StartI2C();

Write8Bit(0xA3);

ChackAck();

for(;bytes!=1;bytes--)

{

*RamAddress=Read8Bit();

Ack();

RamAddress++;

}

*RamAddress=Read8Bit();

NoAck();

StopI2C();

Delay_ns(1);

}

六、AD模块:

详细资料请参考tlc1549.pdf文件

void Before_Once_AD(void);//预采集

uint adc_1549(void) ;//读取AD输出的10bit数据

void sort(uint *V olArray1);//排序函数

void ad_FilterAverage(void);//平均值滤波

void ad_FilterMedia(void);//中值滤波

void ad_FilterSlide(void);//滑动滤波

函数功能描述;预先采集;

void Before_Once_AD(void)

{

uchar i;

ADCLK=ADOUT=0;

ADCS=0; //开启控制电路,使能DA TA OUT和I/O CLOCK

for(i=1;i<=10;i++)

{

ADCLK=1;

_nop_();

ADCLK=0;

_nop_();

}

ADCS=1;

Delay_us(25);//两次转换间隔大于21us

}

函数功能描述:转换并读取;

uint adc_1549(void)

{

uint data_out=0;

uchar i;

ADCLK=ADOUT=0;

ADCS = 1;

_nop_();

ADCS=0; //开启控制电路,使能DA TA OUT和I/O CLOCK

for(i=1;i<=10;i++)

{

//给一个脉冲

ADCLK=1;

data_out<<=1;

if(ADOUT) data_out|=0x01;

ADCLK=0;

}

ADCS=1;

Delay_us(21);//两次转换间隔大于21us

return(data_out);

}

七、DA模块:

详细资料请参考tlc5615.pdf文件

函数功能描述:驱动TLC5615开始DA转换;

dat为被转换的数字量

void tlc5615(uint dat)

{

uchar x;

CS=1;

SCLK=0;

delay(100);

DIO=0;

CS=0;// 片选DA芯片

dat=dat<<6; //虽然说输入是16位数据,但只有10为有效,DAC寄存器是10位

for(x=0;x<12;x++)

{//串行发送

DIO=dat&0x8000;

SCLK=1;//模拟时钟信号

dat=dat<<1;

SCLK=0;

}

CS=1;// CS的上升沿和下降沿只有在clk为低的时候才有效

}

八、语音模块:

详细资料请参考isd1760.pdf文件

预定义

#define low_duanma XBYTE[0xB000]

#define read_duanma XBYTE[0x9FFF]

//XBYTE[0x0000]^4=MISO

#define PU 0x01

#define STOP 0x02

#define RESET 0x03

#define CLI_INT 0x04

#define RD_STA TUS 0x05

#define RD_PLAY_PTR 0x06

#define PD 0x07

#define RD_REC_PTR 0x08

#define RD_DEVID 0x09

#define G_ERASE 0x43

#define RD_APC 0x44

#define WR_APC1 0x45

#define WR_APC2 0x65

#define WR_NVCFG 0x46

#define CHK_MEM 0x49

#define SET_PLAY 0x80

#define SET_REC 0x81

#define SET_ERASE 0x82

extern uchar spi_buf;

void I_delay(void);

uchar ISD_SendData(uchar BUF_ISD); //发数据

void ISD_PU(void); //上电

void ISD_Reset(void); //复位

void RdStatus(void); //读状态

void ISD_WR_APC2(uchar voiceValue);

void ISD_WR_NVCFG(void); //永久写入寄存器

void ISD_Init(void); //器件初始化

void play_close(void); //停止播放

void play_open(unsigned int duanma,unsigned int duanma1);//定点播放

函数功能描述: 发送数据;

uchar ISD_SendData(uchar BUF_ISD){

uchar i,dat=BUF_ISD;

spi_buf&=0xfe;

low_duanma=spi_buf;

spi_buf|=0x02;

low_duanma=spi_buf;

for(i=0;i<8;i++){

spi_buf&=0xfd;

low_duanma=spi_buf;

I_delay();

if(dat&0x01){

spi_buf|=0x04;

}

else{

spi_buf&=0xfb;

}

low_duanma=spi_buf;

dat>>=1;

if(read_duanma&0x10){

dat|=0x80;

}

spi_buf|=0x02;

low_duanma=spi_buf;

I_delay();

}

spi_buf&=0xfb;

low_duanma=spi_buf;

return(dat);

}

函数功能描述: 上电;

void ISD_PU(void){

ISD_SendData(PU);

ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_us(2);

}

函数功能描述: 复位;

void ISD_Reset(void){

ISD_SendData(RESET);

ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_us(2);

}

函数功能描述: 读取状态;

uchar SR0_L;

uchar SR0_H;

uchar SR1;

void RdStatus(void){

do{

ISD_SendData(RD_STA TUS);

ISD_SendData(0x00);

ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

SR0_L =ISD_SendData(RD_STATUS);

SR0_H =ISD_SendData(0x00);

SR1 =ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

}while(!(SR1&0x01)); //if(SR0_L^0==1){system Err} }

函数功能描述: 永久写入寄存器;

void ISD_WR_NVCFG(void){

ISD_SendData(WR_NVCFG);

ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_us(2);

}

函数功能描述: 设置APC2;

void ISD_WR_APC2(uchar voiceValue){

ISD_SendData(WR_APC2);

ISD_SendData(voiceValue); //0xa8声音最大,0xaf声音最小

ISD_SendData(0x0c); //D11=1,在SETPLAY模式下,执行到EOM自动结束。或者在连续两个SET_PLAY命令后,执行到第一个EOM自动跳到第二段开始

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_us(2);

}

函数功能描述: 初始化;

void ISD_Init(void){

ISD_Reset();

Delay_us(2);

RdStatus();

ISD_PU();

RdStatus();

ISD_WR_APC2(0xa8);

RdStatus();

ISD_WR_NVCFG(); //永久写入寄存器

RdStatus();

}

函数功能描述: 停止播放;

void play_close(void){

ISD_SendData(STOP);

ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_ms(2); //因为停止动作比较慢,停止后多一个延时,保证语音芯片接收到下一条指令

}

函数功能描述: 定点播放;

参数说明:AddST为段首地址,AddEN为段末地址

void play_open(unsigned int AddST,unsigned int AddEN){

AddST=AddST&0x3fff;

AddEN=AddEN&0x3fff;

if(AddST>0){

RdStatus();

ISD_SendData(SET_PLAY);

ISD_SendData(0x00);

ISD_SendData((uchar)(AddST&0x00ff)); //S7:S0 开始地址ISD_SendData((uchar)((AddST>>8)&0x00ff)); //S10:S8

ISD_SendData((uchar)(AddEN&0x00ff)); //E7:E0 结束地址ISD_SendData((uchar)((AddEN>>8)&0x00ff)); //E10:E8 ISD_SendData(0x00);

spi_buf|=0x01;

low_duanma=spi_buf;

Delay_us(2);

}

}

51单片机流水灯C语言源代码

#include #include #define uint unsigned int #define uchar unsigned char uchar z=50,e=0x00,f=0xff; uchar code table1[]={ 0x80,0xc0,0xe0,0xf0, 0xf8,0xfc,0xfe,0xff}; uchar code table2[]={ 0x7f,0x3f,0x1f,0x0f, 0x07,0x03,0x01,0x00}; uchar code table3[]={ 0x01,0x03,0x07,0x0f, 0x1f,0x3f,0x7f,0xff}; uchar code table4[]={ 0xe7,0xdb,0xbd,0x7e, 0xbd,0xdb,0xe7,0xff}; uchar code table5[]={ 0xe7,0xc3,0x81,0x00, 0x81,0xc3,0xe7,0xff}; uchar code table6[]={ 0x7e,0x3c,0x18,0x00, 0x18,0x3c,0x7e,0xff}; void delay(uchar); void lsd1(); void lsd2(); void lsd3(); void lsd4(); void lsd5(); void lsd6(); void lsd7(); void lsd8(); void lsd9(); void lsd10(); void lsd11(); void lsd12(); main() { while(1) { lsd1(); lsd2(); lsd3(); lsd4();

单片机c语言编程控制流水灯

说了这么多了,相信你也看了很多资料了,手头应该也有必备的工具了吧!(不要忘了上面讲过几个条件的哦)。那个单片机究竟有什么 功能和作用呢?先不要着急!接下来让我们点亮一个LED(搞电子的应该知道LED是什么吧^_^) 我们在单片机最小系统上接个LED,看我们能否点亮它!对了,上面也有好几次提到过单片机最小系统了,所谓单片机最小系统就是在单片机 上接上最少的外围电路元件让单片机工作。一般只须连接晶体、VCC、GND、RST即可,一般情况下,AT89C51的31脚须接高电平。 #include //头文件定义。或用#include其具体的区别在于:后者定义了更多的地址空间。 //在Keil安装文件夹中,找到相应的文件,比较一下便知! sbit P1_0 = P1 ^ 0; //定义管脚 void main (void) { while(1) { P1_0 = 0;//低电平有效,如果把LED反过来接那么就是高电平有效 } } 就那么简单,我们就把接在单片机P1_0上的LED点亮了,当然LED是低电平,才能点亮。因为我们把LED的正通过电阻接至VCC。 P1_0 = 0; 类似与C语言中的赋值语句,即把0 赋给单片机的P1_0引脚,让它输出相应的电平。那么这样就能达到了我们预先的要求了。 while(1)语句只是让单片机工作在死循环状态,即一直输出低电平。如果我们要试着点亮其他的LED,也类似上述语句。这里就不再讲了。 点亮了几个LED后,是不是让我们联想到了繁华的街区上流动的彩灯。我们是不是也可以让几个LED依次按顺序亮呢?答案是肯定的!其 实显示的原理很简单,就是让一个LED灭后,另一个立即亮,依次轮流下去。假设我们有8个LED分别接在P1口的8个引脚上。硬件连接,在 P1_1--P1_7上再接7个LED即可。例程如下: #include sbit P1_0 = P1 ^ 0; sbit P1_1 = P1 ^ 1; sbit P1_2 = P1 ^ 2; sbit P1_3 = P1 ^ 3; sbit P1_4 = P1 ^ 4; sbit P1_5 = P1 ^ 5; sbit P1_6 = P1 ^ 6; sbit P1_7 = P1 ^ 7; void Delay(unsigned char a) { unsigned char i; while( --a != 0) {

最经典的51单片机经典流水灯汇编程序

单片机流水灯汇编程序设计 开发板上的8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。 程序A: ;用最直接的方式实现流水灯 ORG 0000H START:MOV P1,#01111111B ;最下面的LED点亮 LCALL DELAY;延时1秒 MOV P1,#10111111B ;最下面第二个的LED点亮 LCALL DELAY;延时1秒 MOV P1,#11011111B ;最下面第三个的LED点亮(以下省略) LCALL DELAY MOV P1,#11101111B LCALL DELAY MOV P1,#11110111B LCALL DELAY MOV P1,#11111011B LCALL DELAY MOV P1,#11111101B LCALL DELAY MOV P1,#11111110B LCALL DELAY MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒 AJMP START ;反复循环 ;延时子程序,12M晶振延时约250毫秒 DELAY: MOV R4,#2 L3: MOV R2 ,#250 L1: MOV R3 ,#250 L2: DJNZ R3 ,L2 DJNZ R2 ,L1 DJNZ R4 ,L3 RET END 程序B: ;用移位方式实现流水灯

ajmp main ;跳转到主程序 org 0030h ;主程序起始地址 main: mov a,#0feh ;给A赋值成11111110 loop: mov p1,a ;将A送到P1口,发光二极管低电平点亮 lcall delay ;调用延时子程序 rl a ;累加器A循环左移一位 ajmp loop ;重新送P1显示 delay: mov r3,#20 ;最外层循环二十次 d1: mov r4,#80 ;次外层循环八十次 d2: mov r5,#250 ;最内层循环250次 djnz r5,$ ;总共延时2us*250*80*20=0.8S djnz r4,d2 djnz r3,d1 ret end 51单片机经典流水灯程序,在51单片机的P2口接上8个发光二极管,产生流水灯的移动效果。 ORG 0 ;程序从0地址开始 START: MOV A,#0FEH ;让ACC的内容为11111110 LOOP: MOV P2,A ;让P2口输出ACC的内容 RR A ;让ACC的内容左移 CALL DELAY ;调用延时子程序 LJMP LOOP ;跳到LOOP处执行 ;0.1秒延时子程序(12MHz晶振)=================== DELAY: MOV R7,#200 ;R7寄存器加载200次数 D1: MOV R6,#250 ;R6寄存器加载250次数 DJNZ R6,$ ;本行执行R6次 DJNZ R7,D1 ;D1循环执行R7次 RET ;返回主程序

用单片机控制的LED流水灯设计(电路、程序全部给出)

1.引言 当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。学习单片机的最有效方法就是理论与实践并重,本文笔者用AT89C51单片机自制了一款简易的流水灯,重点介绍了其软件编程方法,以期给单片机初学者以启发,更快地成为单片机领域的优秀人才。 2.硬件组成 按照单片机系统扩展与系统配置状况,单片机应用系统可分为最小系统、最小功耗系统及典型系统等。AT89C51单片机是美国ATM EL公司生产的低电压、高性能CMOS 8位单片机,具有丰富的内部资源:4kB闪存、128BRAM、32根I/O口线、2个16位定时/计数器、5个向量两级中断结构、2个全双工的串行口,具有4.25~5.50V的电压工作范围和0~24MHz 工作频率,使用AT89C51单片机时无须外扩存储器。因此,本流水灯实际上就是一个带有八个发光二极管的单片机最小应用系统,即为由发光二极管、晶振、复位、电源等电路和必要的软件组成的单个单片机。其具体硬件组成如图1所示。 图1 流水灯硬件原理图 从原理图中可以看出,如果要让接在P1.0口的LED1亮起来,那么只要把P1.0口的电平变为低电平就可以了;相反,如果要接在P1.0口的LED1熄灭,就要把P1.0口的电平变为高电平;同理,接在P1.1~P1.7口的其他7个LED的点亮和熄灭的方法同LED1。因此,要

最新五种编程方式实现流水灯的单片机c程序讲课教案

五种编程方式实现流水灯的单片机C程序 //功能:采用顺序结构实现的流水灯控制程序 /*此方式中采用的是字操作(也称为总线操作)*/ #include void delay(unsigned char i); //延时函数声明 void main() //主函数 { while(1) { P1 = 0xfe; //点亮第1个发光二极管,0.000389s delay(200); //延时 P1 = 0xfd; //点亮第2个发光二极管,0.155403s,0.1558 delay(200); //延时 P1 = 0xfb; //点亮第3个发光二极管 delay(200); //延时 P1 = 0xf7; //点亮第4个发光二极管 delay(200); //延时 P1 = 0xef; //点亮第5个发光二极管 delay(200); //延时 P1 = 0xdf; //点亮第6个发光二极管 delay(200); //延时 P1 = 0xbf; //点亮第7个发光二极管 delay(200); //延时 P1 = 0x7f; //点亮第8个发光二极管 delay(200); //延时 } } //函数名:delay //函数功能:实现软件延时 //形式参数:unsigned char i; // i控制空循环的外循环次数,共循环i*255次 //返回值:无 void delay(unsigned char i) //延时函数,无符号字符型变量i为形式参数{ unsigned char j, k; //定义无符号字符型变量j和k for(k = 0; k < i; k++) //双重for循环语句实现软件延时 for(j = 0; j < 255; j++); } //功能:采用循环结构实现的流水灯控制程序 //此方式中采用的移位,按位取反等操作是位操作 #include //包含头文件REG51.H void delay(unsigned char i); //延时函数声明 void main() //主函数

单片机流水灯C语言源程序

单片机流水灯C语言源程序 标题:51单片机流水灯C语言源程序2008-12-06 08:43:05 ************************************************************** 文件名称:flash_led.c 文件说明:流水灯C程序 编写日期:2006年10月5日 程序说明:MCU采用AT89S51,外接12M晶振,P1口输出 *************************************************************/ #include //51系列单片机定义文件 #define uchar unsigned char //定义无符号字符 #define uint unsigned int //定义无符号整数 void delay(uint); //声明延时函数 void main(void) { uint i; uchar temp; while(1) { temp=0x01; for(i=0;i<8;i++) //8个流水灯逐个闪动 { P1=~temp; delay(100); //调用延时函数 temp<<=1; } temp=0x80; for(i=0;i<8;i++) //8个流水灯反向逐个闪动 { P1=~temp; delay(100); //调用延时函数 temp>>=1; } temp=0xFE; for(i=0;i<8;i++) //8个流水灯依次全部点亮 { P1=temp; delay(100); //调用延时函数 temp<<=1; }

简述51系列单片机的中断响应地条件

简述51系列单片机中断响应的条件。●有中断源发出中断请求;●中断总允许位EA=1,即CPU开中断;●申请中断的中断源的中断允许位为1,即中断没有屏蔽;●无同级或更高级中断正在被服务;●当前的指令周期已经结束;●若现在指令为RETI或者是访问IE 或IP指令,则该指令以及紧接着的另一条指令已执行完 简述定时/计数器4种工作模式的特点。模式1:是16位的定时器/计数器; 模式2:把TL0(或TL1)配置成一个可以自动重装载的8位定时器/计数器;模式3:对T0和T1大不相同。若将T0设置为模式3,则TL0和TH0被分为两个相互独立的8位计数器。定时器T1无工作模式3状态。模式0:与模式1几乎完全相同,唯一的差别是模式0中,寄存器TL0用5位,TH0用8位。 单片机原理及应用试卷3 一、填空题 1、MCS—51单片机的运算电路包括了算术逻辑运算单元ALU 累加器A B 寄存器以及状态字寄存器PSW和暂存寄存器等部件。 2、MCS—5l单片机的最大程序寻址空间是 64K ,该空间的地址范围为: 0000H 至FFFFH 系统上电及复位的程序人口地址为 0000H 。 3、MCS-51单片机的一个机器周期包含了 6 个状态周期,每个状态周期又可划分为 2 拍节,一个机器周期实际又包含了 12 个振荡器周期。 4、单片机与普通计算机的不同之处在于其将 CPU、存储器、I/O口三部分集成于一块芯片上。 5、8031单片机复位后,R4所对应的存储单元的地址为 04H ,因上电时PSW= 00H 。这时当前的工作寄存器区是 0 组工作寄存器区。 6、片内RAM低128个单元划分为工作寄存器区、位寻址区、数据缓冲区 3个主要部分。 7、指令格式是由操作码、操作数、和所组成,也可能仅由操作码组成。 8、8031单片机响应中断后,产生长调用指令LCALL,执行该指令的过程包括:首先把 pc 的内容压入堆栈,以进行断点保护,然后把长调用指令的16位地址送 pc ,使程序执行转向程序存储器中的中断地址区。 9、在MCS-51中,PC和DPTR都用于提供地址,但PC是为访问程序存储器提供地址,而DPTR是为访问数据存储器提供地址。 10、假定,SP=60H,A=30H,B=70H,执行下列指令: PUSH A PUSH B 后,SP的内容为 62h ,61H单元的内容为 30h ,62H单元的内容为 70h 。 二、选择题 1.当MCS-51单片机接有外部存储器,P2口可作为( ) D.输出高8位地址2.MCS—5l单片机的堆栈区是设置在( )中。 C.片内RAM区

基于51单片机的流水灯设计说明

基于51单片机的流水灯设计 一.基本功能 利用AT89c51作为主控器组成一个LED流水灯系统,实现8个LED 灯的左、右循环显示。 二.硬件设计 图1.总设计图

1.单片机最小系统 1.1选用AT89C51的引脚功能 图2. AT89C51 XTAL1:单芯片系统时钟的反向放大器输入端。 XTAL2:系统时钟的反向放大器输出端,一般在设计上只要在XTAL1和XTAL2上接上一只石英震荡晶体系统就可以工作了,此外可以在两引脚与地之间加入20PF的小电容,可以使系统更稳定,避免噪音干扰而死机。 RESET:重置引脚,高电平动作,当要对晶体重置时,只要对此引脚电平提升至高电平并保持两个及其周期以上的时间便能完成系统重置的各项动作,使得部特殊功能寄存器容均被设成已知状态。 P3:端口3是具有部提升电路的双向I/O端口,通过控制各个端口的高低电平了实现LED流水灯的控制。

1.2复位电路 如图所示,当按下按键时,就能完成整个系统的复位,使得程序从新运行。 图3.复位电路 1.3时钟电路 时钟电路用于产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进行工作。 在AT89C51芯片部有一个高增益反相放大器,其输入端为芯片引脚X1,输出端为引脚X2,在芯片的外部跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡器。此电路采用12MHz的石英晶体。

图4.时钟电路 2.流水灯部分 图5.流水灯电路 三.软件设计 3.1编程语言及编程软件的选择 本设计选择C语言作为编程语言。C语言虽然执行效率没有汇编语言

51单片机中断系统程序实例

51单片机中断系统程序实例(STC89C52RC) 51单片机有了中断,在程序设计中就可以做到,在做某件事的过程中,停下来先去响应中断,做别的事情,做好别的事情再继续原来的事情。中断优先级是可以给要做的事情排序。 单片机的学习不难,只要掌握学习方法,学起来并不难。什么是好的学习方法呢,一定要掌握二个要点: 1. 要知道寄存器的英文全拼,比如IE = interrupt中断 不知道全拼,要去猜,去查。这样就可以理解为什么是这个名称,理解了以后就不用记忆了。 2. 每个知识点要有形像的出处 比如看到TF0,脑子里马上要形像地定位到TCON寄存器的某位 看到ET0, 马上要形像地定位到IE寄存器的第2位 https://www.sodocs.net/doc/e415510147.html,/tuenhai/独家揭秘:形像是记忆的最大技巧。当人眼看到某个图时,是把视觉信号转化成电信号,再转化成人能理解的形像。当我们回忆形像时,就是在重新检索原先那个视觉信号,并放大。在学习过程中,不断练习检索、放大信号,我们的学习能力就会越来越强。 写程序代码时,也要把尽量把每行代码形像化。 51单片机内中断源 8051有五个中断源,有两个优先级。与中断系统有关的特殊功能寄存器有IE(中断允许寄存器)、IP(中断优先级控制寄存器)、中断源控制寄存器(如TCON、SCON的有关位)。51单片机的中断系统结构如下图(注意,IF0应为TF0):

8052有6个中断源,它比8051多一个定时器/计数器T2中断源。 8051五个中断源分别是: (1)51单片机外部中断源 8051有两个外部中断源,分别是INT0和INT1,分别从P3.2和P3.3两个引脚引入中断请求信号,两个中断源的中断触发允许由TCON的低4位控制,TCON的高4位控制运行和溢出标志。 INT0也就是Interrupt 0。在这里应该看一下你的51单片机开发板的电路原理图。离开形像的记忆是没有意义的。读到上面这句,你应该回忆起原理图上的连接。任何记忆都转化为形像,这是学习的根本原理,我们通过学习单片机要学会这种学习方法,会让你一辈子受益无穷。 TCON的结构如下图: (a)定时器T0的运行控制位TR0

51单片机 流水灯 ~ 花样灯 程序

单片机为89c52 晶振为11.0592, /***此程序为流水灯*** / #include #include #define uchar unsigned char //宏定义 #define uint unsigned int uchar led; void delay(uint z) //延时子函数体 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void main() { led=0xfe; //赋初值 while(1) { P1=led; //点亮第一个小灯 delay(100); //延时100毫秒 led=_crol_(led,1); 将led的变量左移给下一位} }

/*8个发光管间隔200ms由上至下,返回再由上至下,一个个往下亮,后全亮由下至上,返回再由下至上,一个个往下亮,后全亮 再重复2次, 然后全部熄灭再以500ms间隔 全部闪烁3次。重复此过程*/ #include #include #define uchar unsigned char #define uint unsigned int uchar led; uint i,j; void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void main() { while(1) { for(j=0;j<2;j++) { led=0xfe; //赋初值 for(i=0;i<8;i++) { P1=led; //点亮第一个小灯 delay(200); //延时200毫秒 led=_crol_(led,1); //将led变量循环左移给下一位 } led=0xfe; //赋初值 for(i=0;i<8;i++) { P1=led; //点亮第一个小灯 delay(200); //延时200毫秒 led<<=1; //左移给下一位 } led=0x7f; //赋初值

单片机中断系统

ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写。ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是在掉电之后就丢失数据,典型的RAM就是计算机的内存。 FLASH存储器又称闪存,它结合了ROM和RAM的长处,不仅具备电子可擦除可编程(EEPROM)的性能,还不会断电丢失数据同时可以快速读取数据(NVRAM的优势),U盘和MP3里用的就是这种存储器。在过去的20年里,嵌入式系统一直使用ROM(EPROM)作为它们的存储设备,然而近年来Flash全面代替了ROM(EPROM)在嵌入式系统中的地位,用作存储Bootloader以及操作系统或者程序代码或者直接当硬盘使用(U盘)。

键盘中断实验 一、实验目的 键盘/按键是操作人员向单片机系统输入指令的基本工具,在前面的实验中我们已经多 次使用了按键。键盘/按键在编程时可以用查询或中断的方法来检测按键是否按下。其中,中断方式可以优化单片机的运行,并能快速做出反应,且可靠性较高。本实验要求大家用中断方式编写按键检测程序,该程序可以用于各种需要中断键盘/按键的场合。实验中需要掌握以下知识要点: 1.复习中断程序的编写格式及特殊功能寄存器的使用。 2.中断程序的编写格式。 3.中断程序的调试方法。 4.多个按键中,判断具体按下键的分析方法。 二、实验预备知识 1.中断程序的编写方法 普通的MSC-51 单片机有5 个中断源,每个中断有自己的中断程序入口,在汇编语言 中具有中断的程序编写格式如下: ORG 0000H SJMP MAIN ORG 0003H ;INT0 中断入口 LJMP INT0IN …… …… ORG 0030H ;主程序起始地址 MAIN:MOV IE ,#01H ;主程序部分 …… …… INT0IN:……;中断服务程序主体部分 …… RETI ;中断返回指令 END 中断程序的入口就是中断服务程序的首地址,MSC-51 系列单片机的各中断入口地址 是固定的。INT0 的中断入口是0003H,其中断服务程序就必须从0003H 单元开始,在实际编程中,为了不占用其它中断的入口,一般在入口处放一条跳转指令,而把中断服务程序主体放到其它地方。上面的程序就是采用的这种方法。 单片机在运行过程中,只有发生中断后才能运行中断服务程序,而不能直接运行到中 断程序中。单片机复位后,从0000H 单元开始运行程序,为了避免单片机直接运行到中断程序中,所以采用了SJMP MIAN 指令,跳过中断入口,进入主程序中。

51单片机经典流水灯汇编程序

单片机流水灯汇编程序设计 流水灯汇编程序 8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。 ;用最直接的方式实现流水灯 ORG 0000H START:MOV P1,#01111111B ;最下面的LED点亮 LCALL DELAY ;延时1秒 MOV P1,#10111111B ;最下面第二个的LED点亮 LCALL DELAY ;延时1秒 MOV P1,#11011111B ;最下面第三个的LED点亮(以下省略) LCALL DELAY MOV P1,#11101111B LCALL DELAY MOV P1,#11110111B LCALL DELAY MOV P1,#11111011B LCALL DELAY MOV P1,#11111101B LCALL DELAY MOV P1,#11111110B LCALL DELAY MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒 AJMP START ;反复循环 ;延时子程序,12M晶振延时约250毫秒 DELAY: ;大约值:2us*256*256*2=260ms,也可以认为为250ms PUSH PSW ;现场保护指令(有时可以不加) MOV R4,#2 L3: MOV R2 ,#00H L1: MOV R3 ,#00H L2: DJNZ R3 ,L2 ;最内层循环:(256次)2个周期指令(R3减一,如果比1大,则转向L2) DJNZ R2 ,L1 ; 中层循环:256次 DJNZ R4 ,L3 ;外层循环:2次 POP PSW RET END

51单片机汇编程序集(二) 2008年12月12日星期五 10:27 辛普生积分程序 内部RAM数据排序程序(升序) 外部RAM数据排序程序(升序) 外部RAM浮点数排序程序(升序) BCD小数转换为二进制小数(2位) BCD小数转换为二进制小数(N位) BCD整数转换为二进制整数(1位) BCD整数转换为二进制整数(2位) BCD整数转换为二进制整数(3位) BCD整数转换为二进制整数(N位) 二进制小数(2位)转换为十进制小数(分离BCD码) 二进制小数(M位)转换为十进制小数(分离BCD码) 二进制整数(2位)转换为十进制整数(分离BCD码) 二进制整数(2位)转换为十进制整数(组合BCD码) 二进制整数(3位)转换为十进制整数(分离BCD码) 二进制整数(3位)转换为十进制整数(组合BCD码) 二进制整数(M位)转换为十进制整数(组合BCD码) 三字节无符号除法程序(R2R3R4/R7)=(R2)R3R4 余数R7 ;二进制整数(2位)转换为十进制整数(分离BCD码) ;入口: R3,R4 ;占用资源: ACC,R2,NDIV31 ;堆栈需求: 5字节 ;出口: R0,NCNT IBTD21 : MOV NCNT,#00H MOV R2,#00H IBD211 : MOV R7,#0AH LCALL NDIV31 MOV A,R7 MOV @R0,A INC R0 INC NCNT MOV A,R3 ORL A,R4 JNZ IBD211 MOV A,R0 CLR C SUBB A,NCNT MOV R0,A RET ;二进制整数(2位)转换为十进制整数(组合BCD码) ;入口: R3,R4 ;占用资源: ACC,B,R7 ;堆栈需求: 3字节 ;出口: R0

51单片机中断详解

一.中断的概念 1.中断发生 CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理 2.中断响应和中断服务 CPU暂时中断当前的工作,转去处理事件B 3.中断返回 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A 这一过程称为中断 二.中断过程示意图 三.MCS51中断系统的结构

MCS51的中断系统有5个中断源(8052有6个),2个优先级,可实现二级中断嵌套 四.中断寄存器 单片机有10个寄存器主要与中断程序的书写控制有关 1.中断允许控制寄存器IE 2.定时器控制寄存器TCON 3.串口控制寄存器SCON 4.中断优先控制寄存器IP 5.定时器工作方式控制寄存器TMOD 6.定时器初值赋予寄存器(TH0/TH1,TL0/TL1) 五.部分寄存器详解

1.中断允许控制寄存器(IE) EX0:外部中断0允许位; ET0:定时/计数器T0中断允许位; EX1:外部中断1允许位; ET1:定时/计数器T1中断允许位; ES :串行口中断允许位; EA :CPU中断允许(总允许)位。 2.定时器/计数器控制寄存器控制寄存器(TCON) IT0:外部中断0触发方式控制位 当IT0=0时,为电平触发方式(低电平有效) 当IT0=1时,为边沿触发方式(下降沿有效) IE0:外部中断0中断请求标志位 IT1:外部中断1触发方式控制位 IE1:外部中断1中断请求标志位

TF0:定时/计数器T0溢出中断请求标志位 TF1:定时/计数器T1溢出中断请求标志位 3.串行口控制寄存器(SCON) RI:串行口接收中断标志位。当允许串行口接收数据时,每接收完一个串行帧,由硬件置位RI。注意,RI必须由软件清除。 TI:串行口发送中断标志位。当CPU将一个发送数据写入串行口发送缓冲器时,就启动了发送过程。每发送完一个串行帧,由硬件置位TI。CPU响应中断时,不能自动清除TI,TI必须由软件清除。 4.中断优先级控制寄存器(IP) PX0:外部中断0优先级设定位 PT0:定时/计数器T0优先级设定位 PX1:外部中断0优先级设定位 PT1:定时/计数器T1优先级设定位

51单片机外部中断实验

实验6 外部中断实验 (仿真部分) 一、实验目的 1. 学习外部中断技术的基本使用方法。 2. 学习中断处理程序的编程方法。 二、实验内容 在INT0和INT1上分别接了两个可回复式按钮,其中INT0上的按钮每按下一次则计数加一,其中INT1上的按钮每按下一次则计数减一。P1.0~ P1.3接LED灯,以显示计数信号。 三、实验说明 编写中断处理程序需要注意的问题是: 1.保护进入中断时的状态,并在退出中断之前恢复进入时的状态。 2.必须在中断处理程序中设定是否允许中断重入,即设置EX0位。 3.INT0和INT1分别接单次脉冲发生器。P1.0~ P1.3接LED灯,以查看计数信号. 四、硬件设计 利用以下元件:AT89C51、BOTTON、CAP、CAP-POL、CRYSTAL、RES、NOT、LED-Yellow。设计出如下的硬件电路。晶振频率为12MHz。 五、参考程序框图 设置P1.0~ 3初始状态

主程序框图 INT0中断处理程序框图 实验6 外部中断实验 (实验箱部分) 1.实验目的 认识中断的基本概念 学会外部中断的基本用法 学会asm和C51的中断编程方法 2.实验原理 图按键中断 【硬件接法】 控制LED,低电平点亮 INT1接按键,按下时产生低电平 【运行效果】 程序工作于中断方式,按下按键K2后,LED点亮,秒后自动熄灭。

8051单片机有/INT0和/INT1两条外部中断请求输入线,用于输入两个外部中断源的中断请求信号,并允许外部中断源以低电平或下降沿触发方式来输入中断请求信号。/INT0和/INT1中断的入口地址分别是0003H和0013H。 TCON寄存器(SFR地址:88H)中的IT0和IT1位分别决定/INT0和/INT1的触发方式,置位时为下降沿触发,清零时为低电平触发。实际应用时,如果外部的中断请求信号在产生后能够在较短时间内自动撤销,则可以选择低电平触发。在中断服务程序里要等待其变高后才能返回主程序,否则会再次触发中断,产生不必要的麻烦。 如果外部的中断请求信号产生后可能长时间后才能撤销,则为了避免在中断服务程序里长时间无谓等待,可以选择下降沿触发。下降沿触发是“一次性”的,每次中断只会有1个下降沿,因此中断处理程序执行完后可以立即返回主程序,而不必等待中断请求信号恢复为高电平,这是一个重要的技巧。 3. 实验步骤 参考实验例程,自己动手建立Keil C51工程。注意选择CPU类型。Philips半导体的P89V51RB2。 编辑源程序,编译生成HEX文件。 ISP下载开关扳到“00”,用Flash Magic软件下载程序HEX文件到MCU BANK1,运行。 运行Flash Magic软件。各步骤操作如下: Step 1: COM Port:选择实际使用的串行口,通常为COM1; Baud Rate:波特率不可设置得过高,推荐用9600; Device:请选择正确的型号89V51RB2; Interface:选择None(ISP)。 Step 2:请勾中“Erase blocks used by Hex File”。 Step 3:装入你的程序文件,注意必须为HEX格式。 Step 4: 请勾中“Verify after programming”(编程后校验); 对其它几项如果不了解,请不要勾中。 Step 5: 请先给电路板上电,同时按住复位键不松手,然后点击Flash Magic软件的“Start”按

51单片机中断程序大全

//实例42:用定时器T0查询方式P2口8位控制LED闪烁#include<> // 包含51单片机寄存器定义的头文件 void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 TR0=1; //启动定时器T0 @ TF0=0; P2=0xff; while(1)//无限循环等待查询 { while(TF0==0) ; TF0=0; P2=~P2; TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 | //实例43:用定时器T1查询方式控制单片机发出1KHz音频#include<> // 包含51单片机寄存器定义的头文件 sbit sound=P3^7; //将sound位定义为引脚 void main(void) {// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x10; //使用定时器T1的模式1 TH1=(65536-921)/256; //定时器T1的高8位赋初值 TL1=(65536-921)%256; //定时器T1的高8位赋初值 TR1=1; //启动定时器T1 — TF1=0; while(1)//无限循环等待查询 { while(TF1==0); TF1=0; sound=~sound; //将引脚输出电平取反 TH1=(65536-921)/256; //定时器T0的高8位赋初值

51单片机流水灯 程序

1.第一个发光管以间隔200ms闪烁。 2. 8个发光管由上至下间隔1s流动,其中每个管亮500ms,灭500ms。 3. 8个发光管来回流动,第个管亮100ms。 4. 用8个发光管演示出8位二进制数累加过程。 5. 8个发光管间隔200ms由上至下,再由下至上,再重复一次,然后全部熄灭再以300ms间隔全部闪烁5次。重复此过程。 6. 间隔300ms第一次一个管亮流动一次,第二次两个管亮流动,依次到8个管亮,然后重复整个过程。 7. 间隔300ms先奇数亮再偶数亮,循环三次;一个灯上下循环三次;两个分别从两边往中间流动三次;再从中间往两边流动三次;8个全部闪烁3次;关闭发光管,程序停止。 1 #include #define uint unsigned int sbit led1=P1^0; void delay(); void main() { while(1) { led1=0; delay(); led1=1; delay(); } } void delay() { uint x,y; for(x=200;x>0;x--) for(y=100;y>0;y--); } 2

#include #include #define uint unsigned int #define uchar unsigned char sbit p1=P1^0; uchar a; void delay(); void main() { a=0xfe; P1=a; while(1) { a=_crol_(a,1); delay(); P1=a; delay(); } } void delay() { uint b; for(b=55000;b>0;b--); } 3 #include #include #define uint unsigned int #define uchar unsigned char void delay() { uint x,y; for(x=100;x>0;x--) for(y=110;y>0;y--); } void main() { uchar a,i; while(1)

单片机的中断系统

项目五 中断系统的应用 任务一 认识MCS-51单片机的中断系统 中断系统是单片机中非常重要的组成部分,它是为了使单片机能够对外部或内部随机发生的事件实时处理而设置的。中断功能的存在,在很大程度上提高了单片机实时处理能力,它也是单片机最重要的功能之一,是我们学习单片机必须掌握的重要内容。我们不但要了解单片机中断系统的资源配置情况,还要掌握通过相关的特殊功能寄存器打开和关闭中断源、设定中断优先级,掌握中断服务程序的编写方法。 一、中断的概念 为了弄懂中断的概念,下面我们先来了解一下单片机与外设之间数据的输入/输出方式。 1.单片机的输入/输出方式 CPU 与外设之间的信息交换称为输入/输出。在一个单片机系统中,输入/输出是必不可少的,CPU 与外设之间以何种方式进行信息交换,将直接影响到信息交换的可靠性和CPU 的效率。 例如:在一个与打印机相连的微机系统中,CPU 将需要打印的数据输出给打印机,打印机接收到数据后便可进行打印。CPU 是如何将要打印的数据输出给打印机的呢?如果打印机总是处于准备好的状态或者CPU 总是知道打印机的状态,那么CPU 无需查询打印机状态可直接进行输出,这种方式称为无条件传送方式。但外设的执行速度一般是很慢的,像打印机这样的外设不可能总处于准备好的状态,因此CPU 在输出数据前需要先查询打印机是否空闲,若空闲则进行输出操作,若打印机处于忙状态则继续查询,直到打印机处于空闲状态再进行输出。这种方式称为查询传送方式。与无条件传送方式相比,虽然查询传送方式能有效地与慢速外设进行信息交换,提高了信息交换的可靠性,解决了外设与CPU 速度不匹配的矛盾,但由于在外设未准备好的情况下,CPU 需要不断的查询外设状态,不能进行其他操作,这样就浪费了CPU 的资源,使CPU 的利用率大大降低。为了提高CPU 的工作效率,可将外设的“忙/闲”状态信息作为请求触发信号,这样,CPU 就可以做自己的工作,当打印机处理完上一批数据后处于空闲状态时,向CPU 提出中断请求信号,CPU 接到中断请求时,就暂停当前正在进行的工作转去为打印机输出数据,输出一批数据后又返回到刚才中断的地方继续进行原来的工作,这种方式称为中断传送方式。 综上所述,CPU 与外设之间信息交换有三种方式,其执行过程如图5-1所示。 图5-1 输入/输出方式示意图 (a)无条件传送方式 (b)查询传送方式 (c)中断传送方式 (c)中断传送方式

AT89C51单片机中断系统

第 5 章 AT89C51单片机中断系统 难点 ?中断优先级控制原则 ?中断响应过程 要求 掌握: ?中断控制的专用寄存器 ?中断响应过程 了解: ?中断的概念 ?单片机的单步执行方式 5.1 中断的基本概念 5.2 MCS-51 单片机的中断系统 5.3 中断系统的应用举例 5.1 中断的基本概念 在CPU 与外设交换信息时,存在着一个快速的CPU 与慢速的外设之间的矛盾。为解决这个问题,发展了中断的概念。 单片机在某一时刻只能处理一个任务,当多个任务同时要求单片机处理时,这一要求应该怎么实现呢?通过中断可以实现多个任务的资源共享。 中断现象在现实生活中也会经常遇到,例如,你在看书——手机响了——你在书上作个记号——你接通电话和对方聊天——谈话结束——从书上的记号处继续看书。这就是一个中断过程。通过中断,你一个人在一特定的时刻,同时完成了看书和打电话两件事情。用计算机语言来描述,所谓的中断就是,当CPU 正在处理某项事务的时候,如果外界或者内部发生了紧急事件,要求CPU 暂停正在处理工作而去处理这个紧急事件,待处理完后,再回到原来中断的地方,继续执行原来被中断的程序,这个过程称作中断。 从中断的定义我们可以看到中断应具备中断源、中断响应、中断返回这样三个要素。中断源发出中断请求,单片机对中断请求进行响应,当中断响应完成后应进行中断返回,返回被中断的地方继续执行原来被中断的程序。 5.2 MCS-51单片机的中断系统 5.2.1 MCS-51单片机的中断源 MCS-51单片机的中断源共有两类,它们分别是:外部中断和内部中断 1. 外部中断源 ●外部中断0( ):来自P3.2引脚,采集到低电平或者下降沿时,产生中断请求。 ●外部中断1( ):来自P3.3引脚,采集到低电平或者下降沿时,产生中断请求。 2. 内部中断源 ●定时器∕计数器0(T ):定时功能时,计数脉冲来自片内;计数功能时,计数脉冲来自片外P3.4引 脚。发生溢出时,产生中断请求。 ●定时器∕计数器1(T ):定时功能时,计数脉冲来自片内;计数功能时,计数脉冲来自片外P3.5引 1 脚。发生溢出时,产生中断请求。 ●串行口:为完成串行数据传送而设置。单片机完成接受或发送一组数据时,产生中断请求。 5.2.2 中断控制的专用寄存器 MCS-51单片机为用户提供了四个专用寄存器,来控制单片机的中断系统。

51单片机外部中断详解

一.外部中断相关寄存器 1.定时器/计数器控制寄存器控制寄存器(TCON) IT0:外部中断0触发方式控制位 当IT0=0时,为电平触发方式(低电平有效) 当IT0=1时,为边沿触发方式(下降沿有效) IT1:外部中断1触发方式控制位 当IT1=0时,为电平触发方式(低电平有效) 当IT1=1时,为边沿触发方式(下降沿有效) 2.中断允许控制寄存器(IE) EX0:外部中断0允许位; EX1:外部中断1允许位; EA :CPU中断允许(总允许)位。 二.外部中断的处理过程 1、设置中断触发方式,即IT0=1或0,IT1=1或0

2、开对应的外部中断,即EX0=1或EX1=1; 3、开总中断,即EA=1; 4、等待外部设备产生中断请求,即通过,口连接外部设备产生中断 5、中断响应,执行中断服务函数 三.程序编写 要求:通过两位按键连接外部中断0和1,设定外部中断0为下降沿触发方式,外部中断1为低电平触发方式,按键产生中断使数字加减,用一位共阳极数码管来显示数值。 目的:感受外部中断对程序的影响,体会低电平触发和下降沿触发的区别。 #include<>#define uint unsigned int #define uchar unsigned char uchar code dat[]={0xc0, 0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uint num; void main() { ! EA=1; //开总中断 IT0=1; //下降沿触发 IT1=0; //低电平触发 EX0=1; //外部中断0允许 EX1=1; //外部中断1允许 while(1) { P0=dat[num%10]; } } { void plus() interrupt 0//外部中断0

相关主题