单片机代码终极版
单片机课程设计代码

陈新 2014/7/21 17:32:03QQ可以找到历史记录的陈新 17:33:15无痕的回忆 17:01:52LED_LOOP: MOV R1, #251 ;1s的显示延时(好奇怪,居然不准)LED_LOOP_1: MOV R4, #14 ;使用了寄存器R1,R4(估计可以使用堆栈临时释放)LED_LOOP_2: LCALL DISPLAY_MOVEDJNZ R4, LED_LOOP_2DJNZ R1, LED_LOOP_1RET无痕的回忆 23:10:36ORG 0000HAJMP MAINORG 0030HHC595_SCK BIT P0.4HC595_RCK BIT P0.5HC595_RST BIT P0.6HC595_DAT BIT P0.7MAIN: MOV A, #00HMOV P0, ACLR HC595_RSTLOOP0: MOV R0, #0LOOP1: MOV R1, #100LOOP2: MOV R4, #10LOOP3: LCALL DISPLAYDJNZ R4, LOOP3DJNZ R1, LOOP2INC R0LJMP LOOP1DELEY0: MOV R6, #4 ;1ms延时的子程序DELEY1: MOV R7, #123DELEY2: DJNZ R7, DELEY2DJNZ R6, DELEY1NOPRETDISPLAY: MOV A, R0 MOV B, #100DIV ABMOV B, #10DIV AB;MOV A, #0LCALL SHOW_NUM MOV A, P0ANL A, #0F0HORL A, #1MOV P0, A ;延时LCALL DELEY0 ;延时LCALL DELEY0MOV A, R0 ;有问题MOV B, #100DIV AB;MOV A, #7LCALL SHOW_NUM MOV A, P0ANL A, #0F0HORL A, #2MOV P0, A ;延时LCALL DELEY0 ;延时LCALL DELEY0MOV A, R0MOV B, #100DIV ABXCH A, BMOV B, #10DIV AB;MOV A, #7LCALL SHOW_NUM MOV A, P0ANL A, #0F0HORL A, #4MOV P0, ALCALL DELEY0 ;延时LCALL DELEY0 ;延时MOV A, R0MOV B, #10DIV AB;MOV A, #7LCALL SHOW_NUMMOV A, P0ANL A, #0F0HORL A, #8MOV P0, ALCALL DELEY0 ;延时LCALL DELEY0RETSHOW_NUM: MOV DPTR, #SEGMOVC A, @A+DPTRLCALL SEND_BYTERETSEND_BYTE: MOV R2, #8 ;注意这个循环次数控制,有误差则会影响数码管显示MOV R6, #01HSEND_LOOP: MOV R3, AANL A, R6JZ ZEROJNZ NZEROZERO: CLR HC595_DATAJMP NEXTNZERO: SETB HC595_DATNEXT: SETB HC595_SCKCLR HC595_SCKMOV A, R6RL AMOV R6, AMOV A, R3DJNZ R2, SEND_LOOPCLR HC595_RCKSETB HC595_RCKRETSEG: DB 0FCHDB 60HDB 0DAHDB 0F2HDB 66HDB 0BEHDB 0E0HDB 0FEHDB 0F6HEND无痕的回忆 23:10:04int8u tab_abc[] = {0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e};罐头 17:36:46还有那个循环的呢陈新 18:18:36已经发给你了啊DISPLAY: MOV A, KEY ;将KEY转移给ALCALL SHOW_NUMMOV P0, #0FFH ;打开所有的数码管即设置为静态显示MOV P0, ALCALL DELAY_1MS ;延时注意到在动态显示中,点亮每位数码管都需要2秒钟LCALL DELAY_1MS ;延时。
单片机程序源代码

单片机程序源代码第二章任务一:闪烁广告灯的设计利用89c51单片机的端口控制两个LED(D0和D1),编写程序,实现两个LED互闪。
#include<>#define uint unsigned int#define uchar unsigned charsbit LED1=P0^0;sbit LED2=P0^1;void delayms(uint ms){uint i;while(ms--){for(i=0;i<120;i++);}}void main(){while(1){LED1=0;LED2=1;delayms(500);LED1=1;LED2=0;delayms(500);}}任务二:流水广告灯的设计利用89c51单片机的端口控制8个LED(D0~D7)循环点亮,刚开始时D0点亮,延时片刻后,接着D1点亮,然后依次点亮D2->D3->D4->D5 ->D6->D7 ,然后再点亮D7->D6->D5->D4 ->D3->D2->D1->D0,重复循环。
#include<>#include <>#define uint unsigned int#define uchar unsigned charuint i;uchar temp;uint a[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};void delayms(uint ms){while(ms--){ uint j;for(j=0;j<120;j++);}}void main(){while(1){P0=0xfe;while(P0!=0x7f){7f89c89c0f89c0a0f7f0f0f0f7f7f2L3f4f7f6f7fDelay==0) break;else{sound(&music[n]);n++ ;}}}void main(){init();while(1){if(key==0){delayms(5);play(table1);}SPEAKER=1;}}void inter() interrupt 1{TH0 = ReloadH;TL0 = ReloadL;SPEAKER = !SPEAKER; //音乐声频的半个波}(3)#include<>//头文件#define uint unsigned int#define uchar unsigned char//宏定义sbit beep=P1^0;//按键位声明void Beep() //“叮咚”子函数{uint i,j;for(i=300;i;i--)//持续时间{beep=~beep;for(j=240;j;j--);//频率}for(i=200;i;i--)//持续时间{beep=~beep;for(j=180;j;j--);//频率}}void init() //初始化子函数{EA=1; //打开总中断TMOD=0x05;//设置计数器0 工作方式1ET0=1; //打开计数器0中断TR0=1;//启动定时器0TH0=0xff;TL0=0xff;//计数器赋初值}void beep_interrupt() interrupt 1 //计数器0中断服务子程序{TH0=0xff;TL0=0xff;//计数器初值Beep();//调用“叮咚”子函数}void main()//主函数{init();//调用初始化函数while(1);//等待按键按下}任务七:速度可调流水灯控制假设单片机晶振频率为12MHz,单片机P0口外接8只LED,外接按键K1,外接按键K2。
单片机指令大全

