轻松愉快的实训课——C51程序设计

上周焊板子焊到头晕的电路实训课终于结束了,至于这周呢,就是为单片机设计程序了。按照老师的计划,这次实训不会教太深奥的内容,只要入门就够了。


之后在交谈中得知,其实老师也很讨厌这种事。据说在她刚到单位工作时,按规定要参加三个月的培训,主要是为了熟悉单位的管理制度。在第一个月里干的是检查回流焊机筛选下来的残次品,找出不合格的地方,用电烙铁手动焊到正确的地方。

因为对多数人来说是第一次使用Keil,首先要安装开发环境。需要的软件和工具包在keil网站都有下载。顺便还有最重要的密钥生成器(学校不提供正版Keil没办法啊):

官方下载页面:https://www.keil.com/download/product/

c51v952下载:http://pan.baidu.com/s/1F0bFS

MDK5.00下载:http://pan.baidu.com/s/1nFHuJ


STC程序下载软件:http://www.stcmcu.com/STCISP/stc-isp-15xx-v6.63.exe


这次实训要用到的关键字似乎只有一个:

sbit:定义特殊功能寄存器的位变量

e.g.

sbit a = P0^1;

sbit P1 = 0xff;


在为C51编程时必须要包含REG51.H文件。在这个文件中包含对单片机各种端口和地址的定义,不包含的话程序很可能运行不了。

学了这么多该写个程序练习一下了。就从最简单且最常用的延时函数开始写起。

为了直观的体验延时函数的作用,我们要求使开发板上的一个二极管以肉眼可分辨的频率有规律的闪烁。那么在编程之前先观察单片机获得一些必要的信息:

1、用来练习的单片机是这样的:




2、选定一个输出信息的二极管:

决定选P17,因为看起来最好找。



3、记录晶震的工作频率:

显然是12.000MHz


OK,接下来要设置Keil中的一些参数:

点击Target Options:



在这里填入晶震参数:



选中Create HEX File,等下要用外部工具下载程序。



好的,接下来就可以建工程写代码了

1、如果没有STC8051CPU参数可选的话就用Atmel的AT89C51;

2、建立必要的文件:


3、敲代码:

FDdelay.h

#include <REG51.h>
void FDdelay(unsigned int delayTime);


FDdelay.c

void FDdelay(unsigned int delayTime){ // 看上去可以工作的延时函数
    unsigned int i, j;
    for(i = 0; i < delayTime; i++){
        for(j = 0; j < 120; j++);
    }
}

delayTest.c

#include "FDdelay.h"
sbit a = P1^7;
void main(){ // 测试函数

for(;;){
    a = 1;
    FDdelay(500);
    a = 0; 
    FDdelay(500);
   }

}

代码写完了,编~译……成功~



打开STC下载软件下载编好的程序:


选好要下载的程序后点击"下载/编程";


这时重新开关单片机开关,如果不出意外的话,会出现这个提示:


P17一闪一闪的好好看。

------------第一天实训结束-----------------


第二天实训一开始就复习了下很基本的东西……算了写一下吧:

1、reg51.h是单片机51系列必须的头文件;

2、进行位定义 sbit A= P0^1;

3、要使用无符号数据类型保证程序不会出错;

4、宏定义 #define 标识符 字符串;

5、要使用for(;;) 或者 while(1)语句是程序连续执行;

6、端口赋值语句 端口名 = 参数;  P1 = 0xFF;

7、比较器工作方式:

当”+”输入端电压高于”-”输入端时,电压比较器输出为高电平;
当”+”输入端电压低于”-”输入端时,电压比较器输出为低电平;

然后今天的程序嘛~因为是用开发板测试程序,所以只好各种假设了。写好的程序:
#include <reg52.h>

/*
0 = open
1 = close


光敏电阻:
光强越大,电流越强
光强越小,电流越弱


假设:
开发板的按键按下为有光,抬起为无光;
开发板的LED亮起为电机启动,灭掉为电机停机。
*/

const unsigned int open = 0;
const unsigned int close = 1;
const unsigned int light = 0;
const unsigned int dark = 1;

sbit lightLeft = P2^0;
sbit lightRight = P2^1;
sbit powerLeft = P1^7;
sbit powerRight = P1^6;


void delay(unsigned int time){
    unsigned int i, j;
    for(i = 0; i < time; i++){
        for(j = 0; j < 110; j++);
}
}

void main(){

for(;;){
if(lightLeft  == light && lightRight == light){
    powerLeft = open;
    powerRight = open;
}
if(lightLeft  == dark && lightRight == dark){
    powerLeft = close;
    powerRight = close;
}

if(lightLeft  == dark && lightRight == light){
    powerLeft = open;
    powerRight = close;
    delay(500);
    powerLeft = close;
}

if(lightLeft  == light && lightRight == dark){
    powerLeft = close;
    powerRight = open;
    delay(500);
    powerRight = close;
}
}
}

