STC8A8K64S4A12单片机8路抢答器程序程序

宏晶STC8系列单片机C51范例程序(摘自STC8官方数据手册,见STC官网:www.STCMCU.com)
宏晶STC8系列单片机C51范例程序
(注:摘自,同时STC公司亦更新在STC-ISP V6.85Q的【范例程序】中。如果要在程序中使用此代码或在文章中应用此代码,请注明使用了资料及程序。)
(更多STC8 C51例程及汇编A51例程请参看原并自行校验)
/* 串口1 切换 */
#include "reg51.h"
sfr P_SW1 = 0xa2;
void main()
&P_SW1 = 0x00;
//RXD/P3.0, TXD/P3.1
&//P_SW1 = 0x40;
//RXD_2/P3.6, TXD_2/P3.7
&//P_SW1 = 0x80;
//RXD_3/P1.6, TXD_3/P1.7
&//P_SW1 = 0xc0;
//RXD_4/P4.3, TXD_4/P4.4
&while(1);
/* 串口2 切换 */
#include "reg51.h"
sfr P_SW2 = 0
void main()
&P_SW2 = 0x00;
//RXD2/P1.0, TXD2/P1.1
&&//P_SW2 = 0x01;
//RXD2_2/P3.6, TXD2_2/P3.7
&while(1);
/* 串口3 切换 */
#include "reg51.h"
sfr P_SW2 = 0
void main()
&P_SW2 = 0x00;
//RXD3/P0.0, TXD3/P0.1
&&//P_SW2 = 0x02;
// RXD3_2/P5.0, TXD3_2/P5.1
&while(1);
/* 串口4 切换 */
#include "reg51.h"
sfr P_SW2 = 0
void main()
&P_SW2 = 0x00;
//RXD4/P0.2, TXD4/P0.3
&//P_SW2 = 0x04;
//RXD4_2/P5.2, TXD4_2/P5.3
&while(1);
/* SPI切换 */
#include "reg51.h"
sfr P_SW1 = 0xa2;
void main()
&P_SW1 = 0x00;
//SS/P1.2, MOSI/P1.3, MISO/P1.4, SCLK/P1.5
&//P_SW1 = 0x04;
//SS_2/P2.2, MOSI_2/P2.3, MISO_2/P2.4, SCLK_2/P2.5
&//P_SW1 = 0x08;
//SS_3/P7.4, MOSI_3/P7.5, MISO_3/P7.6, SCLK_3/P7.7
&//P_SW1 = 0x0c;
//SS_4/P3.5, MOSI_4/P3.4, MISO_4/P3.3, SCLK_4/P3.2
&while(1);
/* PWM切换 */
#include "reg51.h"
#define PWM0CR(*(unsigned char volatile xdata *) 0xff04)
#define PWM1CR(*(unsigned char volatile xdata *) 0xff14)
#define PWM2CR(*(unsigned char volatile xdata *) 0xff24)
#define PWM3CR(*(unsigned char volatile xdata *) 0xff34)
#define PWM4CR(*(unsigned char volatile xdata *) 0xff44)
#define PWM5CR(*(unsigned char volatile xdata *) 0xff54)
#define PWM6CR(*(unsigned char volatile xdata *) 0xff64)
#define PWM7CR(*(unsigned char volatile xdata *) 0xff74)
sfr P_SW2 = 0
void main()
&P_SW2 = 0x80;
&PWM0CR = 0x00;
//PWM0/P2.0
&//PWM0CR = 0x08;
//PWM0_2/P1.0
&//PWM0CR = 0x10;
//PWM0_3/P6.0
&PWM1CR = 0x00;
//PWM1/P2.1
&//PWM1CR = 0x08;
//PWM1_2/P1.1
&//PWM1CR = 0x10;
//PWM1_3/P6.1
&PWM2CR = 0x00;
//PWM2/P2.2
&//PWM2CR = 0x08;
//PWM2_2/P1.2
&//PWM2CR = 0x10;
//PWM2_3/P6.2
&PWM3CR = 0x00;
//PWM3/P2.3
&//PWM3CR = 0x08;
//PWM3_2/P1.3
&//PWM3CR = 0x10;
//PWM3_3/P6.3
&PWM4CR = 0x00;
//PWM4/P2.4
&//PWM4CR = 0x08;
//PWM4_2/P1.4
&//PWM4CR = 0x10;
//PWM4_3/P6.4
&PWM5CR = 0x00;
//PWM5/P2.5
&//PWM5CR = 0x08;
//PWM5_2/P1.5
&//PWM5CR = 0x10;
//PWM5_3/P6.5
&PWM6CR = 0x00;
//PWM6/P2.6
&//PWM6CR = 0x08;
//PWM6_2/P1.6
&//PWM6CR = 0x10;
//PWM6_3/P6.6
&PWM7CR = 0x00;
//PWM7/P2.7
&//PWM7CR = 0x08;
//PWM7_2/P1.7
&//PWM7CR = 0x10;
//PWM7_3/P6.7
&P_SW2 = 0x00;
&while(1);
/* PCA/CCP切换 */
#include "reg51.h"
sfr P_SW1 = 0xa2;
void main()
&P_SW1 = 0x00;
//ECI/P1.2, CCP0/P1.7, CCP1/P1.6, CCP2/P1.5,CCP3/P1.4
&//P_SW1 = 0x10;
//ECI_2/P2.2, CCP0_2/P2.3, CCP1_2/P2.4, CCP2_2/P2.5,CCP3_2/P2.6
&//P_SW1 = 0x20;
//ECI_3/P7.4, CCP0_3/P7.0, CCP1_3/P7.1, CCP2_3/P7.2,CCP3_3/P7.3
&//P_SW1 = 0x30;
//ECI_4/P3.5, CCP0_4/P3.3, CCP1_4/P3.2, CCP2_4/P3.1,CCP3_4/P3.0
&while(1);
/* I2C切换 */
#include "reg51.h"
sfr P_SW2 = 0
void main()
&P_SW2 = 0x00;
//SCL/P1.5, SDA/P1.4
&//P_SW2 = 0x10;
//SCL_2/P2.5, SDA_2/P2.4
&//P_SW2 = 0x20;
//SCL_3/P7.7, SDA_3/P7.6
&//P_SW2 = 0x30;
//SCL_4/P3.2, SDA_4/P3.3
&while(1);
/* 比较器输出切换 */
#include "reg51.h"
sfr P_SW2 = 0
void main()
&P_SW2 = 0x00;
//CMPO/P3.4
&//P_SW2 = 0x08;
//CMPO_2/P4.1
&while(1);
/* 主时钟输出切换 */
#include "reg51.h"
#define CKSEL(*(unsigned char volatile xdata *) 0xfe00)
sfr P_SW2 = 0
void main()
&P_SW2 = 0x80;
&CKSEL = 0x40;
//IRC24M/4 output via MCLKO/P5.4
&//CKSEL = 0x48;
//IRC24M/4 output via MCLKO_2/P1.6
&//CKSEL = 0xe8;
//IRC24M/128 output via MCLKO_2/P1.6
&P_SW2 = 0x00;
&while(1);
/* EEPROM基本操作 */
#include "reg51.h"
#include "intrins.h"
&//测试工作频率为 11.0592MHz
sfr IAP_DATA = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
sfr IAP_CMD
sfr IAP_TRIG = 0xC6;
sfr IAP_CONTR = 0xC7;
WT_30M 0x80
WT_24M 0x81
WT_20M 0x82
WT_12M 0x83
WT_6M 0x84
WT_3M 0x85
WT_2M 0x86
WT_1M 0x87
void IapIdle()
&IAP_CONTR = 0;
//关闭 IAP 功能
//清除命令寄存器
&IAP_TRIG = 0;
//清除触发寄存器
&IAP_ADDRH = 0x80;
//将地址设置到非 IAP 区域
&IAP_ADDRL = 0;
char IapRead(int addr)
&IAP_CONTR = WT_12M;
//使能 IAP
//设置 IAP 读命令
&IAP_ADDRL =
//设置 IAP 低地址
&IAP_ADDRH = addr >> 8;
//设置 IAP 高地址
&IAP_TRIG = 0x5a;
//写触发命令(0x5a)
&IAP_TRIG = 0xa5;
//写触发命令(0xa5)
&dat = IAP_DATA;
//读 IAP 数据
&IapIdle();
//关闭 IAP 功能
&return(dat);
void IapProgram(int addr, char dat)
&IAP_CONTR = WT_12M;
//使能 IAP
//设置 IAP 写命令
&IAP_ADDRL =
//设置 IAP 低地址
&IAP_ADDRH = addr >> 8;
//设置 IAP 高地址
&IAP_DATA =
//写 IAP 数据
&IAP_TRIG = 0x5a;
//写触发命令(0x5a)
&IAP_TRIG = 0xa5;
//写触发命令(0xa5)
&IapIdle();
//关闭 IAP 功能
void IapErase(int addr)
&IAP_CONTR = WT_12M;
//使能 IAP
//设置 IAP 擦除命令
&IAP_ADDRL =
//设置 IAP 低地址
&IAP_ADDRH = addr >> 8;
//设置 IAP 高地址
&IAP_TRIG = 0x5a;
//写触发命令(0x5a)
&IAP_TRIG = 0xa5;
//写触发命令(0xa5)
&IapIdle();
//关闭 IAP 功能
void main()
&IapErase(0x0400);
&P0 = IapRead(0x0400);
&IapProgram(0x);
&P1 = IapRead(0x0400);
&while(1);
/* 串口1 使用定时器 1(模式 2)做波特率发生器 */
#include "reg51.h"
#include "intrins.h"
BRT(256 - FOSC / 115200 / 32)
sfr AUXR = 0x8e;
char buffer[16];
void UartIsr() interrupt 4 using 1
&&busy = 0;
&&buffer[wptr++] = SBUF;
void UartInit()
&SCON = 0x50;
&TMOD = 0x20;
&TL1 = BRT;
&TH1 = BRT;
&AUXR = 0x40;
&wptr = 0x00;
&rptr = 0x00;
&busy = 0;
void UartSend(char dat)
&while(busy);
&busy = 1;
void UartSendStr(char *p)
&while(*p)
&&UartSend(*p++);
void main()
&UartInit();
&UartSendStr("Uart Test !\r\n");
&while(1);
&&if(rptr != wptr)
&&&UartSend(buffer[rptr++]);
&&&rptr &= 0x0f;
/* 格式化ADC转换结果 */
#include "reg51.h"
#include "intrins.h"
&//测试工作频率为 11.0592MHz
sfr ADC_CONTR = 0
sfr ADC_RES
sfr ADC_RESL = 0
sfr ADCCFG
void main()
//设置 P1.0 为 ADC 口
//设置 ADC 时钟为系统时钟 /2/16/16
&ADC_CONTR = 0x80;
//使能 ADC 模块
&ADC_CONTR |= 0x40;
//启动 AD 转换
&while(!(ADC_CONTR & 0x20));
//查询 ADC 完成标志
&ADC_CONTR &= ~0x20;
//清完成标志
//设置结果左对齐
= ADC_RES;
//A 存储 ADC 的 12 位结果的高 8 位
= ADC_RESL;
//B[7:4] 存储 ADC 的 12 位结果的低 4 位 ,B[3:0] 为 0
&//ADCCFG = 0x20;
// 设置结果右对齐
&//ACC = ADC_RES;
//A[3:0] 存储 ADC 的 12 位结果的高 4 位 ,A[7:4] 为 0
&//B = ADC_RESL;
//B 存储 ADC 的 12 位结果的低 8 位
&while(1);
/* I2C主机模式访问AT24C256(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
sbit SDA = P1^4;
sbit SCL = P1^5;
void I2C_Isr() interrupt 24 using 1
&_push_(P_SW2);
&P_SW2 |= 0x80;
&if(I2CMSST & 0x40)
&&I2CMSST &= ~0x40;
//清中断标志
&&busy = 0;
&_pop_(P_SW2);
void Start()
&busy = 1;
&I2CMSCR = 0x81;
//发送 START 命令
&while(busy);
void SendData(char dat)
//写数据到数据缓冲区
&busy = 1;
&I2CMSCR = 0x82;
//发送 SEND 命令
&while(busy);
void RecvACK()
&busy = 1;
&I2CMSCR = 0x83;
//发送读 ACK 命令
&while(busy);
char RecvData()
&busy = 1;
&I2CMSCR = 0x84;
//发送 RECV 命令
&while(busy);
&return(I2CRXD);
void SendACK()
&I2CMSST = 0x00;
//设置 ACK 信号
&busy = 1;
&I2CMSCR = 0x85;
//发送 ACK 命令
&while(busy);
void SendNAK()
&I2CMSST = 0x01;
//设置 NAK 信号
&busy = 1;
&I2CMSCR = 0x85;
//发送 ACK 命令
&while(busy);
void Stop()
&busy = 1;
&I2CMSCR = 0x86;
//发送 STOP 命令
&while(busy);
void Delay()
&for(i = 0; i < 3000; i++)
&&_nop_();
&&_nop_();
&&_nop_();
&&_nop_();
void main()
&P_SW2 = 0x80;
&I2CCFG = 0xe0;
//使能 I2C 主机模式
&I2CMSST = 0x00;
//发送起始命令
&SendData(0xa0);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址高字节
&RecvACK();
&SendData(0x00);
//发送存储地址低字节
&RecvACK();
&SendData(0x12);
//写测试数据 1
&RecvACK();
&SendData(0x78);
//写测试数据 2
&RecvACK();
//发送停止命令
//等待设备写数据
//发送起始命令
&SendData(0xa0);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址高字节
&RecvACK();
&SendData(0x00);
//发送存储地址低字节
&RecvACK();
//发送起始命令
&SendData(0xa1);
//发送设备地址 + 读命令
&RecvACK();
&P0 = RecvData();
//读取数据 1
&SendACK();
&P2 = RecvData();
//读取数据 2
&SendNAK();
//发送停止命令
&P_SW2 = 0x00;
&while(1);
/* I2C主机模式访问AT24C256(查询方式) */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
sbit SDA = P1^4;
sbit SCL = P1^5;
void Wait()
&while(!(I2CMSST & 0x40));
&I2CMSST &= ~0x40;
void Start()
&I2CMSCR = 0x01;
//发送 START 命令
void SendData(char dat)
//写数据到数据缓冲区
&I2CMSCR = 0x02;
//发送 SEND 命令
void RecvACK()
&I2CMSCR = 0x03;
//发送读 ACK 命令
char RecvData()
&I2CMSCR = 0x04;
//发送 RECV 命令
&return(I2CRXD);
void SendACK()
&I2CMSST = 0x00;
//设置 ACK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void SendNAK()
&I2CMSST = 0x01;
//设置 NAK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void Stop()
&I2CMSCR = 0x06;
//发送 STOP 命令
void Delay()
&for(i = 0; i < 3000; i++)
&&_nop_();
&&_nop_();
&&_nop_();
&&_nop_();
void main()
&P_SW2 = 0x80;
&I2CCFG = 0xe0;
//使能 I2C 主机模式
&I2CMSST = 0x00;
//发送起始命令
&SendData(0xa0);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址高字节
&RecvACK();
&SendData(0x00);
//发送存储地址低字节
&RecvACK();
&SendData(0x12);
//写测试数据 1
&RecvACK();
&SendData(0x78);
//写测试数据 2
&RecvACK();
//发送停止命令
//等待设备写数据
//发送起始命令
&SendData(0xa0);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址高字节
&RecvACK();
&SendData(0x00);
//发送存储地址低字节
&RecvACK();
//发送起始命令
&SendData(0xa1);
//发送设备地址 + 读命令
&RecvACK();
&P0 = RecvData();
//读取数据 1
&SendACK();
&P2 = RecvData();
//读取数据 2
&SendNAK();
//发送停止命令
&P_SW2 = 0x00;
&while(1);
/* I2C主机模式访问PCF8563 */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
sbit SDA = P1^4;
sbit SCL = P1^5;
void Wait()
&while(!(I2CMSST & 0x40));
&I2CMSST &= ~0x40;
void Start()
&I2CMSCR = 0x01;
//发送 START 命令
void SendData(char dat)
//写数据到数据缓冲区
&I2CMSCR = 0x02;
//发送 SEND 命令
void RecvACK()
&I2CMSCR = 0x03;
//发送读 ACK 命令
char RecvData()
&I2CMSCR = 0x04;
//发送 RECV 命令
&return(I2CRXD);
void SendACK()
&I2CMSST = 0x00;
//设置 ACK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void SendNAK()
&I2CMSST = 0x01;
//设置 NAK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void Stop()
&I2CMSCR = 0x06;
//发送 STOP 命令
void Delay()
&for(i = 0; i < 3000; i++)
&&_nop_();
&&_nop_();
&&_nop_();
&&_nop_();
void main()
&P_SW2 = 0x80;
&I2CCFG = 0xe0;
//使能 I2C 主机模式
&I2CMSST = 0x00;
//发送起始命令
&SendData(0xa2);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x02);
//发送存储地址
&RecvACK();
&SendData(0x00);
//设置秒值
&RecvACK();
&SendData(0x00);
//设置分钟值
&RecvACK();
&SendData(0x12);
//设置小时值
&RecvACK();
//发送停止命令
&while(1);
&&Start();
//发送起始命令
&&SendData(0xa2);
//发送设备地址 + 写命令
&&RecvACK();
&&SendData(0x02);
//发送存储地址
&&RecvACK();
&&Start();
//发送起始命令
&&SendData(0xa3);
//发送设备地址 + 读命令
&&RecvACK();
&&P0 = RecvData();
//读取秒值
&&SendACK();
&&P2 = RecvData();
//读取分钟值
&&SendACK();
&&P3 = RecvData();
//读取小时值
&&SendNAK();
//发送停止命令
&&Delay();
/* I2C从机模式(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
SDA = P1^4;
SCL = P1^5;
//设备地址标志
//存储地址标志
unsigned char pdata buffer[256];
void I2C_Isr() interrupt 24 using 1
&_push_(P_SW2);
&P_SW2 |= 0x80;
&if(I2CSLST & 0x40)
&&I2CSLST &= ~0x40;
//处理 START 事件
&}else if(I2CSLST & 0x20)
&&I2CSLST &= ~0x20;
//处理 RECV 事件
&&if(isda)
&&&isda = 0;
//处理 RECV 事件( RECV DEVICE ADDR )
&&}else if(isma)
&&&isma = 0;
//处理 RECV 事件( RECV MEMORY ADDR )
&&&addr = I2CRXD;
&&&I2CTXD = buffer[addr];
&&&buffer[addr++] = I2CRXD;
//处理 RECV 事件( RECV DATA )
&}else if(I2CSLST & 0x10)
&&I2CSLST &= ~0x10;
//处理 SEND 事件
&&I2CTXD = buffer[++addr];
&}else if(I2CSLST & 0x08)
&&I2CSLST &= ~0x08;
//处理 STOP 事件
&&isda = 1;
&&isma = 1;
&_pop_(P_SW2);
void main()
//使能 I2C 从机模式
&I2CSLADR = 0x5a;
//设置从机设备地址为 5A
//使能从机模式中断
//用户变量初始化
= buffer[addr];
&while(1);
/* I2C从机模式(查询方式) */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
SDA = P1^4;
SCL = P1^5;
//设备地址标志
//存储地址标志
unsigned char pdata buffer[256];
void main()
//使能 I2C 从机模式
&I2CSLADR = 0x5a;
//设置从机设备地址为 5A
//禁止从机模式中断
//用户变量初始化
= buffer[addr];
&while(1);
&&if(I2CSLST & 0x40)
&&&I2CSLST &= ~0x40
//处理 START 事件
&&}else if(I2CSLST & 0x20)
&&&I2CSLST &= ~0x20;
//处理 RECV 事件
&&&if(isda)
&&&&isda = 0;
//处理 RECV 事件( RECV DEVICE ADDR )
&&&}else if(isma)
&&&&isma = 0;
//处理 RECV 事件( RECV MEMORY ADDR )
&&&&addr = I2CRXD;
&&&&I2CTXD = buffer[addr];
&&&&buffer[addr++] = I2CRXD;
//处理 RECV 事件( RECV DATA )
&&}else if(I2CSLST & 0x10)
&&&I2CSLST &= ~0x10;
//处理 SEND 事件
&&&I2CTXD = buffer[++addr];
&&}else if(I2CSLST & 0x08)
&&&I2CSLST &= ~0x08;
//处理 STOP 事件
&&&isda = 1;
&&&isma = 1;
/* 测试I2C从机模式代码的主机代码 */
#include "reg51.h"
#include "intrins.h"
sfr P_SW2 = 0
I2CCFG (*(unsigned char volatile xdata *) 0xfe80)
I2CMSCR(*(unsigned char volatile xdata *) 0xfe81)
I2CMSST(*(unsigned char volatile xdata *) 0xfe82)
I2CSLCR(*(unsigned char volatile xdata *) 0xfe83)
I2CSLST(*(unsigned char volatile xdata *) 0xfe84)
I2CSLADR(*(unsigned char volatile xdata *) 0xfe85)
I2CTXD (*(unsigned char volatile xdata *) 0xfe86)
I2CRXD (*(unsigned char volatile xdata *) 0xfe87)
sbit SDA = P1^4;
sbit SCL = P1^5;
void Wait()
&while(!(I2CMSST & 0x40));
&I2CMSST &= ~0x40;
void Start()
&I2CMSCR = 0x01;
//发送 START 命令
void SendData(char dat)
//写数据到数据缓冲区
&I2CMSCR = 0x02;
//发送 SEND 命令
void RecvACK()
&I2CMSCR = 0x03;
//发送读 ACK 命令
char RecvData()
&I2CMSCR = 0x04;
//发送 RECV 命令
&return(I2CRXD);
void SendACK()
&I2CMSST = 0x00;
//设置 ACK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void SendNAK()
&I2CMSST = 0x01;
//设置 NAK 信号
&I2CMSCR = 0x05;
//发送 ACK 命令
void Stop()
&I2CMSCR = 0x06;
//发送 STOP 命令
void Delay()
&for(i = 0; i < 3000; i++)
&&_nop_();
&&_nop_();
&&_nop_();
&&_nop_();
void main()
&P_SW2 = 0x80;
&I2CCFG = 0xe0;
//使能 I2C 主机模式
&I2CMSST = 0x00;
//发送起始命令
&SendData(0x5a);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址
&RecvACK();
&SendData(0x12);
//写测试数据 1
&RecvACK();
&SendData(0x78);
//写测试数据 2
&RecvACK();
//发送停止命令
//发送起始命令
&SendData(0x5a);
//发送设备地址 + 写命令
&RecvACK();
&SendData(0x00);
//发送存储地址高字节
&RecvACK();
//发送起始命令
&SendData(0x5b);
//发送设备地址 + 读命令
&RecvACK();
&P0 = RecvData();
//读取数据 1
&SendACK();
&P2 = RecvData();
//读取数据 2
&SendNAK();
//发送停止命令
&P_SW2 = 0x00;
&while(1);
/* SPI单主单从系统主机程序(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr SPSTAT = 0
sfr SPCTL = 0
sfr SPDAT = 0
sfr IE2 = 0
sbit SS = P1^0;
sbit LED = P1^1;
void SPI_Isr() interrupt 9 using 1
&SPSTAT = 0xc0;
//清中断标志
//拉高从机的 SS 管脚
&busy = 0;
&LED = !LED;
//测试端口
void main()
&busy = 0;
&SPCTL = 0x50;
//使能 SPI 主机模式
&SPSTAT = 0xc0;
//清中断标志
&IE2 = ESPI;
//使能 SPI 中断
&while(1);
&&while(busy);
&&busy = 1;
//拉低从机 SS 管脚
&&SPDAT = 0x5a;
//发送测试数据
/* SPI单主单从系统从机程序(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr SPSTAT = 0
sfr SPCTL = 0
sfr SPDAT = 0
sfr IE2 = 0
sbit LED = P1^1;
void SPI_Isr() interrupt 9 using 1
&SPSTAT = 0xc0;
//清中断标志
&SPDAT = SPDAT;
//将接收到的数据回传给主机
&LED = !LED;
//测试端口
void main()
&SPCTL = 0x40;
//使能 SPI 从机模式
&SPSTAT = 0xc0;
//清中断标志
&IE2 = ESPI;
//使能 SPI 中断
&while(1);
/* SPI互为主从系统程序(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr SPSTAT = 0
sfr SPCTL = 0
sfr SPDAT = 0
sfr IE2 = 0
sbit SS = P1^0;
sbit LED = P1^1;
sbit KEY = P0^0;
void SPI_Isr() interrupt 9 using 1
&SPSTAT = 0xc0;
//清中断标志
&if(SPCTL & 0x10)
//主机模式
//拉高从机的 SS 管脚
&&SPCTL = 0x40;
//重新设置为从机待机
//从机模式
&&SPDAT = SPDAT;
//将接收到的数据回传给主机
&LED = !LED;
//测试端口
void main()
&SPCTL = 0x40;
//使能 SPI 从机模式进行待机
&SPSTAT = 0xc0;
//清中断标志
&IE2 = ESPI;
//使能 SPI 中断
&while(1);
&&if(!KEY)
//等待按键触发
&&&SPCTL = 0x50;
//使能 SPI 主机模式
&&&SS = 0;
//拉低从机 SS 管脚
&&&SPDAT = 0x5a;
//发送测试数据
&&&while(!KEY);
//等待按键释放
/* SPI互为主从系统程序(查询方式) */
#include "reg51.h"
#include "intrins.h"
sfr SPSTAT = 0
sfr SPCTL = 0
sfr SPDAT = 0
sfr IE2 = 0
sbit SS = P1^0;
sbit LED = P1^1;
sbit KEY = P0^0;
void main()
&SPCTL = 0x40;
//使能 SPI 从机模式进行待机
&SPSTAT = 0xc0;
//清中断标志
&while(1);
//等待按键触发
&&&SPCTL = 0x50;
//使能 SPI 主机模式
&&&SS = 0;
//拉低从机 SS 管脚
&&&SPDAT = 0x5a;
//发送测试数据
&&&while(!KEY);
//等待按键释放
&&if(SPSTAT & 0x80)
&&&SPSTAT = 0xc0;
//清中断标志
&&&if(SPCTL & 0x10)
//主机模式
&&&&SS = 1;
//拉高从机的 SS 管脚
&&&&SPCTL = 0x40;
//重新设置为从机待机
//从机模式
&&&&SPDAT = SPDAT;
//将接收到的数据回传给主机
&&&LED = !LED;
//测试端口
/* 比较器的使用(中断方式) */
#include "reg51.h"
#include "intrins.h"
sfr CMPCR1 = 0xe6;
sfr CMPCR2 = 0xe7;
sbit P10 = P1^0;
sbit P11 = P1^1;
void CMP_Isr() interrupt 21 using 1
&CMPCR1 &= ~0x40;
//清中断标志
&if(CMPCR1 & 0x01)
&&P10 = !P10;
//下降沿中断测试端口
&&P11 = !P11;
//上升沿中断测试端口
void main()
&CMPCR2 = 0x00;
&CMPCR2 &= ~0x80;
//比较器正向输出
&//CMPCR2 |= 0x80;
// 比较器反向输出
&CMPCR2 &= ~0x40;
//禁止 0.1us 滤波
&//CMPCR2 |= 0x40;
// 使能 0.1us 滤波
&//CMPCR2 &= ~0x3f;
// 比较器结果直接输出
&CMPCR2 |= 0x10;
//比较器结果经过 16 个去抖时钟后输出
&CMPCR1 = 0x00;
&CMPCR1 |= 0x30;
//使能比较器边沿中断
&//CMPCR1 &= ~0x20;
// 禁止比较器上升沿中断
&//CMPCR1 |= 0x20;
// 使能比较器上升沿中断
&//CMPCR1 &= ~0x10;
// 禁止比较器下降沿中断
&//CMPCR1 |= 0x10;
// 使能比较器下降沿中断
&CMPCR1 &= ~0x08;
//P3.6 为 CMP+ 输入脚
&//CMPCR1 |= 0x08;
//ADC 输入脚为 CMP+ 输入教
&//CMPCR1 &= ~0x04;
// 内部参考电压为 CMP- 输入脚
&CMPCR1 |= 0x04;
//P3.7 为 CMP- 输入脚
&//CMPCR1 &= ~0x02;
// 禁止比较器输出
&CMPCR1 |= 0x02;
//使能比较器输出
&CMPCR1 |= 0x80;
//使能比较器模块
&while(1);
/* 比较器的使用(查询方式) */
#include "reg51.h"
#include "intrins.h"
sfr CMPCR1 = 0xe6;
sfr CMPCR2 = 0xe7;
sbit P10 = P1^0;
sbit P11 = P1^1;
void main()
&CMPCR2 = 0x00;
&CMPCR2 &= ~0x80;
//比较器正向输出
&//CMPCR2 |= 0x80;
// 比较器反向输出
&CMPCR2 &= ~0x40;
//禁止 0.1us 滤波
&//CMPCR2 |= 0x40;
// 使能 0.1us 滤波
&//CMPCR2 &= ~0x3f;
// 比较器结果直接输出
&CMPCR2 |= 0x10;
//比较器结果经过 16 个去抖时钟后输出
&CMPCR1 = 0x00;
&CMPCR1 |= 0x30;
//使能比较器边沿中断
&//CMPCR1 &= ~0x20;
// 禁止比较器上升沿中断
&//CMPCR1 |= 0x20;
// 使能比较器上升沿中断
&//CMPCR1 &= ~0x10;
// 禁止比较器下降沿中断
&//CMPCR1 |= 0x10;
// 使能比较器下降沿中断
&CMPCR1 &= ~0x08;
//P3.6 为 CMP+ 输入脚
&//CMPCR1 |= 0x08;
//ADC 输入脚为 CMP+ 输入教
&//CMPCR1 &= ~0x04;
// 内部参考电压为 CMP- 输入脚
&CMPCR1 |= 0x04;
//P3.7 为 CMP- 输入脚
&//CMPCR1 &= ~0x02;
// 禁止比较器输出
&CMPCR1 |= 0x02;
//使能比较器输出
&CMPCR1 |= 0x80;
//使能比较器模块
&while(1);
&&P10 = CMPCR1 & 0x01;
//读取比较器比较结果
(stcisp.com -整理,请以最新资料为准!)
(欢迎加入STC单片机学习交流QQ群:,共同学习提高)}

我要回帖

更多关于 单片机中断程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信