单片机指令大全- - 指令格式功能简述字节数周期一、数据传送类指令MOV A, Rn 寄存器送累加器 1 1MOV Rn,A 累加器送寄存器 1 1MOV A ,@Ri 内部RAM单元送累加器 1 1MOV @Ri ,A 累加器送内部RAM单元 1 1MOV A ,#data 立即数送累加器 2 1MOV A ,direct 直接寻址单元送累加器 2 1MOV direct ,A 累加器送直接寻址单元 2 1MOV Rn,#data 立即数送寄存器 2 1MOV direct ,#data 立即数送直接寻址单元 3 2MOV @Ri ,#data 立即数送内部RAM单元 2 1MOV direct ,Rn 寄存器送直接寻址单元 2 2MOV Rn ,direct 直接寻址单元送寄存器 2 2MOV direct ,@Ri 内部RAM单元送直接寻址单元 2 2 MOV @Ri ,direct 直接寻址单元送内部RAM单元 2 2 MOV direct2,direct1 直接寻址单元送直接寻址单元 3 2 MOV DPTR ,#data16 16位立即数送数据指针 3 2 MOVX A ,@Ri 外部RAM单元送累加器(8位地址) 1 2 MOVX @Ri ,A 累加器送外部RAM单元(8位地址) 1 2 MOVX A ,@DPTR 外部RAM单元送累加器(16位地址) 1 2MOVX @DPTR ,A 累加器送外部RAM单元(16位地址) 1 2 MOVC A ,@A+DPTR 查表数据送累加器(DPTR为基址) 1 2 MOVC A ,@A+PC 查表数据送累加器(PC为基址) 1 2 XCH A ,Rn 累加器与寄存器交换 1 1XCH A ,@Ri 累加器与内部RAM单元交换 1 1 XCHD A ,direct 累加器与直接寻址单元交换 2 1XCHD A ,@Ri 累加器与内部RAM单元低4位交换 1 1 SWAP A 累加器高4位与低4位交换 1 1POP direct 栈顶弹出指令直接寻址单元 2 2PUSH direct 直接寻址单元压入栈顶 2 2二、算术运算类指令ADD A, Rn 累加器加寄存器 1 1ADD A,@Ri 累加器加内部RAM单元 1 1ADD A, direct 累加器加直接寻址单元 2 1ADD A, #data 累加器加立即数 2 1ADDC A, Rn 累加器加寄存器和进位标志 1 1ADDC A,@Ri 累加器加内部RAM单元和进位标志 1 1 ADDC A, #data 累加器加立即数和进位标志 2 1 ADDC A, direct 累加器加直接寻址单元和进位标志 2 1INC A 累加器加1 1 1INC Rn 寄存器加1 1 1INC direct 直接寻址单元加1 2 1INC @Ri 内部RAM单元加1 1 1INC DPTR 数据指针加1 1 2DA A 十进制调整 1 1SUBB A, Rn 累加器减寄存器和进位标志 1 1 SUBB A,@Ri 累加器减内部RAM单元和进位标志 1 1 SUBB A, #data 累加器减立即数和进位标志 2 1 SUBB A, direct 累加器减直接寻址单元和进位标志 2 1 DEC A 累加器减1 1 1DEC Rn 寄存器减1 1 1DEC @Ri 内部RAM单元减1 1 1DEC direct 直接寻址单元减1 2 1MUL AB 累加器乘寄存器B 1 4DIV AB 累加器除以寄存器B 1 4三、逻辑运算类指令ANL A, Rn 累加器与寄存器 1 1ANL A,@Ri 累加器与内部RAM单元 1 1ANL A, #data 累加器与立即数 2 1ANL A, direct 累加器与直接寻址单元 2 1ANL direct, A 直接寻址单元与累加器 2 1ANL direct, #data 直接寻址单元与立即数 3 1ORL A, Rn 累加器或寄存器 1 1ORL A,@Ri 累加器或内部RAM单元 1 1ORL A,#data 累加器或立即数 2 1 ORL A,direct 累加器或直接寻址单元 2 1 ORL direct, A 直接寻址单元或累加器 2 1 ORL direct, #data 直接寻址单元或立即数 3 1 XRL A, Rn 累加器异或寄存器 1 1XRL A,@Ri 累加器异或内部RAM单元 1 1 XRL A,#data 累加器异或立即数 2 1 XRL A,direct 累加器异或直接寻址单元 2 1 XRL direct, A 直接寻址单元异或累加器 2 1 XRL direct, #data 直接寻址单元异或立即数 3 2 RL A 累加器左循环移位 1 1RLC A 累加器连进位标志左循环移位 1 1 RR A 累加器右循环移位 1 1RRC A 累加器连进位标志右循环移位 1 1 CPL A 累加器取反 1 1CLR A 累加器清零 1 1四、控制转移类指令类ACCALL addr11 2KB范围内绝对调用 2 2 AJMP addr11 2KB范围内绝对转移 2 2 LCALL addr16 2KB范围内长调用 3 2 LJMP addr16 2KB范围内长转移 3 2 SJMP rel 相对短转移 2 2JMP @A+DPTR 相对长转移 1 2RET 子程序返回 1 2RET1 中断返回 1 2JZ rel 累加器为零转移 2 2JNZ rel 累加器非零转移 2 2CJNE A ,#data ,rel 累加器与立即数不等转移 3 2 CJNE A ,direct ,rel 累加器与直接寻址单元不等转移 3 2 CJNE Rn,#data ,rel 寄存器与立即数不等转移 3 2 CJNE @Ri ,#data,rel RAM单元与立即数不等转移 3 2 DJNZ Rn ,rel 寄存器减1不为零转移 2 2 DJNZ direct ,rel 直接寻址单元减1不为零转移 3 2 NOP 空操作 1 1五、布尔操作类指令MOV C, bit 直接寻址位送C 2 1MOV bit, C C送直接寻址位 2 1CLR C C清零 1 1CLR bit 直接寻址位清零 2 1CPL C C取反 1 1CPL bit 直接寻址位取反 2 1SETB C C置位 1 1SETB bit 直接寻址位置位 2 1ANL C, bit C逻辑与直接寻址位 2 2ANL C, /bit C逻辑与直接寻址位的反 2 2ORL C, bit C逻辑或直接寻址位 2 2ORL C, /bit C逻辑或直接寻址位的反 2 2JC rel C为1转移 2 2JNC rel C为零转移 2 2JB bit,rel 直接寻址位为1转移 3 2JNB bit,rel 直接寻址为0转移 3 2JBC bit,rel 直接寻址位为1转移并清该位 3 2单片机MCS-51系列指令快速记忆法随着微电子技术和超大规模集成电路技术的发展,单片微型计算机以其体积小、性价比高、功能强、可靠性高等独有的特点,在各个领域(如工业控制、家电产品、汽车电子、通信、智能仪器仪表)得到了广泛的应用。
单片机指令大全

引言概述:单片机指令是嵌入式系统设计中至关重要的一部分,它们定义了单片机的功能和操作。
本文是单片机指令大全系列的第二部分,旨在提供更多全面的单片机指令信息,帮助读者更好地理解和应用单片机指令。
正文内容:一、移位指令1.逻辑左移指令:将操作数的每一位向左移动一位,并且最低位填充0。
2.逻辑右移指令:将操作数的每一位向右移动一位,并且最高位填充0。
3.算术右移指令:将操作数的每一位向右移动一位,并且最高位保持不变。
4.循环左移指令:将操作数的每一位向左循环移动一位,即最高位移动到最低位。
5.循环右移指令:将操作数的每一位向右循环移动一位,即最低位移动到最高位。
二、逻辑运算指令1.逻辑与指令:对操作数进行逻辑与运算,将两个二进制数对应位上的值进行逻辑与操作。
2.逻辑或指令:对操作数进行逻辑或运算,将两个二进制数对应位上的值进行逻辑或操作。
3.逻辑非指令:对操作数进行逻辑非运算,将二进制数的每一位取反。
4.逻辑异或指令:对操作数进行逻辑异或运算,将两个二进制数对应位上的值进行逻辑异或操作。
5.逻辑移位指令:将操作数进行逻辑左移或右移。
三、算术运算指令1.加法指令:对操作数进行加法运算,并将运算结果保存到指定的寄存器或存储器中。
2.减法指令:对操作数进行减法运算,并将运算结果保存到指定的寄存器或存储器中。
3.乘法指令:对操作数进行乘法运算,并将运算结果保存到指定的寄存器或存储器中。
4.除法指令:对操作数进行除法运算,并将运算结果保存到指定的寄存器或存储器中。
5.移位指令:对操作数进行移位运算,包括算术左移、算术右移、循环左移和循环右移。
四、输入输出指令1.读取输入指令:从指定的输入设备读取数据,并将数据保存到指定的寄存器或存储器中。
2.输出显示指令:将指定的数据从寄存器或存储器中读取,并显示到指定的输出设备上。
3.端口输入指令:从指定的端口读取数据,并将数据保存到指定的寄存器或存储器中。
4.端口输出指令:将指定的数据从寄存器或存储器中读取,并输出到指定的端口上。
经典单片机实用开发教程代码

