单片机C语言程序的结构和设计.docx

上传人:b****4 文档编号:24600699 上传时间:2023-05-29 格式:DOCX 页数:36 大小:1.75MB
下载 相关 举报
单片机C语言程序的结构和设计.docx_第1页
第1页 / 共36页
单片机C语言程序的结构和设计.docx_第2页
第2页 / 共36页
单片机C语言程序的结构和设计.docx_第3页
第3页 / 共36页
单片机C语言程序的结构和设计.docx_第4页
第4页 / 共36页
单片机C语言程序的结构和设计.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

单片机C语言程序的结构和设计.docx

《单片机C语言程序的结构和设计.docx》由会员分享,可在线阅读,更多相关《单片机C语言程序的结构和设计.docx(36页珍藏版)》请在冰豆网上搜索。

单片机C语言程序的结构和设计.docx

单片机C语言程序的结构和设计

实验五单片机C语言程序的结构和设计

一、实验目的

1.掌握单片机C语言的程序结构;

2.掌握单片机C语言程序的编写和调试方法;

3.掌握MSP430FG2553基本I/O控制方法;

4.掌握单片机对外部接口电路的控制方法。

二、实验任务

1.练习调试程序

(1)硬件连接图

(2)原程序存在的问题

①实验要求将L1~L8连接到P2OUT端口上,所以程序中的端口应该采用P2OUT;

②由于程序中用到了P2OUT所有端口作为输出,所以应该首先将P2设置为GPIO;

③实验要求八个LED等应该在亮和灭之间进行循环,所以应该在原程序中加入主循环;

④在延时函数delay()中,延时时间不够,所以不能够看出灯的闪烁,应该将循环的时间延长;

(3)修改后的程序:

#include"io430.h"

voiddelay();

intmain(void)

{

WDTCTL=WDTPW+WDTHOLD;//关闭看门狗

P2SEL=0;

P2SEL2=0;

P2DIR=0xff;//设置端口1为输出

P2OUT=0xff;

for(;;)

{P2OUT=~P2OUT;//将端口1的值取反后输出

delay();//调用函数延时

}

}

voiddelay()//延时函数

{unsignedintj;

for(j=0;j<0xffff;j++);}

(3)程序调试方法总结

程序调试时主要使用逐步调试的方法,通过F10和F11使程序逐步运行,有必要时通过view观测register寄存器的相关值的变化,通过观察每一步运行之后相关寄存器的变化,可以初步判断对应程序运行的正确与否,还可以通过设置断点的方式进行局部调试。

对于几个不同调试按钮的使用方法总结如下:

GO属于连续执行,在调试过程中通常与断点同时使用,用于程序的长距离跳转;stepover用于逐步运行程序,但是不会运行到子程序的内部,如本例子中的delay函数,用此按钮时不会运行到delay内部;而stepinto则可以进入子函数内部,通常用来调试子函数,在调试子函数过程中若想跳出子函数可以使用stepout;合理地使用这些指令可以高效的调试程序。

2.控制发光二极管的显示变化

(1)硬件连接图

(2)C语言程序

#include"io430.h"

voiddelay();

voidaction_1();

voidaction_2();

constunsignedcharLED_blink1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

constunsignedcharLED_blink2[4]={0xdb,0xe7,0x7e,0xbd};

intmain(void)

{

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P2SEL=0;//将P2端口设置为GPIO

P2SEL2=0;

P2DIR=0xff;//方向设定

for(;;)//主循环

{

action_1();//子函数调用

action_2();

}

}

voiddelay()//延时函数

{

inti;

for(i=0;i<0xffff;i++);

}

voidaction_1()//规律一动作函数

{

intj;

for(j=0;j<=7;j++)

{

delay();

P2OUT=~LED_blink1[j];//使输出端口按照表中显示

}

}

voidaction_2()//规律二动作函数

{

intk;

for(k=0;k<4;k++)

{

delay();

P2OUT=LED_blink2[k];//使输出端口按照表中显示

}

}

由于本程序比较简单,并且在上面程序后面附有注释,故不再说明程序的运行原理。

(3)思考

若要使用P1端口控制8个发光二极管,则实验板上的连线方面需要将L1~L8分别用跳线连接至P1.0~P1.7,在程序方面只需要将原程序中用到的P2端口均换成P1端口即可。

