历史上的今天
返回首页

历史上的今天

今天是:2025年01月06日(星期一)

正在发生

2020年01月06日 | AVR单片机8位数码管显示的程序实现

2020-01-06 来源:eefocus

我们接着来完成 数码管的显示实验。现在我们开始动手编写程序;

根据前面的介绍,我们应该已经能够知道编写一个 的C语言程序的基本步骤和方法了。

下面给出这个程序的主程序文件,在这个程序中我们应该能够知道这个程序都包含了那几块,具体来说我们应该能够在这个程序中把以下几个部分找出来:预编译语句、 的定义、函数的声明、主函数、函数定义。如果你还不能够准确找出这几部分,那么需要把前面的内容再详细阅读一下。


主程序代码

#include < /io.h> //io端口寄存器配置文件,必须包含

#include //GCC中的延时函数头文件

#include "hc .h"

//unsigned char Led_Disbuf[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共阴极

unsigned char Led_Disbuf[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //共阳极

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

//函数声明

extern void Delayus(unsigned int lus); //us延时函数

extern void Delayms(unsigned int lms); //ms延时函数

int main(void) //GCC中main文件必须为返回整形值的函数,没有参数

{

unsigned char i;

PORTB = 0xff; //PORTB输出低电平,使 熄灭

DDRB = 0xFF; //配置端口PB全部为输出口

HC595_port_init();

while(1)

{

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

{

PORTB = Led_Disbuf; //送段码

HC595_Send_Data(ComBuf); //选通位选端口

Delayus(70); //延时

HC595_Send_Data(0x00); //位选通关闭

}

}

}

//us级别的延时函数

void Delayus(unsigned int lus)

{

while(lus--)

{

_delay_loop_2(4); //_delay_loop_2(1)是延时4个时钟周期,参数为4则延时16

//个时钟周期,本实验用16M晶体,则16个时钟周期为16/16=1us

}

}

//ms级别的延时函数

void Delayms(unsigned int lms)

{

while(lms--)

{

Delayus(1000); //延时1ms

}

}


在这个主程序文件中有人可能会注意到有一些我们前面没有介绍过的内容,比如extern这个单词,它在这里起什么作用?


这就牵涉到C语言的关键字了,关于C语言的关键字,我们可以到相关的C语言教材中去做详细了解,在这里我们只针对extern这个关键字作出解释,我们注意到extern用在一个函数声明的地方,它的作用就是把这个函数声明为外部函数,这样我们在整个项目的所有文件中就都可以调用这个函数了。同理extern也可以用来声明一个变量为外部变量。


我们可能还会有一个疑惑:#include "hc595.h"这个头文件包含语句中的hc595.h有什么作用,它是GCC提供的还是我们自己编写的?


这里我们就要学习C语言中的一个重要的概念:模块化程序设计。何为模块化程序设计?它实现什么功能?如果要铺开来讲的话,可能需要一本书的内容。我们耗不起这个时间和精力。其实我们只需要知道,模块化程序设计是为了简化程序容量而采取的一种将一个程序分成不同的模块,然后通过特定的方法将这些模块组合起来共同完成同一个目标。通俗的说就是化整为零。


在我们刚开始学习 的时候,我们编写的程序都很简单,程序量也不大,所以往往涉及不到模块化程序设计,但是这是一种很好的编程思路,我们有必要掌握。本实例就是采用的这种方法。


模块化程序设计的思路是:将实现相同功能的程序单独编写,然后实现一个综合的功能,举个例子,我们想实现一个液晶显示的温度测量程序,那么我们可以把液晶显示相关的程序放在一个文件中,把温度测量的程序放在另一个文件中,最后在主程序中调用这两个文件来实现整体的功能。


通常我们在进行模块化程序设计的时候,常常将 ,端口设置,函数声明等部分保存在一个.h文件中,而将函数定义部分放在一个.c文件中,在编写主程序文件的时候,用预处理命令#include将.h文件包含起来,而在编译的时候将所有用到的.c文件一起编译。这样就实现了模块化文件的整合。


在本实例中,我们将74HC595相关的变量定义,端口定义,函数声明放在74HC595.h文件中,而主程序中的#include "hc595.h"这句话实现了将这个文件包含到主程序中的功能。


下面是本实例中模块化程序设计的.h文件

/*****************************

.h

***********************************/

/*74hc595与 的引脚连接

/MR(10脚) VCC 低点平时将 的数据清零。通常将它接Vcc

/OE(13脚) PG4 高电平时禁止输出(高阻态)。

如果 的引脚不紧张,用一个引脚控制它,

可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。

ST_CP(12脚) PG1 上升沿时移位寄存器的数据进入数据存储寄存器,

下降沿时存储寄存器数据不变。通常将RCK置为低电平,

当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。

通常都选微秒级),更新显示数据。

SH_CP(11脚) PG0 上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;

下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。

通常都选微秒级)

DS(14) PG2 串行数据输入端。

*/

#ifndef __HC595_H__

#define __HC595_H__

#include //io端口寄存器配置文件,必须包含

#include //GCC中的延时函数头文件

#define HC595_latch (1 << PG1) //上升沿数据打入8位锁存器,下降沿锁存器数据不变

#define HC595_sclk (1 << PG0) //上升沿数据移位,下降沿数据不变

#define HC595_oe (1 << PG4) //低电平,8位数据锁存器输出,高电平输出高组态

#define HC595_data (1 << PG2) //串行数据输入端

#define SET_HC595_latch (PORTG |= (1 << PG1))

#define CLR_HC595_latch (PORTG &= ~(1 << PG1))

#define SET_HC595_sclk (PORTG |= (1 << PG0))

#define CLR_HC595_sclk (PORTG &= ~(1 << PG0))

#define SET_HC595_data (PORTG |= (1 << PG2))

#define CLR_HC595_data (PORTG &= ~(1 << PG2))

#define SET_HC595_oe (PORTG |= (1 << PG4))

#define CLR_HC595_oe (PORTG &= ~(1 << PG4))

void HC595_port_init(void); //595端口初始化

void HC595_Send_Data(unsigned char byte); //发送一个字节

void HC595_Output_Data(unsigned char data); //发送字符串

#endif

同时我们将与74HC595相关的函数定义部分放在74HC595.c文件中,如下

/********************************

74hc595.c

**************************************/

#include "hc595.h"

//595端口初始化

void HC595_port_init(void)

{

PORTG = 0x00;

DDRG |= (1 << PG0) | (1 << PG1) | (1 << PG2) | (1 << PG4);

}

//发送一个字节

void HC595_Send_Data(unsigned char byte)

{

unsigned char i;

//CLR_HC595_latch;

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

{

if(byte & 0x80)

{

SET_HC595_data;

}

else

{

CLR_HC595_data;

}

byte <<=1;

SET_HC595_sclk; //上升沿数据移位

CLR_HC595_sclk;

}

SET_HC595_latch;

CLR_HC595_latch;

}

//发送字符串

void HC595_Output_Data(unsigned char data)

{

CLR_HC595_latch; //下降沿锁存器数据不变

HC595_Send_Data(data);

SET_HC595_latch; //上升沿数据打入8位锁存器

}

在主程序中我们使用预定义语句将.h文件包含到了主程序文件中,那么我们怎样实现将.c文件编译到整个项目程序中呢?在这里我们只要在makefile文件中将这个.c文件加进去就可以了,如下图所示,在SRC = $(TARGET).C的后面空一格,然后输入我们所定义的.c文件的名称,然后保存makefile文件的更改。最后进行编译就可以了,编译的时候如果我们仔细观察编译器的输出信息,会发现不但编译了main.c文件,同时也编译了74hc595.c文件。

推荐阅读

史海拾趣

BROTHER公司的发展小趣事

BROTHER公司的历史可以追溯到1908年,当时安井兼吉在名古屋市开设了工业缝纫机维修及零部件生产的“安井缝纫机商会”。随着时间的推移,公司逐渐发展成为缝纫机领域的领导者。然而,BROTHER并没有满足于在缝纫机领域的成功,而是开始寻求跨界发展的机会。上世纪中叶,随着电子技术的兴起,BROTHER开始利用其在机械制造和精密加工方面的技术优势,涉足电子产品领域。通过不断研发和创新,BROTHER成功推出了一系列电子产品,逐渐在电子行业崭露头角。

EiKO Global LLC公司的发展小趣事

EiKO Global LLC,简称EiKO,成立于XXXX年,由一群热衷于照明科技的先驱者共同创立。公司初期专注于照明产品的研发与生产,致力于为全球用户提供高质量的照明解决方案。EiKO凭借对市场的敏锐洞察力和技术创新,迅速在北美市场崭露头角。

在创立初期,EiKO便确立了以“质量第一、客户至上”为经营理念的方针。通过引进先进的生产设备和技术,严格把控产品质量,EiKO的照明产品逐渐赢得了消费者的信赖。同时,EiKO还积极拓展市场,与多家知名企业和零售商建立了合作关系,产品销售网络遍布全球。

Cardinal Components公司的发展小趣事

1986年,Cardinal Components公司正式成立,标志着其在电子行业的起点。初创时期,公司面临着资金短缺、市场竞争激烈等诸多挑战。然而,凭借创始人的远见卓识和团队的共同努力,Cardinal迅速确立了其在宽线晶体和振荡器制造领域的专业地位。公司不断研发新产品,提高产品质量,逐渐赢得了客户的信任和市场的认可。

COMPUTAR公司的发展小趣事

进入90年代,电动变焦镜头逐渐成为市场的新宠。CBC株式会社紧跟时代潮流,于1992年成功推出电动6倍系列镜头。这款镜头采用电动变焦设计,操作简便、速度快捷,极大地提高了拍摄效率。电动6倍系列镜头的全球上市,不仅进一步扩大了CBC的市场影响力,也为公司的未来发展奠定了坚实的基础。

通过以上五个故事,我们可以看到COMPUTAR公司(前身为CBC株式会社)在电子行业中的发展历程。从创立之初的艰苦创业,到逐步拓展国际市场;从手动变焦镜头的研制成功,到非球面高速镜头和电动6倍系列镜头的诞生与上市,每一步都凝聚着COMPUTAR人的智慧和汗水。正是这些不懈的努力和持续的创新,使得COMPUTAR在电子行业中脱颖而出,成为一家备受尊敬的企业。

Altmustech公司的发展小趣事

创新是Altmustech公司发展的核心动力。公司不断投入研发资金,引进优秀人才,推动技术创新和产品升级。从最初的半导体芯片到后来的智能设备、物联网解决方案,Altmustech始终站在技术前沿,引领行业发展趋势。这种持续的创新精神使得公司在激烈的市场竞争中始终保持领先地位。

EPSON公司的发展小趣事

近年来,EPSON积极响应数字化时代的趋势,不断进行技术革新和数字化转型。公司加大了对人工智能、物联网等前沿技术的研发投入,推出了一系列智能化、数字化的电子产品和解决方案。这些创新产品不仅满足了客户日益多样化的需求,还进一步巩固了EPSON在电子行业的领先地位。同时,EPSON还积极推动数字化转型在内部管理、供应链等方面的应用,以提高企业的运营效率和市场竞争力。

问答坊 | AI 解惑

新材料可实现超快光电开关,提高光通信速度

作者:崔晓楠  日期:2006-11-1   来自 今日电子 美国华盛顿州立大学物理系研究人员近日设计出一种新型分子,其对光的传播的控制能力比现有的最好材料提高了近20倍,一旦成功用于超快光电开关,将能大大提高互联网与光通信的速度。 研究 ...…

查看全部问答>

通用串行总线(USB)原理及接口设计 I

用串行总线(USB)原理及接口设计 摘要:以USB1.1为基础讨论了USB的基本原理、工作流程、通信协议和相应的关键技术,并介绍了一种USB接口的10M以太网卡的设计方案。已经发布的USB2.0支持480Mbps的高速数据传输,这将使P ...…

查看全部问答>

达芬奇DSP算法很慢的问题

问题是这样,我用videnc_copy修改,加入我的放大算法代码,在process里面要用到width height pitch等值, 要传参数,我把这些变量放到process里面声明称局部变量并赋初值,程序就跑的很快(20ms),但是我把这几个变量 复制到process的外面(全局 ...…

查看全部问答>

探讨一下关于symbian智能手机操作系统的技术问题

探讨一下关于symbian智能手机操作系统的技术问题 各位从事symbian 智能手机研发或者从事相关电信领域工作的同弟姐妹们,我从事这方面的工作有相当长 的时间,对这个行业,包括有些技术领域有些困惑,想结识一些有同样背景的朋友们,做一下各方 ...…

查看全部问答>

如何传送信息

电子制作产品要远程传送信息需要什么样的外设来传送接收,以达到远程控制的效果…

查看全部问答>

关于CE5的补丁,做个调查,顺便散分!!!

大家做的产品,无论是量产的还是正在开发中的,都打上了CE5的补丁了吗?这些补丁全部打上之后对系统的性能会有改善或者倒退的影响吗? 我现在正在做的产品没有打任何补丁,但是总感觉电源管理有些问题,有时候睡眠唤醒收不到PBT_TRANSITION以及PBT ...…

查看全部问答>

请问这个调光台灯电路中的电容是做什么用的?

http://cl998gp.spaces.live.com/blog/cns!9F94614F95902BF0!187.entry…

查看全部问答>

正在使用FPGA- XINLINX 请教如果设置大量的寄存器

请教各位高手和版主: 如何使用RAM设置大量的寄存器?(仅仅听说这种方法,不知道是不是这样称呼)。 如果使用状态机特别的麻烦,每设置一个寄存器要使用4个状态,1k就要有4000个状态,实在是太麻烦了,请教有什么简便的方法么?谢谢了····· [ ...…

查看全部问答>

hercules菜鸟步步新建工程点亮LED(HET0)

一、环境说明:HALCoGen :版本03.05.02CCS        :版本Code Composer Studio Version:5.4.0.00091硬件        :TMS570LS031USB 二、工作目录:     CCS工作 ...…

查看全部问答>

汽车雨刮器的设计 单片机课设

1. 设计要求单臂式雨刮器,步进电机驱动,摆角+70o, 周期范围为0.5S~20S。需根据雨量传感器数据调整摆动周期。需要使用显示器显示当前雨刮器的摆动周期。雨刮器说明:为防损坏雨刮,雨刮器每步摆动角必需小于1o ,请根据这个需要选择步距角合适的步 ...…

查看全部问答>