//实例51-2:定时器T0的模式2测量正脉冲宽度#include<reg51.h> //包含51单片机寄存器定义的头文件sbit ui=P3^2; //将ui位定义为P3.0(INT0)引脚,表示输入电压/*******************************************函数功能:主函数******************************************/void main(void){TMOD=0x0a; // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1 EA=1; //开总中断ET0=0; //不使用定时器T0的中断TR0=1; //启动T0TH0=0; //计数器T0高8位赋初值TL0=0; //计数器T0低8位赋初值while(1) //无限循环,不停地将TL0计数结果送P1口{while(ui==0) //INT0为低电平,T0不能启动;TL0=0; //INT0为高电平,启动T0计时,所以将TL0清0while(ui==1) //在INT0高电平期间,等待,计时;P1=TL0; //将计时结果送P1口显示}}//实例52:用定时器T0控制输出高低宽度不同的矩形波#include<reg51.h> //包含51单片机寄存器定义的头文件sbit u=P3^0; //将u位定义为P3.0,从该引脚输出矩形脉冲unsigned char Countor; //设置全局变量,储存负跳变累计数/*************************************************函数功能:延时约30ms (3*100*100=30 000μs =30ms)*************************************************/void delay30ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<100;n++);}/*******************************************函数功能:主函数******************************************/void main(void){unsigned char i;EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断Countor=0;for(i=0;i<100;i++) //输出100个负跳变{u=1;delay30ms();u=0;delay30ms();}while(1); //无限循环,防止程序跑飞}/************************************************************** 函数功能:外中断T0的中断服务程序**************************************************************/ void int0(void) interrupt 0 using 0 //外中断0的中断编号为0{Countor++;P1=Countor;}//实例53:用外中断0的中断方式进行数据采集#include<reg51.h> //包含51单片机寄存器定义的头文件sbit S=P3^2; //将S位定义为P3.2,/*******************************************函数功能:主函数******************************************/void main(void){EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断P1=0xff;while(1); //无限循环,防止程序跑飞}/**************************************************************函数功能:外中断T0的中断服务程序**************************************************************/ void int0(void) interrupt 0 using 0 //外中断0的中断编号为0{P1=~P1; //每产生一次中断请求,P1取反一次。
STCCAS单片机各个模块程序代码

//**************************************************************************** //// STC12C5A60S2可编程时钟模块////// 说明:STC12C5A60S2单片机有三路可编程时钟输出CLKOUT0/T0/P3.4// CLKOUT1/T1/P3.5、CLKOUT2/P1.0//// 涉及寄存器:AUXR(辅助寄存器)、WAKE_CLKO(时钟与系统掉电唤醒控制寄存器) // BRT(独立波特率发生器定时器寄存器)//// 程序说明:// 本程序可选实现P3.4输出CLKOUT0时钟、P3.5输出CLKOUT1时钟// P1.0输出CLKOUT2时钟//////************************************************************************** **//#include <STC12C5A60S2.H>#include <intrins.h>//#define Port_BRT //如果想测试独立波特率发生器时钟输出请打开此句//若想测试CLKOUT1和CLKOUT0请注释此句#ifdef Port_BRT /*条件编译独立波特率发生器时钟输出*///*********************************//// CLKOUT2时钟初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x04; //Bit2-BRTCLKO 允许P1.0配置为独立波特率发生器的时钟输出//BRT工作在1T模式下时的输出频率 = Sysclk/(256-BRT)/2 //BRT工作在12T模式下时输出频率 = Sysclk/12/(256-BRT)/2 AUXR = 0x14; //Bit4-BRTR 允许独立波特率发生器运行//Bit2-BRTx12 BRT工作在1T模式下BRT = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频}#else /*条件编译CLKOUT0时钟输出*///*********************************//// CLKOUT0时钟和CLKOUT1初始化 ////*********************************//void CLKOUT_init(void){WAKE_CLKO = 0x03; //允许将P3.4/T0脚配置为定时器0的时钟输出CLKOUT0//T0工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2//T0工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2 //1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只能工作在定时器模式2下//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2 //1T指的是每1个时钟加1,是普通C51的12倍//12T指的是每12个时钟加1与普通C51一样AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下//T1定时器速度是普通8051的12倍,即工作在1T模式下TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数//定时器1工作模式为方式2,自动装载时间常数TH0 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL0 = 0xff;TH1 = 0xff; //更改该寄存器的值可实现对输出的时钟频率进行分频TL1 = 0xff;TR1 = 1;TR0 = 1;}#endif//**********************************//// 主程序////**********************************//void main(){CLKOUT_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统时钟模块////// 说明: STC12C5A60S2单片机有两个时钟源,内部R/C振荡时钟和外部晶体时钟// 出厂标准配置是使用外部晶体或时钟////// 涉及寄存器:CLK_DIV(时钟分频寄存器)// 由该寄存器的Bit0-2组合可实现对时钟源进行0、2、4、8、16 // 32、64、128分频// //// 程序说明:// 对外部时钟进行分频得到Sysclk,然后经过P1.0的独立波特率// 时钟输出功能Sysclk/2输出时钟频率//**************************************************************************** //#include <STC12C5A60S2.h>#include <intrins.h>#define Bus_clk 12 //若要修改系统时钟直接在此处修改//12 为 12M 的sysclk//6 为 6M 的sysclk//3 为 3M 的sysclk//1500 为 1.5M 的sysclk//750 为 750kHz 的sysclk//375 为 375kHz 的sysclk//187500 为 187.5kHz 的sysclk//93750 为 93.75kHz 的sysclk//*********************************************//// 系统时钟初始化 ////*********************************************//void Sysclk_init(void){WAKE_CLKO = 0x04; //配置P1.0口为频率输出AUXR = 0x14; //允许波特率时钟工作//工作模式为1TBRT = 0xff;#if( Bus_clk == 12 )CLK_DIV = 0x00;#elif( Bus_clk == 6 )CLK_DIV = 0x01;#elif( Bus_clk == 3 )CLK_DIV = 0x02;#elif( Bus_clk == 1500 )CLK_DIV = 0x03;#elif( Bus_clk == 750 )CLK_DIV = 0x04;#elif( Bus_clk == 375 )CLK_DIV = 0x05;#elif( Bus_clk == 187500 )CLK_DIV = 0x06;#elif( Bus_clk == 93750 )CLK_DIV = 0x07;#endif}//**********************************************//// 主程序////**********************************************//void main(){Sysclk_init();while(1);}//**************************************************************************** //// STC12C5A60S2系统省电模块////// 说明: STC12C5A60S2单片机有三种省电模式以降低功耗.空闲模式,低速模式// 掉电模式////// 涉及寄存器:PCON(电源控制寄存器)// Bit0 - IDL 控制单片机进入IDLE空闲模式// Bit1 - PD 控制单片机进入掉电模式// //// 程序说明:程序实现让单片机先工作一阵子(通过P0^3指示灯显示)// 然后进入掉电状态,利用外部中断0口来唤醒单片机工作// 唤醒后单片机将通过P0^0-3口的灯闪烁显示开始工作////************************************************************************** **//#include <STC12C5A60S2.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar Power_Down_Flag = 0; //进入掉电状态标志sbit Chip_Start_LED = P0^0; //单片机开始工作指示灯sbit Power_Down_LED_INT0 = P0^1; //INT0口掉电唤醒指示灯sbit N_Power_Down_LED_INT0 = P0^2; //INT0口没有唤醒指示灯sbit Normal_Work_LED = P0^3; //正常工作指示灯sbit Power_Down_Wakeup_INT0= P3^2; //外中断唤醒输入口void Delay_ms( uint time );void Normal_work(void);void Intp_init(void);void After_Powr_Down(void);//***********************************//// 软件延时 ////***********************************//void Delay_ms( uint time ){uint t; //延时时间 = (time*1003+16)us while(time--){for( t = 0; t < 82; t++ );}}//***********************************//// 正常工作指示//***********************************//void Normal_work(void){Normal_Work_LED = 1;Delay_ms(500);Normal_Work_LED = 0;Delay_ms(500);}void After_Power_Down(void){uchar i ;for( i = 0; i < 100; i++ ){P0 = 0x0f;Delay_ms(500);P0 = 0x00;Delay_ms(500);}}//***********************************//// 中断初始化 ////***********************************//void Intp_init(void){IT0 = 0; //外部中断源0为低电平触发EX0 = 1; //允许外部中断EA = 1; //开总中断}//***********************************//// 主程序 ////***********************************//void main(){uchar j = 0;uchar wakeup_counter = 0; //记录掉电次数P0 = 0x00;Chip_Start_LED = 1; //单片机开始工作Intp_init(); //外中断0初始化while(1){P2 = wakeup_counter;wakeup_counter++;for( j = 0; j < 250; j++ ){Normal_work(); //系统正常工作指示}Power_Down_Flag = 1; //系统开始进入掉电状态PCON = 0x02;_nop_();_nop_();_nop_();_nop_();After_Power_Down(); //掉电唤醒后}}//**********************************//// 中断服务//**********************************//void INT0_Service(void) interrupt 0{if( Power_Down_Flag ) //掉电唤醒状态指示 {Power_Down_Flag = 0;Power_Down_LED_INT0 = 1;while( Power_Down_Wakeup_INT0 == 0 ){_nop_(); //等待高电平}Power_Down_LED_INT0 = 0;}else //未掉电状态{N_Power_Down_LED_INT0 = 1; //不是掉电唤醒指示while( Power_Down_Wakeup_INT0 == 0 ){_nop_();}N_Power_Down_LED_INT0 = 0;}}//**************************************************************************** //// STC12C5A60S2 A/D转换模块////// 说明: STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7//// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)// ADC_RES、ADC_RESL(转换结果寄存器)//// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,再启动A/D转换// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精度A/D 转换// 若能将定时器/串行/中断系统关闭更好。
技师 单片机程序 最终版本V2