虽然运行结果跟我预期的不同,但老师说要的就是这个效果。算了,信老师一次。

---今天实训的内容就这些,没有下期预告---

终于有时间更新了,差点烂尾的说。先让我回忆一下……
今天要做的是将昨天写好的程序烧到mcu中,让小车正常运行。首先呢,我是这样定义引脚的:
P20 -> 电机左, 输出高电平电机启动
P23 -> 电机右, 输出高电平电机启动
P10 -> 光敏右, 输入高电平表示有光
P13 -> 光敏左, 输入高电平表示有光

将引脚修改好后,下载程序,运行……车轮隔好几秒才转一下。这是要怎样啊。果断把延时全部去掉后小车能跑了,左边有光向左转,右边有光向右转,两边都感应到有光当然是向前走了。在把像蜘蛛网一样的杜邦线收拾了一下后拿到机房去测试。测试结果于预期高度一致。Good,收工验收走人。
刚要走发现我身后围了好多人呐,这什么情况,一个不能倒车的小车有什么好看的。不过算了,给他们演示一下吧。就在这时,我想到了一个不错的问题,可以把我做好的这些东西完善一下,做成一个方案提供给需要的人。看起来不错呐~经过了一些简单但有效的运作后,我设计的方案很快就要统治实训课了(包括但不限于我们的)~
接下来的下午没有实训课-
第二天又到了,结果不出我所料,目标达成了~在对申请方案的老师简单培训之后,剩下的事情就是将我的代码下载到mcu中分发给老师们。尽管这样,今天上午我还是忙的一瓶可乐都没喝完。看来我处理突发业务的能力还有待提高啊,呵呵。

实训项目二:  4位SEG7显示指定数字
老师又开始传授新知识了,趁机休息一下。
4位SEG7显示指定数字简单的说就是将4个SEG7做到一个模块上。这个模块通常有12根引脚,8根控制线,4根位选线。实训用的板子上自带一个共阴极4位SEG7,经测试后引脚对应如下:
P27高电平-> SEG1亮
P26高电平-> SEG2亮
P25高电平-> SEG3亮
P24高电平-> SEG4亮

P00低电平 -> dp
P01低电平 -> g亮
P02低电平 -> f亮
P03低电平 -> e亮
P04低电平 -> d亮
P05低电平 -> c亮
P06低电平 -> b亮
P07低电平 -> a亮

然后可根据上面的信息得到控制SEG显示的数据:
uint LED_1 = 0x80;
uint LED_2 = 0x40;
uint LED_3 = 0x20;
uint LED_4 = 0x10;

uint CHAR_0 = 0x03;
uint CHAR_1 = 0x9f;
uint CHAR_2 = 0x25;
uint CHAR_3 = 0x0d;
uint CHAR_4 = 0x99;
uint CHAR_5 = 0x49;
uint CHAR_6 = 0x41;
uint CHAR_7 = 0x1f;
uint CHAR_8 = 0x01;
uint CHAR_9 = 0x09;
uint CHAR_DOT = 0xfe;

实现用C51控制SEG7-4自动计数,从0数到99。经过我一番缜密的思考,一不小心写下了这段代码:
#include <reg51.h>
#define uint unsigned int;

// delay function
void delay(unsigned int time){ 
int i;
for(i = 0; i < time; i++);
}
// end delay function


/*
显示位选择
*/
uint LED[4] = {0x80, 0x40, 0x20, 0x10};
/*
uint LED_1 = 0x80;
uint LED_2 = 0x40;
uint LED_3 = 0x20;
uint LED_4 = 0x10;
*/

/*
数字选择
*/
uint CHAR[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
/*
uint CHAR_0 = 0x03;
uint CHAR_1 = 0x9f;
uint CHAR_2 = 0x25;
uint CHAR_3 = 0x0d;
uint CHAR_4 = 0x99;
uint CHAR_5 = 0x49;
uint CHAR_6 = 0x41;
uint CHAR_7 = 0x1f;
uint CHAR_8 = 0x01;
uint CHAR_9 = 0x09;
uint CHAR_DOT = 0xfe;
*/

/*
端口设定
*/


// disp number to SEG7
void disp(int j, int k){
        int count;
        for(count = 0;count < 500; count++){
        P2 = LED[0];    
        P0 = CHAR[j];
        delay(100);
        P2 = LED[1];
        P0 = CHAR[k];
        delay(100);
        }
}
// end disp number to SEG7


void main (){
for(;;){
    
int j, k;
// count number 0 to 99
for(j = 0; j < 10; j++){
    for(k = 0; k < 10; k++){
        disp(j, k);
    }
}
// end count number 0 to 99


/*  test code
        P2 = LED[0];    
        P0 = CHAR[3];
        delay(50);
        P2 = LED[1];
        P0 = CHAR[5];
        delay(50);
        
        */
}
}

以上就是本次实训全部内容。至于各种琐事就不必提了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值