3.用按键控制发光二极管的显示变化

(1)硬件连接图

(2)程序设计思路

首先由于在上一个任务中已经实现了两种显示方式的循环显示,所以为实现该任务,只需要在上一个任务的程序中加入按键控制即可。

通过两个将两个P1引脚设置成输入引脚并与按键相连用来检测按键,在上个任务中的程序中,由于两个动作方式是循环进行的,所以只需实现当检测到对应的按键时,使得程序跳出执行某一动作的循环而进入执行另一动作的循环即可。

另外由于子函数一个循环是显示完一个动作,所以也需要在子函数中加入按键检测,当到按键时就跳出循环。

对于按键检测,由于当按下键时与地相连,所以需要给其一个上拉电阻,然后检测按键相连的输入引脚是否为低电平即可。

(3)C语言程序

#include"io430.h"

voiddelay();

voidaction_1();

voidaction_2();//函数声明

constunsignedcharLED_blink1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

constunsignedcharLED_blink2[4]={0xdb,0xe7,0x7e,0xbd};

intmain(void)

{

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P2SEL=0;

P2SEL2=0;//将P2端口设置为普通IO

P1SEL=0;

P1SEL2=0;//将P1端口设置为普通IO

P2DIR=0xff;//P2设置为输出引脚

P1DIR=0xf0;//P1.0~P1.3设置为输入引脚,其余为输出引脚

P1REN|=BIT0+BIT1+BIT2+BIT3;//P1.0~P1.3上拉电阻使能置为1

P1OUT=0xff;//为P1.0~P1.3接上拉电阻

P1OUT|=BIT7;

for(;;)//主循环

{

for(;;)//动作一执行循环

{

action_1();//调用动作一函数

if((P1IN&BIT3)==0)//当检测到P1IN&BIT3对应按键时执行

{

P1OUT&=~BIT7;//置零P1.7,蜂鸣器工作

delay();//延时一段时间

P1OUT|=BIT7;//置位P1.7,蜂鸣器停止

break;//跳出动作一循环,进入动作二循环

}

}

for(;;)//动作二循环

{

action_2();//调用动作二函数

if((P1IN&BIT0)==0)//当检测到P1IN&BIT0对应按键时执行

{

P1OUT&=~BIT7;//蜂鸣器工作

delay();//延时一段时间

P1OUT|=BIT7;//蜂鸣器停止

break;//跳出动作二循环,进入动作一循环

}

}

}

}

voidaction_1()//动作一子函数

{

intj;

for(j=0;j<=7;j++)

{

delay();

P2OUT=~LED_blink1[j];

if((P1IN&BIT3)==0)break;//当检测到按键时立即跳出

}

}

voidaction_2()//动作二子函数

{

intk;

for(k=0;k<4;k++)

{

delay();

P2OUT=LED_blink2[k];

if((P1IN&BIT0)==0)break;//当检测到按键时立即跳出子函数

}

}

voiddelay()//延时函数

{

inti;

for(i=0;i<0xffff;i++);

}

该任务的代码如上所示,该代码中LED灯工作的基本思想与上一任务中的基本相同,程序的说明见程序后的注释,不再赘述。

4.并行方式控制数码管的显示

(1)数码管工作原理

数码管电路的内部结构如下图所示:

如上图所示,数码管的控制电路由两部分组成,一部分是位选信号S1~S4,控制四个数码管的显示与否,当其为高电平时,对应的数码管点亮。

Sa~Sh为数码管段选信号,用于控制八段数码管的显示内容。

所以若想在某个数码管上显示,首先应该给位选信号一个高电平,然后利用段选信号来控制要显示的内容。

(2)硬件连接图

(3)数码管的轮流显示

(a)硬件连接图

硬件连接图如上图所示。

(b)设计思路

将想要显示的内容翻译成数码管的段选信号,并将其存在数组中。

在较短的时间内,使四个数码管的为选信号依次单独为1,同时给相应的数码管段选信号。

(c)C语言程序

#include"io430.h"

//定义一个数码管显示表对应数码管显示为{,,,0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,,,,,G,o,o,d};

unsignedintNUM_tab[27]={0xff,0xff,0xff,0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,

0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xff,0xff,0xff,0x82,0xa3,0xa3,0xa1};

voidprint(intk);//函数声明

intmain(void)