目录0 YuYin 录音专用lcd显示录音地址V1 ...........................................................................- 1 -1 DianZhiCheng led显示V1 ................................................................................................- 3 -2 DianZhiCheng lcd显示V1 ................................................................................................- 4 -3 DianZhiCheng lcd显示语音读重量值V1 .......................................................................-4 -4 ChaoShengBo led显示距离报警V1 ..............................................................................- 7 -5 ChaoShengBo lcd显示距离报警V1 ...............................................................................- 9 -6 ChaoShengBo lcd显示距离报警语音读距离V1 ...................................................... - 12 -7 MiMaSuo led显示V1 将密码写入24C02 ....................................................................- 17 -8 MiMaSuo led显示V1 .................................................................................................... - 18 -9 MiMaSuo lcd显示V1 .................................................................................................... - 22 -注:底层程序需要修改说明.............................................................................................- 26 -1 AT24C02底层程序...................................................................................................- 26 -2.4X4键盘底层程序...................................................................................................- 26 -0 YuYin 录音专用lcd显示录音地址V1#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit key0=P2^5; //录音按键sbit key1=P2^6; //放音按键sbit key2=P2^7; //音频地址+1按键uchar num; //修改音频地址累加uchar ress[2]; //显示的录音地址缓存//--------lcd显示函数声明---------------------------- 1 -void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//--------语音模块函数声明---------------------------void powerup(void);void record(unsigned char address);void play_4004(unsigned char address);//-------------------------------------------void delay(uint ii){while(ii--);}main(){powerup();init_lcd();ch_disp_any(0x98,9,"音频地址:");ress[0]=0+0x30; //使地址初值显示00ress[1]=0+0x30; //液晶字符地址从0x30往后为阿拉伯数字0 1 2 3 ……while(1){if(key0==0){delay(1000);if(key0==0){while(!key0);record(num); //录音}}if(key1==0){delay(1000);if(key1==0){while(!key1);play_4004(num); //放音}- 2 -}if(key2==0){delay(3000);if(key2==0){while(!key2);num++; //音频地址+1if(num>=13)num=0;ress[1]=num%10+0x30; //提取个位数ress[0]=num/10+0x30; //提取十位数}}ch_disp_any(0x98,9,"音频地址:");ch_disp_any(0x9d,2,ress);}}1 DianZhiCheng l ed显示V1#include<reg52.h>#define uint unsigned int#define uchar unsigned char//--------AD模拟TLC549 函数声明---------------------------unsigned char TLC549(void);//--------led显示函数声明---------------------------void DISPLAY(unsigned int x);//-------------------------------------------void main(){while(1){uint i;i=TLC549(); //读取转换后的电压值i=i*500/255; //当TCL549的AD模拟电压采集输入端2脚AIN = REF+参考电压输入端时i=255//500为最大的砝码重量500gDISPLAY(i);}- 3 -}2 DianZhiCheng lcd显示V1#include<reg52.h>#define uint unsigned int#define uchar unsigned charuint i;uchar lcd_g[3]=0;//--------AD模拟TLC549 函数声明---------------------------unsigned char TLC549(void);//--------lcd显示函数声明---------------------------void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//-------------------------------------------void main(){init_lcd();ch_disp_any(0x80,6,"电子称");ch_disp_any(0x88,12,"姓名: 某某某");ch_disp_any(0x98,13,"重量是: g");while(1){i=TLC549(); //读取转换后的电压值i=i*500/255; //当TCL549的AD模拟电压采集输入端2脚AIN = REF+参考电压输入端时i=255//500为最大的砝码重量500glcd_g[0]=i%1000/100+0x30; //提取百位数lcd_g[1]=i%100/10+0x30; //提取十位数lcd_g[2]=i%10+0x30; //提取个位数ch_disp_any(0x8c,3,lcd_g);}}3 DianZhiCheng lcd显示语音读重量值V1#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit key1=P2^7; //播放距离按键- 4 -uint i;uchar lcd_g[3]=0;uchar i1,i2,i3; //语音读数据的百十个位//--------AD模拟TLC549 函数声明---------------------------unsigned char TLC549(void);//--------LCD显示函数声明---------------------------void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//--------语音---函数声明---------------------------------------void powerup(void);void record(unsigned char address); //语音录入函数本程序未使用因此有一个警告void play_4004(unsigned char address);//-------------------------------------------void delay(uint z) //语音播放连续字节发送指令延时{uint x ,y;for(x=z;x>0;x--)for(y=121;y>0;y--);}void main(){powerup(); //语音模块上电init_lcd();ch_disp_any(0x80,6,"电子称");ch_disp_any(0x88,12,"姓名: 某某某");ch_disp_any(0x98,13,"重量是: g");while(1){i=TLC549(); //读取转换后的电压值i=i*500/255; //当TCL549的AD模拟电压采集输入端2脚AIN = REF+参考电压输入端时i=255//500为最大的砝码重量500glcd_g[0]=i%1000/100+0x30; //提取百位数lcd_g[1]=i%100/10+0x30; //提取十位数lcd_g[2]=i%10+0x30; //提取个位数ch_disp_any(0x8c,3,lcd_g);if(key1==0){- 5 -i1=lcd_g[0]-0x30; //语音读取重量数据i2=lcd_g[1]-0x30;i3=lcd_g[2]-0x30;if(i1!=0&&i2!=0&&i3!=0) //百位十位个位都不为零读数方式{play_4004(i1);delay(50); //延时保证数据再次发送稳定play_4004(10);delay(50);play_4004(i2);delay(50);play_4004(11);delay(50);play_4004(i3);delay(50);play_4004(12);}if(i1==0&&i2!=0&&i3!=0) //百位为零十位个位都不为零读数方式{play_4004(i2);delay(50);play_4004(11);delay(50);play_4004(i3);delay(50);play_4004(12);}if(i1==0&&i2==0&&i3!=0) //百位为零十位为零个位不为零读数方式{play_4004(i3);delay(50);play_4004(12);}if(i1!=0&&i2==0&&i3!=0) //百位不为零十位为零个位不为零读数方式{play_4004(i1);delay(50);play_4004(10);- 6 -delay(50);play_4004(i2);delay(50);play_4004(0);delay(50);play_4004(i3);delay(50);play_4004(12);}}}}4 ChaoShengBo led显示距离报警V1#include<reg52.h>#include<math.h>#define uint unsigned int#define uchar unsigned charsbit send=P3^0; //超声波发送40kHz信号引脚sbit beep=P3^1; //蜂鸣器引脚定义//外部中断0固定为单片机P3.2引脚不需要定义为接收超声波反馈信息引脚bit flag=0; //位定义作为有中断时计算距离用标志flag=1时为有中断产生uint time_H=0,time_L=0; //缓存计数器的计数时间高8位底八位uchar count=0; //发送超声波脉冲计数uchar display_lcd[3]; //lcd显示距离缓存uint value; //最终计算的距离值//--------lde显示函数声明---------------------------void DISPLAY(unsigned int x);//-------------------------------------------void initTimer(void){TMOD=0x21; //T1为8位自动重装模式,T0为16位定时器TH0=0; //定时器T0初值用于计时超声波间断发送时间间隔TL0=0;TH1=0xf3; //定时器T1初值用于产生40kHz超声波发送探头所需信号TL1=0xf3;- 7 -}//--------------------------------------void timer0(void) interrupt 1 //T0中断,65ms中断一次即:重新发送超声波信号并且从0开始计时{TR1=1; //当定时器定时时间到时打开定时器1 发送超生波同时从0开始计时}//--------------------------------------void timer1(void) interrupt 3 //T1中断,发超声波用{send=~send; //超声波发送引脚count++; //超声波发送脉冲个数计数if(count>4) //计数个数到{count=0; //清零脉冲发送个数为下次发送准备TR1=0; //关闭定时器1 即关闭自身不在发送40kHz信号EX0=1; //打开外部中断等待超声波接收探头的响应信号}}//--------------------------------------void int0(void) interrupt 0 //接受中断{TR0=0; //关定时器T0 停止计时EX0=0; //关接受中断EA=0; //关闭总中断不在响应任何中断time_H=TH0; //读取定时器T0的计时时间即:超声波从发送到接受的响应信号的时间time_L=TL0;TR0=1; //本次超声波发送到接收时间读取完成开定时器T0开始计时开始下一个轮回EA=1; //打开总中断flag=1; //置计算距离表示有效}//----------------------------------------void main(){initTimer(); //定时器配置初始化TR0=1; //开启定时器T0- 8 -ET0=1; //允许定时器T0中断计时超声波发送到接收到回响信号时间//允许定时器T0中断未收到回响信号重复发送超声波信号间隔时间ET1=1; //允许定时器T1中断产生40kHz超声波发送信号EA=1; //允许总中断while(1){if(flag==1) //中断表示有效重新计算距离{time_H<<=8; //读取的定时器1 计时时间的高八位value=time_H+time_L; //第八位与高八位相加合成一个十六位电压值value=value*17/1000; //设S为测量距离,T为往返时间差,超声波的传播速度为V,则有: V = T/2 * S//value = ((value(单位是是us)* 0.000 001)s / 2) * 340m/s//value = ((value(单位是是us)* 0.000 001)s / 2) * (340 * 100)m/s//value = 【((value(单位是是us)* 0.001) / 2) * 34】cm 注:单位转换位cm//value = 【((value * (34 / 2)) * 1000 】cm 注:分子分母同时乘以1000 转换位整数计算flag=0; //本次距离计算处理完成清楚标志位}DISPLAY(value); //数码管显示距离if(value<10) //报警距离设定beep=0;elsebeep=1;}}5 ChaoShengBo lcd显示距离报警V1#include<reg52.h>#include<math.h>#define uint unsigned int#define uchar unsigned charsbit send=P3^0; //超声波发送40kHz信号引脚sbit beep=P3^1; //蜂鸣器引脚定义//外部中断0固定为单片机P3.2引脚不需要定义为接收超声波反馈信息引脚bit flag=0; //位定义作为有中断时计算距离用标志flag=1时为有中断产生- 9 -uint time_H=0,time_L=0; //缓存计数器的计数时间高8位底八位uchar count=0; //发送超声波脉冲计数uchar display_lcd[3]; //lcd显示距离缓存uint value; //最终计算的距离值//--------LCD显示函数声明---------------------------void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//-------------------------------------------void delay_m(){int a,b;for(a=400;a>0;a--);for(b=400;b>0;b--);}void initTimer(void){TMOD=0x21; //T1为8位自动重装模式,T0为16位定时器TH0=0; //定时器T0初值用于计时超声波间断发送时间间隔TL0=0;TH1=0xf3; //定时器T1初值用于产生40kHz超声波发送探头所需信号TL1=0xf3;}//--------------------------------------void timer0(void) interrupt 1 //T0中断,65ms中断一次即:重新发送超声波信号并且从0开始计时{TR1=1; //当定时器定时时间到时打开定时器1 发送超生波同时从0开始计时}//--------------------------------------void timer1(void) interrupt 3 //T1中断,发超声波用{send=~send; //超声波发送引脚count++; //超声波发送脉冲个数计数if(count>4) //计数个数到{count=0; //清零脉冲发送个数为下次发送准备TR1=0; //关闭定时器1 即关闭自身不在发送40kHz信号EX0=1; //打开外部中断等待超声波接收探头的响应信号- 10 -}}//--------------------------------------void int0(void) interrupt 0 //接受中断{TR0=0; //关定时器T0 停止计时EX0=0; //关接受中断EA=0; //关闭总中断不在响应任何中断time_H=TH0; //读取定时器T0的计时时间即:超声波从发送到接受的响应信号的时间time_L=TL0;TR0=1; //本次超声波发送到接收时间读取完成开定时器T0开始计时开始下一个轮回EA=1; //打开总中断flag=1; //置计算距离表示有效}//----------------------------------------void main(){initTimer(); //定时器配置初始化TR0=1; //开启定时器T0ET0=1; //允许定时器T0中断计时超声波发送到接收到回响信号时间//允许定时器T0中断未收到回响信号重复发送超声波信号间隔时间ET1=1; //允许定时器T1中断产生40kHz超声波发送信号EA=1; //允许总中断init_lcd(); //初始化led显示ch_disp_any(0x81,12,"超声波测距仪"); //0x81为汉字在lcd上显示的起始位置(芯片资料的lcd手册中可以查到)//12为显示的字节数(一个汉字为2个字节)ch_disp_any(0x90,10,"姓名: 某某");ch_disp_any(0x88,12,"距离:cm");while(1){if(flag==1) //中断表示有效重新计算距离{- 11 -time_H<<=8; //读取的定时器1 计时时间的高八位value=time_H+time_L; //第八位与高八位相加合成一个十六位电压值value=value*17/1000; //设S为测量距离,T为往返时间差,超声波的传播速度为V,则有: V = T/2 * S//value = ((value(单位是是us)* 0.000 001)s / 2) * 340m/s//value = ((value(单位是是us)* 0.000 001)s / 2) * (340 * 100)m/s//value = 【((value(单位是是us)* 0.001) / 2) * 34】cm 注:单位转换位cm//value = 【((value * (34 / 2)) * 1000 】cm 注:分子分母同时乘以1000 转换位整数计算flag=0; //本次距离计算处理完成清楚标志位}delay_m(); //延时降低lcd的刷新频率display_lcd[2]=0x30+value%10; //提取个位数display_lcd[1]=0x30+value%100/10; //提取十位数display_lcd[0]=0x30+value%1000/100; //提取百位数ch_disp_any(0x8B,3,display_lcd); //更新显示if(value<10) //报警距离设定beep=0;elsebeep=1;}}6 ChaoShengBo lcd显示距离报警语音读距离V1#include<reg52.h>#include<math.h>#define uint unsigned int#define uchar unsigned charsbit key1=P2^7; //播放距离按键sbit send=P3^0; //超声波发送40kHz信号引脚sbit beep=P3^1; //蜂鸣器引脚定义//外部中断0固定为单片机P3.2引脚不需要定义为接收超声波反馈信息引脚bit flag=0; //位定义作为有中断时计算距离用标志flag=1时为有中断产生uint time_H=0,time_L=0; //缓存计数器的计数时间高8位底八位uchar count=0; //发送超声波脉冲计数uchar display_lcd[3]; //lcd显示距离缓存- 12 -uchar value; //最终计算的距离值uchar i1,i2,i3; //语音读数据的百十个位//--------LCD显示函数声明---------------------------void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//--------语音---函数声明---------------------------------------void powerup(void);void record(unsigned char address); //语音录入函数本程序未使用因此有一个警告void play_4004(unsigned char address);//-------------------------------------------void delay_m() //lcd刷新显示延时{int a,b;for(a=400;a>0;a--);for(b=400;b>0;b--);}void delay(uint z) //语音播放连续字节发送指令延时{uint x ,y;for(x=z;x>0;x--)for(y=121;y>0;y--);}void initTimer(void){TMOD=0x21; //T1为8位自动重装模式,T0为16位定时器TH0=0; //定时器T0初值用于计时超声波间断发送时间间隔TL0=0;TH1=0xf3; //定时器T1初值用于产生40kHz超声波发送探头所需信号TL1=0xf3;}//--------------------------------------void timer0(void) interrupt 1 //T0中断,65ms中断一次即:重新发送超声波信号并且从0开始计时{TR1=1; //当定时器定时时间到时打开定时器1 发送超生波同时从0开始计时}//--------------------------------------void timer1(void) interrupt 3 //T1中断,发超声波用{- 13 -send=~send; //超声波发送引脚count++; //超声波发送脉冲个数计数if(count>4) //计数个数到{count=0; //清零脉冲发送个数为下次发送准备TR1=0; //关闭定时器1 即关闭自身不在发送40kHz信号EX0=1; //打开外部中断等待超声波接收探头的响应信号}}//--------------------------------------void int0(void) interrupt 0 //接受中断{TR0=0; //关定时器T0 停止计时EX0=0; //关接受中断EA=0; //关闭总中断不在响应任何中断time_H=TH0; //读取定时器T0的计时时间即:超声波从发送到接受的响应信号的时间time_L=TL0;TR0=1; //本次超声波发送到接收时间读取完成开定时器T0开始计时开始下一个轮回EA=1; //打开总中断flag=1; //置计算距离表示有效}//----------------------------------------void main(){powerup(); //语音模块上电initTimer(); //定时器配置初始化TR0=1; //开启定时器T0ET0=1; //允许定时器T0中断计时超声波发送到接收到回响信号时间//允许定时器T0中断未收到回响信号重复发送超声波信号间隔时间ET1=1; //允许定时器T1中断产生40kHz超声波发送信号EA=1; //允许总中断init_lcd(); //初始化led显示ch_disp_any(0x81,12,"超声波测距仪"); //0x81为汉字在lcd上显示的起始位置(芯片资料的lcd手册中可以查到)- 14 -//12为显示的字节数(一个汉字为2个字节)ch_disp_any(0x90,10,"姓名: 某某");ch_disp_any(0x88,12,"距离:cm");while(1){if(flag==1) //中断表示有效重新计算距离{time_H<<=8; //读取的定时器1 计时时间的高八位value=time_H+time_L; //第八位与高八位相加合成一个十六位电压值value=value*17/1000; //设S为测量距离,T为往返时间差,超声波的传播速度为V,则有: V = T/2 * S//value = ((value(单位是是us)* 0.000 001)s / 2) * 340m/s//value = ((value(单位是是us)* 0.000 001)s / 2) * (340 * 100)m/s//value = 【((value(单位是是us)* 0.001) / 2) * 34】cm 注:单位转换位cm//value = 【((value * (34 / 2)) * 1000 】cm 注:分子分母同时乘以1000 转换位整数计算flag=0; //本次距离计算处理完成清楚标志位}delay_m(); //延时降低lcd的刷新频率display_lcd[2]=0x30+value%10; //提取个位数display_lcd[1]=0x30+value%100/10; //提取十位数display_lcd[0]=0x30+value%1000/100; //提取百位数ch_disp_any(0x8B,3,display_lcd); //更新显示if(value<10) //报警距离设定beep=0;elsebeep=1;if(key1==0){i1=display_lcd[0]-0x30; //语音读取距离数据i2=display_lcd[1]-0x30;i3=display_lcd[2]-0x30;if(i1!=0&&i2!=0&&i3!=0) //百位十位个位都不为零读数方式{play_4004(i1);delay(50); //延时保证数据再次发送稳定- 15 -play_4004(10);delay(50);play_4004(i2);delay(50);play_4004(11);delay(50);play_4004(i3);delay(50);play_4004(12);}if(i1==0&&i2!=0&&i3!=0) //百位为零十位个位都不为零读数方式{play_4004(i2);delay(50);play_4004(11);delay(50);play_4004(i3);delay(50);play_4004(12);}if(i1==0&&i2==0&&i3!=0) //百位为零十位为零个位不为零读数方式{play_4004(i3);delay(50);play_4004(12);}if(i1!=0&&i2==0&&i3!=0) //百位不为零十位为零个位不为零读数方式{play_4004(i1);delay(50);play_4004(10);delay(50);play_4004(i2);delay(50);play_4004(0);delay(50);play_4004(i3);delay(50);play_4004(12);}- 16 -}}}7 MiMaSuo led显示V1 将密码写入24C02/****************************************************************************** **************************向AT24C02写入密码主程序说明:led数码管显示按键说明:无按键在程序中设定功能说明:当密码设定成功时数码管显示你所设定的密码当密码设定失败是数码管显示数字 5******************************************************************************* ****************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar num;uint buffer,buffer_H,buffer_L;//--------led数码管显示函数声明---------------------------void DISPLAY(unsigned int x);//--------AT24C02 函数声明---------------------------void WRITE_IIC(unsigned char ADDR_IIC2,unsigned char DATA_IIC2);unsigned char READ_IIC(unsigned char ADDR_IIC2);//-------------------------------------------void delay(uint t){while(t--);}void main(){while(1){if(num==0){num=1; //停止密码写入/*当你要设定的密码为**************1234时**********************/WRITE_IIC(0x00,12); /*写入24C02数据*****设定密码的高两位请修改这里******为12*/delay(1000);WRITE_IIC(0x01,34); /*写入24C02数据*****设定密码的底两位请修改这里- 17 -******为34*/}buffer_H=READ_IIC(0x00); //读取该地址的数据delay(1000);buffer_H=buffer_H*100;buffer_L=READ_IIC(0x01); //读取该地址的数据delay(1000);buffer=buffer_H+buffer_L;if(1234==buffer) /*修改为1234修改为你要设定的密码****例如为****1234时********/DISPLAY(buffer); //密码设定成功显示设定的密码else{DISPLAY(5); //密码设定失败num=0; //密码写入失败再次写入}}}8 MiMaSuo led显示V1/****************************************************************************** **************************密码锁主程序说明:LDE数码管显示LED灯指示密码输入正确与否按键说明:4X4键盘的0 1 ……8 9 为密码输入按键|| 4X4键盘按键10为复位键清空从新输入密码显示功能说明:当输入密码正确时程序自动确认LED指示灯点亮当4位密码输入完成LED指示灯未点亮则说明本次密码输入错误当再次按下任意数字键时进入下一次密码输入状态当第三次输入四位密码时未能成功点亮LED 蜂鸣器响三次密码错误报警当按下4X4键盘按键10 复位解除报警进入下一次密码输入轮回LED灯显示J2 LED1 接P3.6蜂鸣器J1 Buzzer 接P3.1******************************************************************************* ****************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit ok=P3^0; //密码输入正确指示接ledsbit beep=P3^1; //蜂鸣器引脚定义报警- 18 -uchar num,count; //密码输入次数计数|| 密码输入位数计数uint buffer_mima,buffer_key,display_key; //缓存读取24C02内部存存储的密码|| 读取的键值|| 显示的键值uint mima1,mima2,mima3,mima4; //缓存第4次输入密码千位百位十位个位|| 缓存第3次输入密码的千位百位十位|| 缓存第2次输入密码的千位百位|| 缓存第1次输入密码的最高位(千位)bit flag_beep; //报警状态标志uint buffer_H,buffer_L; //读取24C02中存储的密码的高低位//--------lde数码管显示函数声明---------------------------void DISPLAY(unsigned int x);//--------24C04数据存储函数声明---------------------------void WRITE_IIC(unsigned char ADDR_IIC2,unsigned char DATA_IIC2);unsigned char READ_IIC(unsigned char ADDR_IIC2);//--------4X4键盘函数声明---------------------------unsigned char Keyboard(void);//-------------------------------------------void delay(uint t){while(t--);}void initTimer(void){TMOD=0x1;TH0=0xb1;TL0=0xe0;}void timer0(void) interrupt 1{TH0=0xb1;TL0=0xe0;DISPLAY(display_key); //数码管扫描(数码管动态扫描放在主程序中时当按键按下数码管不能正常扫描)} //因此键数码管扫描放在定时器中当按键按下时保证显示正常void main(){initTimer();TR0=1;ET0=1;- 19 -EA=1;buffer_H=READ_IIC(0x00); //读取该地址的数据密码的千位百位delay(1000);buffer_H=buffer_H*100; //该字节地址数据位密码的千位百位放大100倍准备与十位个位合并buffer_L=READ_IIC(0x01); //读取该地址的数据密码的十位个位delay(1000);buffer_mima=buffer_H+buffer_L; //合并密码的千位百位与十位个位存入密码缓存while(1){buffer_key=Keyboard(); //读取4X4键盘的键值存入buffer_key按键值缓存if(16!=buffer_key){if(buffer_key<10) //当输入的键值小于10的时候认为是密码输入{count++; //密码输入的位数if(count>=5) //当第五位密码输入{count=1; //置密码位数为最高位输入}if(count<=4){switch(count) //密码千位百位十位个位识别{case 1:mima4=buffer_key;display_key=mima4; //显示密码千位break;case 2:mima3=buffer_key+mima4*10;display_key=mima3; //显示密码千位百位break;case 3:mima2=buffer_key+mima3*10;display_key=mima2; //显示密码千位百位个位break;case 4:mima1=buffer_key+mima2*10;display_key=mima1; //显示密码千位百位- 20 -个位个位break;}}if(count==4) //已输入4位密码进行密码识别{num++; //密码识别次数+1if(buffer_mima==mima1&&flag_beep==0) //缓存的密码与输入的密码比较&& 未到识别次数限制{ok=0; //密码正确标识num=0; //清零密码识别次数}else{if(num>=3) //密码输入错误次数判别{beep=0; //已到次数限制报警flag_beep=1; //停止密码再次判别}}}}if(10==buffer_key) //4X4键盘按键10 清零复位键{count=0; //清零按键位数计数mima1=0; //清零位数显示mima2=0;mima3=0;mima4=0;num=0; //清零密码识别次数ok=1; //清零密码正确标识beep=1; //清零报警flag_beep=0; //清零密码禁止识别标识display_key=0; //清零显示}}}}- 21 -9 MiMaSuo lcd显示V1/****************************************************************************** **************************密码锁主程序说明:LCE液晶显示按键说明:4X4键盘的0 1 ……8 9 为密码输入按键|| 4X4键盘按键10为复位键清空从新输入密码显示功能说明:当输入密码正确时程序自动确认液晶显示正确当4位密码输入完成液晶显示错误当再次按下任意数字键时进入下一次密码输入状态当第三次输入四位密码时蜂鸣器响三次密码错误报警并且4X4键盘的0 1 ……8 9 按键被锁定当按下4X4键盘按键10 复位解除报警解除被锁定按键进入下一次密码输入轮回蜂鸣器J1 Buzzer 接P3.1******************************************************************************* ****************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit beep=P3^1; //蜂鸣器引脚定义报警uchar num,count; //密码输入次数计数|| 密码输入位数计数uint buffer_mima,buffer_key,display_key; //缓存读取24C02内部存存储的密码|| 读取的键值|| 显示的键值uint mima1,mima2,mima3,mima4; //缓存第4次输入密码千位百位十位个位|| 缓存第3次输入密码的千位百位十位|| 缓存第2次输入密码的千位百位|| 缓存第1次输入密码的最高位(千位)bit flag_beep; //报警状态标志uint buffer_H,buffer_L; //读取24C02中存储的密码的高低位uchar lcd_display[4]=0;//--------LCD显示函数声明---------------------------void init_lcd(void);void ch_disp_any (unsigned char add, unsigned char num, unsigned char *chn);//--------24C04数据存储函数声明---------------------------void WRITE_IIC(unsigned char ADDR_IIC2,unsigned char DATA_IIC2);unsigned char READ_IIC(unsigned char ADDR_IIC2);//--------4X4键盘函数声明---------------------------unsigned char Keyboard(void);//-------------------------------------------- 22 -void delay(uint t){while(t--);}void main(){init_lcd();ch_disp_any(0x80,16,"密码锁**应电1014");ch_disp_any(0x90,14,"姓名: 某某某");ch_disp_any(0x88,12,"密码: ");ch_disp_any(0x98,14,"密码识别: ");buffer_H=READ_IIC(0x00); //读取该地址的数据密码的千位百位delay(1000);buffer_H=buffer_H*100; //该字节地址数据位密码的千位百位放大100倍准备与十位个位合并buffer_L=READ_IIC(0x01); //读取该地址的数据密码的十位个位delay(1000);buffer_mima=buffer_H+buffer_L; //合并密码的千位百位与十位个位存入密码缓存while(1){buffer_key=Keyboard(); //读取4X4键盘的键值存入buffer_key按键值缓存if(16!=buffer_key){if(buffer_key<10&&flag_beep==0) //当输入的键值小于10的时候认为是密码输入&& 未报警即:未到识别次数限制{count++; //密码输入的位数if(count>=5) //当第五位密码输入{count=1; //置密码位数为最高位输入ch_disp_any(0x9D,4," "); //4个空格密码清除密码正确|| 错误显示ch_disp_any(0x8B,8," "); //8个空格清除输入显示着的密码}if(count<=4){- 23 -switch(count) //密码千位百位十位个位识别{case 1: mima4=buffer_key;lcd_display[0]=buffer_key+0x30; //显示密码千位break;case 2: mima3=buffer_key+mima4*10;lcd_display[0]=buffer_key+0x30; //显示密码千位break;case 3: mima2=buffer_key+mima3*10;lcd_display[0]=buffer_key+0x30; //显示密码千位break;case 4: mima1=buffer_key+mima2*10;lcd_display[0]=buffer_key+0x30; //显示密码千位break;}if(count==1) ch_disp_any(0x8B,1,lcd_display); //将千位的密码显示到千位位置if(count==2) ch_disp_any(0x8C,1,lcd_display); //将百位的密码显示到百位位置if(count==3) ch_disp_any(0x8D,1,lcd_display); //将十位的密码显示到十位位置if(count==4) ch_disp_any(0x8E,1,lcd_display); //将个位的密码显示到个位位置}if(count==4) //已输入4位密码进行密码识别{num++; //密码识别次数+1if(buffer_mima==mima1) //缓存的密码与输入的密码比较{num=0; //清零密码识别次数ch_disp_any(0x9D,4,"成功"); //当汉字写‘确认’时两个汉字时显示出错}else{if(num>=3) //密码输入错误次数- 24 -判别{beep=0; //已到次数限制报警flag_beep=1; //停止密码再次判别ch_disp_any(0x9D,4,"报警");}elsech_disp_any(0x9D,4,"错误");}}}if(10==buffer_key) //4X4键盘按键10 清零复位键{count=0; //清零按键位数计数mima1=0; //清零位数显示mima2=0;mima3=0;mima4=0;num=0; //清零密码识别次数beep=1; //清零报警flag_beep=0; //清零密码禁止识别标识display_key=0; //清零显示ch_disp_any(0x9D,4," "); //4个空格密码清除密码正确|| 错误显示ch_disp_any(0x8B,8," "); //8个空格清除输入显示着的密码}}}}- 25 -注:底层程序需要修改说明1 AT24C02底层程序修改原因:按底层程序接线,将无法实现对AT24C02的读写操作!修改理由:修改前如图一所示,图一方框中程序VSDA定义为P3.6、VSCL定义为P3.7而程序说明中,如图一圆圈内容所示SCL接P3.6、SDA接P3.7显然与程序设定相反,所以请修改程序,如图二中圆圈所示,将程序注释中SCL接P3.7、SDA接P3.6。
单片机c语言代码及应用

