完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
本人为软件工程专业,接触计算机硬件学习较少,以一个嵌入式非专业角度,入门学习。对于一个要求红黑树都要能敲出来的专业,对于这种面向寄存器编程,是比较简单的,大家可以很快入门(写代码而言,想外设学习,自己组装硬件还学专业地学习电子相关知识)如有错误请见谅。使用普中51-单核-A2学习。本学习笔记适合人员:计算机相关专业、或者有熟练的C语言编程学习经历的勇士!
单片机针脚 C51系列单片机有4*8=32个针脚。p0,p1,p2,p3四个寄存器,每个寄存器大小为8位,干什么用的呢?这些针脚只有两种状态即0(低电平)与1(高电平)。我们可以通过写程序,通过编译器生成CPU的一条条指令,烧录到里面去。我们通过对针脚的高低电平进行逻辑判断,再通过一系列状态对针脚状态做出改变。 举一个例子,比如查看某个针脚状态,读到了1,可以假想(另一个针脚上连着电机),我们改变针脚状态,让电机转起来。 总之完单片机编程玩的就是寄存器,我们也可以称它为针脚编程。为什么使用C语言写的呢,而写我们好像都是用的一个叫做keil的软件。其实我们的C语言代码没有跑在单片机上,CPU认识的东西叫做指令集,其实就是一串串0-1编码。一条条执行,跑了起来,keil就是做其中的转换的一个编译软件,将我们写的C语言单片机代码转换为CPU可以认识的一条条指令。有人肯定想问:我们不用C语言不行吗,当然可以,如果你能写一个自己的编程语言,做这样的转换,也许下一个革命的人就是你呢。 那个银亮色的晶振什么鬼 人们都说单片机的心藏是那个叫晶振的东西,晶振有什么用呢。上面我们提到,CPU认识需要执行一条一条的指令,但机器怎么知道一条条执行呢,我们可以傻瓜式想想,晶振发出脉冲信号,没发一次单片机就会执行一条或多条指令。我们后面会学到单片的中断、定时器,晶振每隔固定时间发出信号,那么我们就可以利用它来知道经过了多长时间。管它什么鬼呢,把硬件交给搞硬件的,我们先专心写我们的面向针脚编程吧。 C51程序界的Hello World #include void main() { P2=0xFE; //1111 1110 while(1) { } } 我们通过控制寄存器存储的值,来改变针脚的状态,后面为什么有一个while(1){}呢,单片机程序与我们现在windows、Linux C程序不同,电脑上的程序运行一次就结束了。单片机如果程序运行完后、它会从头再来。所以我们让单片机卡死在哪里就好了。 LED灯闪烁实现 怎样实现延时呢?没错我们可以暴力解决,让它运行一段循环不就行了嘛。我们可以使用stc-isp软件来生成延时代码片段。我们要知道,晶振就像一个定时的东西,每隔一个固定的时间片段就会发出脉冲信号,让我们的单片机CPU指令,一条条执行(形象地描述,原理太复杂了,恐怕要读一整本计算机组成原理) #include #include void Delay500ms() //@12.000MHz { unsigned char i, j, k; _nop_(); i = 4; j = 205; k = 187; do { do { while (--k); } while (--j); } while (--i); } void main() { while(1) { P2=0xFE; //1111 1110 Delay500ms(); P2=0xFF; //1111 1111 Delay500ms(); } } 我们改变的个针脚的状态,交替执行,转态变化 0__1__0__1__0__1…,这样不就闪烁起来了吗。 LED流水灯实现 流水灯这不过,是一排灯按照按顺序点亮,灭掉,下一个点亮,灭掉…而已。我们按一定的逻辑来控制一个寄存器的位的状态就好了。 #include #include void Delay500ms() //@12.000MHz { unsigned char i, j, k; _nop_(); i = 4; j = 205; k = 187; do { do { while (--k); } while (--j); } while (--i); } void main() { while(1) { P2=0xFE;//1111 1110 Delay500ms(); P2=0xFD;//1111 1101 Delay500ms(); P2=0xFB;//1111 1011 Delay500ms(); P2=0xF7;//1111 0111 Delay500ms(); P2=0xEF;//1110 1111 Delay500ms(); P2=0xDF;//1101 1111 Delay500ms(); P2=0xBF;//1011 1111 Delay500ms(); P2=0x7F;//0111 1111 Delay500ms(); } } 虽然这是一种傻瓜式流水灯,但我们能实现功能就好了。就像做实物一样,不管用了什么技术,就像有一个网站,java做服务端,C++做服务端。做为一个使用者,谁会没事关注这些东西呢。 延时函数可复用 我们不能需要用到多长时间的延时,都去创建一个函数吧,为何不把延时函数加个参数,来实现呢 #include void Delay1ms(unsigned int xms); //@12.000MHz void main() { while(1) { P2=0xFE;//1111 1110 Delay1ms(1000); P2=0xFD;//1111 1101 Delay1ms(1000); P2=0xFB;//1111 1011 Delay1ms(100); P2=0xF7;//1111 0111 Delay1ms(100); P2=0xEF;//1110 1111 Delay1ms(100); P2=0xDF;//1101 1111 Delay1ms(100); P2=0xBF;//1011 1111 Delay1ms(100); P2=0x7F;//0111 1111 Delay1ms(100); } } void Delay1ms(unsigned int xms) //@12.000MHz { unsigned char i, j; while(xms) { i = 2; j = 239; do { while (--j); } while (--i); xms--; } } 使用按键 如果一个开关一边接到了针脚上,另一端接上1(高电平),当我们地的开关闭合时,那么针脚状态就是1,开关断开,则是0 ,我们可以去检测针脚状态来进行逻辑控制 #include void main() { while(1) { if(P3_1==0 || P3_0==0) //如果K1按键或K2按键按下 { P2_0=0; //LED1输出0,点亮 } else { P2_0=1; //LED1输出1,熄灭 } } } 使用按键保存状态 #include void Delay(unsigned int xms) { unsigned char i, j; while(xms) { i = 2; j = 239; do { while (--j); } while (--i); xms--; } } void main() { while(1) { if(P3_1==0) //如果K1按键按下 { /* 1 /1 / / 0----/0 */ Delay(20); //消除下坡上坡影响 while(P3_1==0); //松手检测 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 void Delay(unsigned int xms); unsigned char LEDNum; void main() { P2=~0x01; //上电默认LED1点亮 while(1) { if(P3_1==0) //如果K1按键按下 { Delay(20); while(P3_1==0); Delay(20); LEDNum++; //LEDNum自增 if(LEDNum>=8) //限制LEDNum自增范围 LEDNum=0; P2=~(0x01< if(P3_0==0) //如果K2按键按下 { Delay(20); while(P3_0==0); Delay(20); if(LEDNum==0) //LEDNum减到0后变为7 LEDNum=7; else //LEDNum未减到0,自减 LEDNum--; P2=~(0x01< } } void Delay(unsigned int xms) { unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); } } |
|
|
|
只有小组成员才能发言,加入小组>>
2545 浏览 0 评论
1142浏览 2评论
741浏览 1评论
495浏览 0评论
256浏览 0评论
417浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:18 , Processed in 1.390458 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号