{

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P1SEL=0;

P1SEL2=0;

P2SEL=0;

P2SEL2=0;//将P1和P2均设置为GPIO

P2DIR=0xff;//P2设置为输出端口

P1DIR=0xff;//P1设置为输出端口

P1OUT&=~(BIT0+BIT1+BIT2+BIT3);

P1OUT|=BIT0;

intj;

for(j=0;j<20;j++)//数码管上轮流显示上面内容的循环

{

print(j);//调用函数进行扫描显示

}

for(;;){print(23);}//一直显示“Good。

}

voidprint(intk)

{

inta;

for(a=0;a<0x2ff;a++)//循环实现延时

{

if((a%24)==0)

{P2OUT=NUM_tab[k+3];P1OUT|=BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;}

//右边第一个数码管显示

elseif((a%24)==6)

{P2OUT=NUM_tab[k+2];P1OUT&=~BIT0;P1OUT|=BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;}

//右边第二个数码管显示

elseif((a%24)==12)

{P2OUT=NUM_tab[k+1];P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT|=BIT2;P1OUT&=~BIT3;}

//右边第三个数码管显示

elseif((a%24)==18)

{P2OUT=NUM_tab[k];P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT|=BIT3;}

//最左边数码管显示

}

}

(4)设计电子跑表

(a)硬件连接图

硬件连接图与(3)中相同。

(b)设计思路

该任务与上一个任务相似,都是使用四个数码管同时显示数字,由于对于3分钟以内的跑表,每个数码管上显示的内容都是0~9之间,所以同样可以定义数组一次存放0~9,显示时利用循环实现循环显示的功能。

(c)C语言程序

#include"io430.h"

voidseg();

intnum3,num2,num1,num0;

intmain(void)

{

unsignedcharNUM_tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P1SEL=0;

P1SEL2=0;

P2SEL=0;

P2SEL2=0;//P1和P2设置为GPIO

P1DIR=0x1f;//P1.0~P1.4设置为输出,其余设置为输入

P2DIR=0xff;//P2设置为输出

P1REN|=BIT5+BIT6+BIT7;//上拉电阻使能

P2OUT=0x00;

P1OUT|=BIT4+BIT5+BIT6+BIT7;//接上拉电阻

inti,j,k;

for(;;)

{

num3=NUM_tab[0];//时钟最高位一直显示0

for(i=0;i<=3;i++)//循环控制时钟分钟个位

{

num2=NUM_tab[i];//分钟个位赋值

if(i==3)

P1OUT&=~BIT4;//当到三分钟时,蜂鸣器工作

else

P1OUT|=BIT4;

for(j=0;j<=5;j++)//时钟秒十位循环控制

{

num1=NUM_tab[j];//时钟秒十位赋值

for(k=0;k<=9;k++)//秒个位循环控制

{

num0=NUM_tab[k];//秒个位赋值

seg();//调用显示函数进行显示

if(num2==0xb0&&num1==0xc0&&num0==0xc0)

break;//当计时到三分钟时跳出循环

}

if(num2==0xb0&&num1==0xc0&&num0==0xc0)

break;

}

if(num2==0xb0&&num1==0xc0&&num0==0xc0)

break;

}

}

}

voidseg()

{

inta;

for(a=0;a<0xff;a++)

{

if((a%12)==0)

{P1OUT|=BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;P2OUT=num0;}

elseif((a%12)==3)

{P1OUT&=~BIT0;P1OUT|=BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;P2OUT=num1;}

elseif((a%12)==6)

{P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT|=BIT2;P1OUT&=~BIT3;P2OUT=num2;}

elseif((a%12)==9)

{P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT|=BIT3;P2OUT=num3;}

}

}

(d)思考题

控制每个数码管显示的延时时间不能太短也不能太长,这是因为若太长则四个数码管显示存在闪烁;若时间太短则数码管亮度太低。

(5)(提高)增加按键控制功能

(a)硬件电路图

(b)设计思路

与LED的按键控制思路相同,当暂停时使数码管处于死循环中,循环显示同一个时刻,当按下开始或者复位键时跳出该循环,若是开始键则运行与上面相同,当按下复位键时使程序从循环最开始运行,并进入死循环,此时一直显示00:

00.

(c)C语言程序

#include"io430.h"

voidseg();

intnum3,num2,num1,num0;

intmain(void)