单片机c语言代码及应用单片机是一种集成了中央处理器、内存和各种外设接口的微型计算机。
它广泛应用于家用电器、工控设备、汽车电子等各个领域。
C语言是单片机最常用的编程语言,它具有代码简洁、运行效率高的特点。
下面我将为你介绍一些单片机C 语言代码的应用。
首先,我们可以使用C语言编写一个LED闪烁的程序。
这个程序可以通过单片机的GPIO口控制LED的亮灭,实现LED的闪烁效果。
以下是一个简单的LED 闪烁的C语言代码:c#include <reg51.h>void delay(unsigned int count) 延时函数{while (count);}int main(){while (1) {P1 = 0xFF; 点亮LEDdelay(50000);P1 = 0x00; 熄灭LEDdelay(50000);}return 0;}上面的代码中,我们首先定义了一个延时函数`delay`,它通过循环来实现延时。
然后在`main`函数中,通过控制P1口的电平来控制LED的亮灭,并调用延时函数来控制闪烁的时间间隔。
这样就实现了一个简单的LED闪烁程序。
另外一个常见的应用是通过单片机控制液晶显示屏。
液晶显示屏可以用来显示各种信息,比如温度、湿度、时间等。
以下是一个使用单片机控制液晶显示屏显示字符串的程序:c#include <reg51.h>#define LCD_DATA P0 数据口sbit LCD_RS = P1^0; RS口sbit LCD_RW = P1^1; RW口sbit LCD_EN = P1^2; EN口void delay(unsigned int count) 延时函数{while (count);}void lcd_write_command(unsigned char command) 写指令{LCD_RS = 0; 设置为指令模式LCD_RW = 0; 设置为写入模式LCD_DATA = command;LCD_EN = 1;delay(5);LCD_EN = 0;}void lcd_write_data(unsigned char data) 写数据{LCD_RS = 1; 设置为数据模式LCD_RW = 0; 设置为写入模式LCD_DATA = data;LCD_EN = 1;delay(5);LCD_EN = 0;}void lcd_init() LCD初始化{lcd_write_command(0x38); 初始化显示模式lcd_write_command(0x08); 关闭显示lcd_write_command(0x01); 清屏lcd_write_command(0x06); 设置光标移动方向lcd_write_command(0x0C); 显示开启}void lcd_display_string(unsigned char x, unsigned char y, unsigned char *string) 在指定位置显示字符串{unsigned char address;if (y == 0) {address = 0x80 + x;} else {address = 0xC0 + x;}lcd_write_command(address);while (*string) {lcd_write_data(*string++);}}int main(){unsigned char string[] = "Hello, World!";lcd_init(); LCD初始化lcd_display_string(0, 0, string); 在第一行显示字符串while (1);return 0;}上面的代码中,我们首先定义了一些宏和端口变量,用来控制液晶显示屏。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.输出方波(周期2ms)
ORG 0000H
LJMP MAIN
ORG OOOBH
LJMP SER
MAIN:MOV SP,#50H
MOV TMOD,#00H;选择工作方式0
MOV TH0,#1CH
MOV TL0,#18H
SETB EA
SETB ET0
SETB TR0
HERE:SJMP $
SER:CPL P1.0
MOV TH0,#1CH
MOV TL0,#18H
RETI
END
二.输出锯齿波(占空50us)用器件DAC082来实现锯齿波
ORG 0000H
START:MOV DPTR,#7FFFH
STEP1:MOV A, #00H
STEP2:MOVX @DPTR,A
INC A
CJNE A,#32H,STEP2
AJMP STEP1
三.定时器流水灯(定时50ms)灯是共阳的
ORG 0000H
LJMP MAIN
ORG OOOBH
LJMP SER
MAIN:MOV SP,#50H
MOV TMOD,#01H
MOV TH0,#0BH
MOV TL0,#C3H
MOV A,#0FEH
MOV P1,A
SETB EA
SETB ET0
SETB TR0
HERE:SJMP $
SER:RL A
MOV P1,A
MOV TH0,#1CH
MOV TL0,#18H
RETI
END
四.数码管静态显示(共阴型)
C语言编程:依次显示0、1…….7;这里的C语言和下面图片没有关系,只是书本里面的。
#include "reg51.h"
Void main(void)
{
Uchar code LEDValue[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};共阴
UcharI;
TI=0;
For(i=0;i<8;i++){
SBUF=LEDValue[7-i];
While(TI==0);TI=0;
}
}
汇编语言编程:循环显示0-9;仅做参考:(数码管为共阳型)仿
真可以实现!
;数据存放
ORG 0100
TABLE: DB 0C0h,0F9H,0A4H,0b0H,99H,92H,82H,0F8H,80H,90H ;数据表:共阳数码管0-9 ORG 0000H ;程序开始
LJMP MAIN
ORG 0200H
MAIN: CLR P2.0 ;选择数码管D第一位,静态显示,P1口输出表数据显示,不需要刷新,(可选择其它数码管或两位以上)具体看你怎么选择多少位数码管。
M1: MOV R7,#10 ;循环显示0-9
MOV DPTR,#TABLE
M2: CLR A
MOVC A,@A+DPTR ;查表输出定义好的数码管段值到P0口,显示相应的0-9
MOV P1,A
LCALL DELAY ;调用延时
INC DPTR;开始循环显示0、1、2、 (9)
DJNZ R7,M2
LJMP M1
DELAY: MOV R5,#255 ;此次延时子程序
D1: MOV R6,#255
DJNZ R6,$
DJNZ R5,D1
RET
END
五.数码管动态显示(共阴型)动态显示区别:可以选择哪个位的数码管工作,且在数码管上的各个位显示自己想输出的数字。
(此程序为8位数码管)
#include "reg51.h"
Extern void delay_1ms(void);
Void display(void)
{
Uchar code LEDValue[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07}
UcharI;
TI=0;
For(i=0;i<8;i++){
P0=LEDValue[i];
P2=[i];
Delay_1ms();
}
Void delay_1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
}
}
六.8255扩展延时流水灯
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:MOV DPTR,#7FFFH;8255的地址
MOV A,#80H;选择8255全部为输出方式
MOVX @DPTR,A
M1:MOV DPTR,#7FFCH;选择8255的A口
MOV A,#0FEH;因为流水灯是共阳的,先亮最低位MOVX @DPTR,A
ACALL DELAY
M2:RL A;循环左移,形成流水
MOVX @DPTR,A
ACALL DELAY
JMP M2
DELAY: MOV R5,#255 ;延时子程序
D1: MOV R6,#255
DJNZ R6,$
DJNZ R5,D1
RET
END。