以计算机相关专业角度学习单片机

2021-05-27 23:45:59 浏览
单片机针脚

C51系列单片机有4*8=32个针脚。p0,p1,p2,p3三个寄存器,每个寄存器大小为8位,干什么用的呢?这些针脚只有两种状态即0(低电平)与1(高电平)。我们可以通过写程序,通过编译器生成CPU的一条条指令,烧录到里面去。我们通过对针脚的高低电平进行逻辑判断,再通过一系列状态对针脚状态做出改变。 举一个例子,比如查看某个针脚状态,读到了1,可以假想(另一个针脚上连着电机),我们改变针脚状态,让电机转起来。

C51程序界的Hello World

#include<REGX52.H>voidmain(){ P2=0xFE;//1111 1110while(1){ }}

我们通过控制寄存器存储的值,来改变针脚的状态,后面为什么有一个while(1){}呢,单片机程序与我们现在windows、Linux C程序不同,电脑上的程序运行一次就结束了。单片机如果程序运行完后、它会从头再来。所以我们让单片机卡死在哪里就好了。

LED灯闪烁实现

怎样实现延时呢?没错我们可以暴力解决,让它运行一段循环不就行了嘛。我们可以使用stc-isp软件来生成延时代码片段。我们要知道,晶振就像一个定时的东西,每隔一个固定的时间片段就会发出脉冲信号,让我们的单片机CPU指令,一条条执行(形象地描述,原理太复杂了,恐怕要读一整本计算机组成原理)

#include<REGX52.H>#include<INTRINS.H>voidDelay500ms()//@12.000MHz{ unsignedchar i, j, k;_nop_(); i =4; j =205; k =187;do{ do{ while(--k);}while(--j);}while(--i);}voidmain(){ while(1){ P2=0xFE;//1111 1110Delay500ms(); P2=0xFF;//1111 1111Delay500ms();}}

我们改变的个针脚的状态,交替执行,转态变化 0__1__0__1__0__1…,这样不就闪烁起来了吗。

LED流水灯实现

流水灯这不过,是一排灯按照按顺序点亮,灭掉,下一个点亮,灭掉…而已。我们按一定的逻辑来控制一个寄存器的位的状态就好了。

#include<REGX52.H>#include<INTRINS.H>voidDelay500ms()//@12.000MHz{ unsignedchar i, j, k;_nop_(); i =4; j =205; k =187;do{ do{ while(--k);}while(--j);}while(--i);}voidmain(){ while(1){ P2=0xFE;//1111 1110Delay500ms(); P2=0xFD;//1111 1101Delay500ms(); P2=0xFB;//1111 1011Delay500ms(); P2=0xF7;//1111 0111Delay500ms(); P2=0xEF;//1110 1111Delay500ms(); P2=0xDF;//1101 1111Delay500ms(); P2=0xBF;//1011 1111Delay500ms(); P2=0x7F;//0111 1111Delay500ms();}}

虽然这是一种傻瓜式流水灯,但我们能实现功能就好了。就像做实物一样,不管用了什么技术,就像有一个网站,java做服务端,C++做服务端。做为一个使用者,谁会没事关注这些东西呢。

延时函数可复用

我们不能需要用到多长时间的延时,都去创建一个函数吧,为何不把延时函数加个参数,来实现呢

#include<REGX52.H>voidDelay1ms(unsignedint xms);//@12.000MHzvoidmain(){ while(1){ P2=0xFE;//1111 1110Delay1ms(1000); P2=0xFD;//1111 1101Delay1ms(1000); P2=0xFB;//1111 1011Delay1ms(100); P2=0xF7;//1111 0111Delay1ms(100); P2=0xEF;//1110 1111Delay1ms(100); P2=0xDF;//1101 1111Delay1ms(100); P2=0xBF;//1011 1111Delay1ms(100); P2=0x7F;//0111 1111Delay1ms(100);}}voidDelay1ms(unsignedint xms)//@12.000MHz{ unsignedchar i, j;while(xms){ i =2; j =239;do{ while(--j);}while(--i); xms--;}}

使用按键

如果一个开关一边接到了针脚上,另一端接上1(高电平),当我们地的开关闭合时,那么针脚状态就是1,开关断开,则是0 ,我们可以去检测针脚状态来进行逻辑控制

#include<REGX52.H>voidmain(){ while(1){ if(P3_1==|| P3_0==)//如果K1按键或K2按键按下{ P2_0=;//LED1输出0,点亮}else{ P2_0=1;//LED1输出1,熄灭}}}

使用按键保存状态

#include<REGX52.H>voidDelay(unsignedint xms){ unsignedchar i, j;while(xms){ i =2; j =239;do{ while(--j);}while(--i); xms--;}}voidmain(){ while(1){ if(P3_1==)//如果K1按键按下{ /* 1\ /1 \ / \ / 0\----/0 */Delay(20);//消除下坡上坡影响while(P3_1==);//松手检测Delay(20);//延时消抖 P2_0=~P2_0;//LED1取反}}}

利用左移右移

左移:右边补0,例:00000001<<3 -> 00000010;按位左移运算符。左操作数按位左移右操作数指定的位数(在低位补 0)。左移运算符,num << 1,相当于 num 乘以 2(每左移一位就相当于乘以一个 2)。按位右移运算符。左操作数按位右移右操作数指定的位数(如果该数为正数,则高位补 0 ,若为负数,则高位补 1)。右移运算符,num >> 1,相当于 num 除以 2(每右移一位相当于除以一个 2)。

#include<REGX52.H>voidDelay(unsignedint xms);unsignedchar LEDNum;voidmain(){ P2=~0x01;//上电默认LED1点亮while(1){ if(P3_1==)//如果K1按键按下{ Delay(20);while(P3_1==);Delay(20); LEDNum++;//LEDNum自增if(LEDNum>=8)//限制LEDNum自增范围 LEDNum=; P2=~(0x01<<LEDNum);//LED的第LEDNum位点亮}if(P3_0==)//如果K2按键按下{ Delay(20);while(P3_0==);Delay(20);if(LEDNum==)//LEDNum减到0后变为7 LEDNum=7;else//LEDNum未减到0,自减 LEDNum--; P2=~(0x01<<LEDNum);//LED的第LEDNum位点亮}}}voidDelay(unsignedint xms){ unsignedchar i, j;while(xms--){ i =2; j =239;do{ while(--j);}while(--i);}}


文章标签: 学习单片机

本文链接地址: 以计算机相关专业角度学习单片机:
联系信息:单片机疑难问题咨询:方先生 手机:15328075932 QQ:67828115

版权声明 本文部分文字和图片来源于互联网,如有侵犯您的权利请发送内容至:173323810@qq.com,我们将立即删除!