{

unsignedcharNUM_tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P1SEL=0;

P1SEL2=0;

P2SEL=0;

P2SEL2=0;

P1DIR=0x1f;

P2DIR=0xff;

P1REN|=BIT5+BIT6+BIT7;

P2OUT=0x00;

P1OUT|=BIT4+BIT5+BIT6+BIT7;

inti,j,k;

intrst,start;

for(;;)

{

num3=NUM_tab[0];

for(i=0;i<=3;i++)

{

num2=NUM_tab[i];

if(i==3)

P1OUT&=~BIT4;

else

P1OUT|=BIT4;

for(j=0;j<=5;j++)

{

num1=NUM_tab[j];

for(k=0;k<=9;k++)

{

num0=NUM_tab[k];

while(!

start)//未按下开始键时执行循环即暂停

{

seg();

if((P1IN&BIT5)==0||(P1IN&BIT7)==0)break;//当按下开始或者清零时跳出循环

}

if((P1IN&BIT7)==0){start=1;rst=0;}//若按下开始键则start=1,rst=0;

if((P1IN&BIT6)==0){start=0;rst=0;}//若按下暂停键则start=0,rst=0;

if((P1IN&BIT5)==0){start=0;rst=1;}//若按下清零键则start=0,rst=1;

seg();

if((num2==0xb0&&num1==0xc0&&num0==0xc0)||rst==1)//当计时结束或者清零键时跳出循环

break;

}

if((num2==0xb0&&num1==0xc0&&num0==0xc0)||rst==1)

break;

}

if((num2==0xb0&&num1==0xc0&&num0==0xc0)||rst==1)

break;

}

}

}

////////////////////数码管显示电路///////////////////

voidseg()

{

inta;

for(a=0;a<0x1ff;a++)

{

if((a%12)==0)

{P1OUT|=BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;P2OUT=num0;}

elseif((a%12)==3)

{P1OUT&=~BIT0;P1OUT|=BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;P2OUT=num1;}

elseif((a%12)==6)

{P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT|=BIT2;P1OUT&=~BIT3;P2OUT=num2;}

elseif((a%12)==9)

{P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT|=BIT3;P2OUT=num3;}

}

}

5.串行方式控制数码管显示

(1)硬件连接图

(2)设计思路

使用74HC595实现的串行方式控制数码管,与并行方式的唯一差别在于对于一个数码管的显示内容的控制。

并行方式较为简单,直接将对应的值赋给连接段选信号的输出端口即可,而串行方式则需要一位一位地输入,即从高位到低位一次从DS端口输入,每准备好一位数据需要给SHCP一个脉冲读入,输入八位之后给STCP一个脉冲使得数码管进行显示,所以在之前任务的基础上,创建子函数实现这个过程即可,其余相同。

(3)C语言程序

#include"io430.h"

voidseg();

voidINPUT();

unsignedcharBIT[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

//位测试向量,用于检测对应位上的值

unsignedcharNUM_TAB[27]={0xff,0xff,0xff,0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xff,0xff,0xff,0x82,0xa3,0xa3,0xa1};

//显示表

intmain(void)

{

//Stopwatchdogtimertopreventtimeoutreset

WDTCTL=WDTPW+WDTHOLD;

P1SEL=0;

P1SEL2=0;

P2SEL=0;

P2SEL2=0;//设置为GPIO

P2DIR=0xff;

P1DIR=0xff;//设置为输出端口

P1OUT=0x00;

intj;

for(j=0;j<20;j++)//循环实现移动显示

{

seg(j);

}

for(;;){seg(23);}//循环完之后显示Good

}

//********************数码管扫描显示函数***********************//

//由于该部分与之前任务相同不再赘述

voidseg(intk)

{

inta;

for(a=0;a<0x2ff;a++)

{

if((a%12)==0)

{INPUT(k+3);P1OUT|=BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;}

elseif((a%12)==3)

{INPUT(k+2);P1OUT&=~BIT0;P1OUT|=BIT1;P1OUT&=~BIT2;P1OUT&=~BIT3;}

elseif((a%12)==6)

{INPUT(k+1);P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT|=BIT2;P1OUT&=~BIT3;}

elseif((a%12)==9)

{INPUT(k);P1OUT&=~BIT0;P1OUT&=~BIT1;P1OUT&=~BIT2;P1OUT|=BIT3;}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 国外设计风格

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1