51例程编写学习过程.docx
《51例程编写学习过程.docx》由会员分享,可在线阅读,更多相关《51例程编写学习过程.docx(17页珍藏版)》请在冰豆网上搜索。
51例程编写学习过程
51单片机系统板
例程学习编写过程
7426笨蛋编
序言
兴趣是最好的老师,它可激发人的创造热情、好奇心和求知欲。
由百折不挠的信念所支持的人的意志,比那些似乎是无敌的物质力量有更强大的威力。
————爱因斯坦
对电子由衷的喜欢是一直以来学习的动力,像很多爱好者一样自己对知识掌握到一定程度就迫不及待地想着给人分享自己的学习经验,因此本文档就产生了。
在如今,单片机已经遍布在我们生活每个角落,学习单片机的人越来越多,市场上的相关系统开发板也是遍地开花,随之而来的配套例程数不胜数。
为什么编者还是要在这里自己写例程呢?
现在卖开发板的商家愈来愈多,形式也是多种多样,但其中配套例程大多数都是你抄抄我我抄抄你,造成范例程序参差不齐,有的根本不配所卖的板子,有的程序则是bug百出。
所以在这里,决定资料中的每一个程序都自己编写,这也算是把所学到的知识复习一遍,并且把其中的一些学习经验记录下来,希望能够带给大家一些帮助,能够让大家更好的理解程序吧。
由于本人水平有限,难免在文档或者例程中有错误,敬请大家批评指正。
7426笨蛋
2014年8月
目录
1、LED闪烁灯(位操作)
2、LED闪烁灯(查表法)
3、按键控制LED
4、LED点阵简单来回显示
5、LED点阵静态显示字符
6、LED点阵滚动显示字符
7、按键控制点阵显示点、线
8、按键控制点阵显示字符
9、利用定时器制作60秒表
10、蜂鸣器的驱动
11、产生不同频率驱动蜂鸣器
12、利用蜂鸣器唱歌
13、电动机的驱动
14、产生PWM驱动电动机
15、OLED屏驱动显示
16、AD转换显示
17、利用AD制作简易电压表
18、利用AD制作简易示波器
19、DS1302时钟模块制作时钟
20、按键控制OLED屏分级显示
21、制作一个简单的综合控制显示系统
1、LED闪烁灯(位操作)
绝大多数初学者刚接触单片机所做的都是同一件事--点亮LED灯,无论是哪个教材都差不多。
因为学单片机,最简单就是的IO口控制高低电平,而led灯可以直观显示出IO口的电平状态。
所以本文档的例程也是从LED闪烁灯开始。
准备工作(后面章节不再重复)
1.电脑并安装好KeiluVision4(
2.打开KeiluVision4
3.工程——新建uVision工程,设置好保存路径,键入文件名后保存
4.设置好单片机型号ATmel下的89C52,点确定,后面有提示点否。
这样一个工程就建好了。
5.开始写程序,点文件下面那个白色的图标,弹出框后随便写个字母,之后点关闭,这时候会弹出一个对话框,点是,输入文件名以.c后缀名保存
6.在左边源组1哪里右键——添加文件到源组,在弹出的对话框中选择刚才保存的c文件
7.文件添加好了就点击有红绿白三色块左边那个想魔棒一样的图标,在弹出的面板上面点输出,然后勾上产生hex文件的选项,最后确定。
8.之后就可以编程序了,在编好程序之后,点文件保存图标下面的那个有两个箭头的图标编译一遍看看程序有没有错误,如果有错误下面会有提示,改好后再点重新构建,没错误的话下面就会有创建hex文件成功的提示creatinghexfilefrom"LEDMatrix"...
9.有了hex文件后我们就可以烧写进单片机中了,打开stc-isp软件,选择好单片机型号STC12C5A60S2,点打开程序,在弹出的对话框中打开我们刚才程序的那个文件夹,选中上面生成的hex文件后打开
10.数据线连接开发板或者用USB串口线连接单片机最小系统板后插上电脑(如果提示安装驱动就按照资料包中的USB串驱动中的教程安装好),之后点STC-isp软件中的扫描,这时候应该找到所连接的串口了,再点下载/编程,最后在按单片机开发板上的开关冷启动一下,这时候应该STC-isp程序界面右边会出现一个过程进度条,最后就会提示操作成功。
(注意:
如果一直是提示正在检测目标单片机...就点停止——再点下载/编程试多几遍,如果还是不行就拔掉数据线再插上或者是关掉软件重新打开试试)
11.程序烧好之后就可以给单片机供电看程序运行正不正确了。
没有达到自己所要的效果就先大致看下程序有没有明显的错误的地方(比如说IO口定义错了,程序进入一个没有用的死循环等等......)大致明显的错误的话就可以看下硬件了,是不是线没有连接好,有的跳线没有连接,器件有没有坏。
如果都没问题这时候就要仔细的查看所编的程序了,看看是不是有逻辑错误,变量的定义类型有没有对会不会超出范围,所用到的函数有没有声明.......等等这些都是要一步一步细心的去查找排除的。
开始编程
1.编程思路:
要独立控制单个IO,所以要用到位操作,于是在程序开始应该先位定义:
可以把P2口中的第一个脚定义为LED0(sbitLED1=P2^0;)以此类推。
定义好了之后,比如说(LED1=1)就是把P2^0口置高电平,对应接到P2^0口的led灯就亮了。
单片机的IO口不仅可以单个控制,还可以一排控制。
比如说代码(P2=0x01;),因为0x01换算成二进制就是00000001,所以是也是等于把P2^0口置高电平。
2.具体程序:
//************LED灯闪烁程序(位操作)****************//
//*****************迷梦数码科技***********************//
//*********************//
//**********程序编写:
7426笨蛋************************//
//**********编写日期:
2014年8月***********************//
#include//STC12C5A60S2头文件,没有用到相关寄存器可以用reg51.h代替
#include//涉及汇编操作命令的头文件,合理利用可以简化代码
sbitLED1=P2^0;//位定义
sbitLED2=P2^1;
sbitLED3=P2^2;
sbitLED4=P2^3;
sbitLED5=P2^4;
sbitLED6=P2^5;
sbitLED7=P2^6;
sbitLED8=P2^7;
voiddelay(unsignedintms)//延时函数
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<800;j++)
{
;;
}
}
}
voidmain(void)
{
inti;
while
(1)
{
P2=0;
LED1=1;
delay(1000);
LED2=1;
delay(1000);
LED3=1;
delay(1000);
LED4=1;
delay(1000);
LED5=1;
delay(1000);
LED6=1;
delay(1000);
LED7=1;
delay(1000);
LED8=1;
delay(1500);
LED8=0;
delay(1000);
LED7=0;
delay(1000);
LED6=0;
delay(1000);
LED5=0;
delay(1000);
LED4=0;
delay(1000);
LED3=0;
delay(1000);
LED2=0;
delay(1000);
LED1=0;
delay(2000);
//上面是单独操作P2口每一个脚,依次给高电平点亮LED
//下面是一次性给P2口赋值点亮LED
P2=0x80;
for(i=0;i<8;i++)
{
P2=_crol_(P2,1);//_crol_(a,n)将char型变量a循环向左移动n位数后返回
delay(1000);
}
P2=0x01;
for(i=0;i<8;i++)
{
P2=_cror_(P2,1);//_cror_(a,n)将char型变量a循环向右移动n位数后返回
delay(1000);
}
}
}
二、LED闪烁灯(查表法)
1.编程思路:
所谓的查表法,就是预先取出一批8位的十六进制数,放在一个数组里面,然后在程序中循环读取给单片机一排IO口整体赋值。
程序编起来很简单,想要那几个灯亮就直接换算成十六制放进数组里就好了。
再来一个for循环把数组的数付给P2。
2.具体程序:
//************LED灯闪烁程序(查表法)****************//
//*****************迷梦数码科技******************//
//*********************//
//**********程序编写:
7426笨蛋***************//
//**********编写日期:
2014年8月*******************//
#include//STC12C5A60S2头文件,没有用到相关寄存器可以用reg51.h代替
#include//涉及汇编操作命令的头文件,合理利用可以简化代码
unsignedcharled[40]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
0x00,0x00,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x00,0x00,
0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,
0x00,0x00,
0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,
0x00,0x00
};
//P2/P2^0/P2^1/P2^2/P2^3/P2^4/P2^5/P2^6/P2^7/
//0x01/1/0/0/0/0/0/0/0/
//0x02/0/1/0/0/0/0/0/0/
//0x04/0/0/1/0/0/0/0/0/
//0x08/0/0/0/1/0/0/0/0/
//0x10/0/0/0/0/1/0/0/0/
//0x20/0/0/0/0/0/1/0/0/
//0x40/0/0/0/0/0/0/1/0/
//0x80/0/0/0/0/0/0/0/1/
voiddelay(unsignedintms)//延时函数
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<800;j++)
{
;;
}
}
}
voidmain()
{
unsignedchari;
P2=0xff;
delay(1000);
P2=0;
for(i=0;i<40;i++)
{
P2=led[i];//查表取模显示(高电平LED亮)
delay(1000);
}
}
3、按键控制LED
1.编程思路:
按键作为一个输入器件在单片机的应用非常广泛。
单片机检测按键输入其实很简单,就是读取IO口的电平。
一般来说接法都是当按键按下时,IO口被拉低。
由于按键在按下过程中会有抖动,所以在读取后加几微秒延时,再读取。
在读取按键时,可以专门写一个函数keycheck();这样一来可以使得程序更加易懂,更加简洁,再者是读取按键的函数在后面经常会用到,方便移植复制修改。
要达到按键控制led灯亮,可以定义一些标志位(比如说charalllight_flag;全部灯亮标志位,1:
全亮,0:
不起作用,用S5键控制切换)这样在主程序里只要循环读取按键,判断标志位后控制led的亮灭,具体可以看详细程序。
2.具体程序:
//**************按键控制LED********************//
//*****************迷梦数码科技********************//
//*********************//
//**********程序编写:
7426笨蛋**********************//
//**********编写日期:
2014年8月********************//
#include//STC12C5A60S2头文件,没有用到相关寄存器可以用reg51.h代替
sbitS1=P0^3;//位定义
sbitS2=P0^4;
sbitS3=P0^5;
sbitS4=P0^6;
sbitS5=P0^7;
unsignedcharalllight_flag;//全部灯亮标志位,1:
全亮,0:
不起作用,用S5控制切换
unsignedchardirection_flag;//左右排灯亮标志位,1:
右0:
左,用S3、S4切换
unsignedcharled_num;//灯亮的led号数
unsignedcharled[2][5]=//led显示二维数组,对应左右排每个led灯,其中加入0x00使得数据顺序符合常规思维
{
{0x00,0x01,0x02,0x04,0x08},//led1~4
{0x00,0x10,0x20,0x40,0x80}//led5~8
};
voidkeycheck();
voiddelay(unsignedintms)//延时函数
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<100;j++)
{
;;
}
}
}
voidmain()
{
led_num=1;//初始化led,LED1亮
while
(1)
{
keycheck();
if(alllight_flag)//如果成立则全部灯亮
{
P2=0xff;
delay(1000);
}
else
{
P2=led[direction_flag][led_num];//调出二维数组赋值给P2口点亮指定位置LED
delay(1000);
}
}
}
voidkeycheck()//按键扫描程序
{
if(S5==0)
{
delay
(1);//按键去抖
if(S5==0)
{
alllight_flag=!
alllight_flag;
while(S5==0);
}
}
elseif(S3==0)
{
delay
(1);
if(S3==0)
{
direction_flag=1;
}
}
elseif(S4==0)
{
delay
(1);
if(S4==0)
{
direction_flag=0;
}
}
elseif(S1==0)
{
delay
(1);
if(S1==0)
{
led_num++;
if(led_num>=4)//防止溢出,一边只有4个led
{
led_num=4;
}
while(S1==0);//加入这句,防止按着的时候数据一直在增加
}
}
elseif(S2==0)
{
delay
(1);
if(S2==0)
{
led_num--;
if(led_num<=1)//防止溢出,一边只有4个led
{
led_num=1;
}
while(S2==0);
}
}
}
4.LED点阵简单来回显示
1.编程思路:
LED点阵在我们单片机学习中可以说是一个不可或缺的模块,学习好点阵的驱动我们就能很好的理解并应用动态扫描来达到一些效果并节省IO口,同时在驱动点阵显示的同时我们也能学习到串口发送数据的方法,利用单片机来实现IC的时序操作。