历史上的今天
返回首页

历史上的今天

今天是:2025年12月07日(星期日)

正在发生

2022年12月07日 | 51单片机C语言程序100例分析(4)外设

2022-12-07 来源:zhihu

和我预想的一致,接下来该涉及外设了!


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


*********数码管显示*****数码管显示********************


数码管显示****************数码管显示


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


//实例60:用LED数码显示数字5


#include//包含51单片机寄存器定义的头文件


void main(void)


{


P2=0xfe;//P2.0引脚输出低电平,数码显示器接通电源准备点亮


P0=0x92;//让P0口输出数字"5"的段码92H


}

说是外设其实就是利用IO引脚而已,可见基础的重要性。


//实例61:用LED数码显示器循环显示数字0~9


#include //包含51单片机寄存器定义的头文件


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


函数功能:延时函数,延时一段时间


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


void delay(void)


{


unsigned char i,j;


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


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


;


}


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


函数功能:主函数


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


void main(void)


{


unsigned char i;


unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


//数码管显示0~9的段码表,程序运行中当数组值不发生变化时,


//前面加关键字code,可以大大节约单片机的存储空间


P2=0xfe;   //P2.0引脚输出低电平,数码显示器DS0接通电源工作


while(1)   //无限循环


{


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


{


P0=Tab[i];  //让P0口输出数字的段码92H


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


}


}


}

//实例62:用数码管慢速动态扫描显示数字"1234"


#include          //   包含51单片机寄存器定义的头文件


void delay(void)          //延时函数,延时一段时间


{


unsigned char i,j;


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


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


;


}


void main(void)


{


while(1)    //无限循环


{


P2=0xfe;   //P2.0引脚输出低电平,DS0点亮


P0=0xf9;  //数字1的段码


delay();


P2=0xfd;   //P2.1引脚输出低电平,DS1点亮


P0=0xa4;  //数字2的段码


delay();


P2=0xfb;   //P2.2引脚输出低电平,DS2点亮


P0=0xb0;  //数字3的段码


delay();


P2=0xf7;   //P2.3引脚输出低电平,DS3点亮


P0=0x99;  //数字4的段码


delay();


P2=0xff;


}



}

注意外设的原理,主要是看引脚的对接和电平的逻辑


//实例63:用LED数码显示器伪静态显示数字1234


#include              //   包含51单片机寄存器定义的头文件


void delay(void)          //延时函数,延时约0.6毫秒


{


unsigned char i;


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


;


}


void main(void)


{


while(1)    //无限循环


{


P2=0xfe;   //P2.0引脚输出低电平,DS0点亮


P0=0xf9;  //数字1的段码


delay();


P2=0xfd;   //P2.1引脚输出低电平,DS1点亮


P0=0xa4;  //数字2的段码


delay();


P2=0xfb;   //P2.2引脚输出低电平,DS2点亮


P0=0xb0;  //数字3的段码


delay();


P2=0xf7;   //P2.3引脚输出低电平,DS3点亮


P0=0x99;  //数字4的段码


delay();


P2=0xff;


}


}

//实例64:用数码管显示动态检测结果

#include     //  包含51单片机寄存器定义的头文件

#include//包含随机函数rand()的定义文件

unsigned char i;//记录中断次数

unsigned int x;//随机检测的数据

unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示0~9的段码表

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

函数功能:快速动态扫描延时,延时约0.9毫秒

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

void delay(void)

{

  unsigned int i;

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

}

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

函数功能:4位数的数码显示器显示

入口参数:k

出口参数:无

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

void display(unsigned int k)

{

  P2=0xfe;   //即P2=11111110B,P2.0引脚输出低电平,数码显示器DS0接通电源

  P0=Tab[k/1000];          //显示千位

  delay();

  P2=0xfd;   //即P2=11111101B,P2.1引脚输出低电平,数码显示器DS1接通电源

  P0=Tab[(k%1000)/100];            //显示百位

  delay();

  P2=0xfb;   //即P2=11111011B,P2.2引脚输出低电平,数码显示器DS2接通电源

  P0=Tab[(k%100)/10];   //显示十位

  delay();

  P2=0xf7;   //即P2=11110111B,P2.3引脚输出低电平,数码显示器DS3接通电源

  P0=Tab[k%10];//显示个位

  delay();

  P2=0xff;  //关闭所有显示器

}


void main(void)//主函数

{

  TMOD=0x01;//定时器0工作方式一

  TH0=(65536-46083)/256;

  TL0=(65536-46083)%256;

  EA=1;

  ET0=1;

  TR0=1;

  while(1)

  {

    display(x);//调用检测结果的显示程序

  }

}

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

函数功能:定时器T0的中断服务程序

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

void Time0(void) interrupt 1 using 1

{

  TR0=0;    //关闭定时器T0

  i++;      //每来一次中断,i自加1

  if(i==20)   //够20次中断,即1秒钟进行一次检测结果采样

  {

    x=rand()/10;      //随机产生一个从0到32767的整数,再将其除以10,获得一个随机4位数,模拟检测结果

    i=0;              //将i清0,重新统计中断次数

  }

  TH0=(65536-46083)/256;    //重新给计数器T0赋初值

  TL0=(65536-46083)%256;

  TR0=1;     //启动定时器T0

}

x在中断中发生改变,通过显示函数显示,这个函数的结构就是一个比较复杂的程序的常用结构了,包括初始化和功能块,注意逻辑分析。


//实例65:数码秒表设计


包含51单片机寄存器定义的头文件


unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示0~9的段码表


unsigned char int_time;          //记录中断次数


unsigned char second;          //储存秒


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


***


函数功能:快速动态扫描延时,延时约0.6毫秒


*********************************************************************


***/


void delay(void)


{


unsigned char i;


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


;


}


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


***


函数功能:显示秒


入口参数:k


出口参数:无


*********************************************************************


***/


void Display Second(unsigned char k)

{

  P2=0xfb;          //P2.6引脚输出低电平,DS6点亮

  P0=Tab[k/10];            //显示十位

  delay();

  P2=0xf7;         //P2.7引脚输出低电平,DS7点亮

  P0=Tab[k%10];           //显示个位

  delay();

  P2=0xff;      //关闭所有数码管

}

void main(void)//主函数

{

  TMOD=0x01;//使用定时器T0秒

  TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085微=50000微秒=50毫秒

  TL0=(65536-46083)%256;

  EA=1;//开启总中断

  ET0=1;//定时器T0中断允许

  TR0=1;//启动定时器T0开始运行

  int_time=0;//中断次数初始化

  second=0;//秒初始化

  while(1)

  {

     DisplaySecond(second);//调用秒的显示子程序

  }

}

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

//函数功能:定时器T0的中断服务程序

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

void interserve(void) interrupt 1 using 1

{

TR0=0;    //关闭定时器T0

int_time++;          //每来一次中断,中断次数int_time自加1

if(int_time==20)    //够20次中断,即1秒钟进行一次检测结果采样

{

int_time=0;     //中断次数清0

second++;     //秒加1

if(second==60)

second=0;//秒等于60就返回0

}

TH0=(65536-46083)/256;    //重新给计数器T0赋初值

TL0=(65536-46083)%256;

TR0=1;     //启动定时器T0

}


//实例66:数码时钟设计

#include//包含51单片机寄存器定义的头文件

unsigned char Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//control  shape

unsigned char port[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned char int_time;//中断次数计数变量

unsigned char second;     //秒计数变量

unsigned char minute;     //分钟计数变量

unsigned char hour;      //小时计数变量

void delay(void)//延时函数,延时约0.6ms

{

  unsigned char j;

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

}

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

函数功能:显示秒的子程序

入口参数:s

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

void Display Second(unsigned char s)

{

  P2=0xbf;          //P2.6引脚输出低电平,DS6点亮

  P0=Tab[s/10];            //显示十位

  delay();

  P2=0x7f;         //P2.7引脚输出低电平,DS7点亮

  P0=Tab[s%10];           //显示个位

  delay();

  P2=0xff;      //关闭所有数码管

}

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

函数功能:显示分钟的子程序

入口参数:m

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

void Display Minute(unsigned char m)

{

  P2=0xf7;   //P2.3引脚输出低电平,DS3点亮

  P0=Tab[m/10];//显示个位

  delay();

  P2=0xef;   //P2.4引脚输出低电平,DS4点亮

  P0=Tab[m%10];

  delay();

  P2=0xdf;   //P2.5引脚输出低电平,DS5点亮

  P0=0xbf;   //分隔符“-”的段码

  delay();

  P2=0xff;   //关闭所有数码管

}

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

函数功能:显示小时的子程序

入口参数:h

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

void Display Hour(unsigned char h)

{

  P2=0xfe;          //P2.0引脚输出低电平,DS0点亮

  P0=Tab[h/10];            //显示十位

  delay();

  P2=0xfd;         //P2.1引脚输出低电平,DS1点亮

  P0=Tab[h%10];     //显示个位

  delay();

  P2=0xfb;      //P2.2引脚输出低电平,DS2点亮

  P0=0xbf;      //分隔符“-”的段码

  delay();

  P2=0xff;      //关闭所有数码管

}

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

函数功能:主函数

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

void main(void)

{

  TMOD = 0x01;                //使用定时器T0

  EA=1;                      //开中断总允许

  ET0=1;                     //允许T0中断

  TH0=(65536-46083)/256;   //定时器高八位赋初值

  TL0=(65536-46083)%256;   //定时器低八位赋初值

  TR0=1;

  int_time=0;     //中断计数变量初始化

  second=0;       //秒计数变量初始化

  minute=0;      //分钟计数变量初始化

  hour=0;         //小时计数变量初始化

  while(1)

  {

    DisplaySecond(second);     //调用秒显示子程序

    delay();

    DisplayMinute(minute);    //调用分钟显示子程序

    delay();

    DisplayHour(hour);

    delay();

  }

}

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

函数功能:定时器T0的中断服务子程序

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

void interserve(void) interrupt 1 using 1   //usingTime0

{

  int_time++;

  if(int_time==20)

  {

    int_time=0;     //中断计数变量清0

    second++;       //秒计数变量加1

  }

  if(second==60)

 {

   second=0;     //如果秒计满60,将秒计数变量清0

   minute++;     //分钟计数变量加1

推荐阅读

史海拾趣

Foxboro I C T Inc公司的发展小趣事

在电子行业,尤其是工业自动化与控制领域,Foxboro I C T Inc(现为施耐德电气旗下的一部分,通常简称为Foxboro)的发展充满了创新与挑战。以下是五个与Foxboro在电子行业里发展起来相关的故事,每个故事均基于事实进行描述:

1. Foxboro的起源与早期创新

Foxboro的历史可以追溯到1908年,在美国马萨诸塞州的福克斯伯勒,E.H.和B.B.兄弟联手开设了商店,并逐渐发展成为一家专注于工业控制自动化的公司。1920年代,Foxboro推出了其第一款Model 10 Stabilog比例加复位控制器,这标志着公司在工业自动化领域的初步探索。此后,Foxboro持续在控制技术上取得突破,如1950年代发布的全尺寸图形面板仪表和首款磁流量计,这些创新为公司在工业控制领域奠定了坚实的基础。(参考来源:Foxboro官网及相关历史资料)

2. 分布式控制系统的先驱

进入1970年代,Foxboro推出了SPEC 200系统,这是全球第一款真正的分布式控制系统(DCS)。该系统通过分散控制、集中管理的理念,极大地提高了工业生产的效率和可靠性。SPEC 200系统的成功推出,不仅巩固了Foxboro在工业自动化领域的领先地位,也推动了整个行业向更加智能化、自动化方向发展。(参考来源:知乎专栏及相关行业报告)

3. 进入中国市场,引领自动化发展

1983年,在中美贸易合作的大背景下,Foxboro与中国上海仪电控股(集团)公司共同投资成立了上海福克斯波罗有限公司(即Foxboro中国)。作为最早的中美合资企业之一,Foxboro中国迅速将最新技术和产品引入中国,推动了中国过程自动化行业的蓬勃发展。在成立初期,Foxboro中国就完成了最新技术和产品向中国本土的转移,所生产的成套系统装置广泛应用于石油、化工、电力等多个行业。(参考来源:国际能源网及相关报道)

4. ISO 9001国际质量认证的历史性突破

1991年12月,Foxboro中国成为中国首个获得ISO 9001国际质量合格证书的企业。这一历史性突破不仅标志着Foxboro中国在质量管理上达到了国际先进水平,也为中国仪表行业乃至整个工业领域树立了标杆。此后,Foxboro中国积极分享其质量管理经验,帮助众多中国企业取得国际质量体系认证,推动了整个行业的质量提升。(参考来源:知乎专栏及相关历史资料)

5. 数字化时代的转型与升级

2014年,Foxboro被施耐德电气收购后,融入了施耐德电气的一体化能源管理与过程自动化解决方案。在此背景下,Foxboro推出了新一代EcoStruxure Foxboro DCS过程自动化系统。该系统融合了Foxboro I/A Series控制系统的可靠性和施耐德电气的数字化能力,为企业客户提供了一站式的平台服务。EcoStruxure Foxboro DCS的推出,标志着Foxboro在数字化时代迈出了重要一步,也为公司在全球工业自动化领域的持续发展注入了新的动力。(参考来源:施耐德电气官网及相关产品介绍)

Aces Electronics Co Ltd公司的发展小趣事

在发展过程中,Aces也面临过各种挑战和危机。例如,原材料价格波动、市场竞争激烈、贸易壁垒等因素都曾经给公司带来不小的压力。然而,Aces凭借敏锐的市场洞察力和强大的危机管理能力,成功应对了这些挑战。公司及时调整采购策略、优化产品结构、拓展销售渠道等措施,有效缓解了外部压力,保持了稳定的发展态势。

这些故事虽然基于假设和推测,但反映了一个电子企业在发展过程中可能遇到的各种情况。无论面对技术挑战、市场竞争还是行业变革,Aces Electronics Co., Ltd.都展现了坚韧不拔、勇往直前的精神风貌。未来,公司将继续致力于技术创新和市场拓展,为电子行业的发展贡献更多力量。

弘凯光电(BRIGHTEK)公司的发展小趣事

随着技术的不断进步和市场的逐步打开,弘凯光电开始将业务拓展至全球范围。公司的客户群迅速扩大,遍布60多个国家和地区,同时在欧洲、北美、南美、东南亚和中东地区均设立了经销网点。此外,弘凯光电还积极寻求国际认证,以证明其产品的品质和可靠性。通过取得ISO9001质量保证体系、ISO14001国际环境管理体系认证等一系列认证,公司进一步提升了品牌形象和市场竞争力。

珠海艾派克(APEXMIC)公司的发展小趣事

随着技术的不断进步,艾派克逐渐在打印机芯片领域取得了突破。公司成功研发出一系列从打印机主控SoC芯片到耗材加密芯片的全系列打印机芯片产品,不仅满足了国内市场的需求,还成功打入国际市场,成为全球打印机通用耗材芯片的重要供应商。这一成就标志着艾派克在打印机芯片领域的领先地位得到了进一步巩固。

德艺隆(DEALON)公司的发展小趣事

在激烈的市场竞争中,德艺隆始终坚持诚信经营的原则。他们严格遵守承诺,对客户提供的商业信息严格保密,不向任何第三方泄露。这种高度的诚信度赢得了客户的信任,许多客户都愿意与德艺隆建立长期合作关系。同时,德艺隆还积极参与社会公益活动,回馈社会,进一步提升了公司的品牌形象。

Fabrimex AG公司的发展小趣事

Fabrimex AG成立于1947年5月19日,总部位于瑞士苏黎世。公司最初进入电子市场是通过收购国际整流器公司(美国)的总代表处,开始涉足半导体产品。随着德州仪器活动的加入,Fabrimex AG逐渐在电子市场中稳固了地位。在这个阶段,公司积极寻求市场机会,通过多元化的产品线和灵活的商业模式,为未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

通过mini2440的蜂鸣器演奏“两只老虎”

程序模拟了音乐的七个音皆(do,re,me,fa,so,la,si),包括低音,中音及高音. 有兴趣的朋友可下载程序到target board一试,或到以下网站观看示范片段. http://v.youku.com/v_show/id_XMTQwMjI0MjI0.html 附件是作者提供的Qtopia应用程序,感兴趣的 ...…

查看全部问答>

一位值得借鉴的电子专业学长的足迹

本帖最后由 paulhyde 于 2014-9-15 09:30 编辑 在哈尔滨工程大学六年,我在学校电子创新实验室呆了四年,这四年里创新实验室给我提供了良好的学习环境和完善的实验设备;在与众多电子爱好者的交流中,使我学到了更多的专业知识;在学校老师们的教 ...…

查看全部问答>

IPHONE手机监控系统安装说明

进入 IPHONE 首先开启  IPHONE首页画面 因为本公司已将软件上传至APP STORE空间 所以接下来点选 APP STORE寻找软件 出现选择的清单页面 输入AVTECH(这是本公司产品的品牌名称),大小写都可以找的到。 这时会出现两个软件 ...…

查看全部问答>

wince找师傅带我入门

初学wince,指望高手指点下明路,要具体点的。不要什么一句话去看书。没用的,我只要快点入门。…

查看全部问答>

信号采集的问题

有没有前人做过  信号采集或者处理   音频的 采集到WinCE板的信号如何才能消除其中的直流电平偏置。 否则FFT的谱全都在0上了 .. 有没有谁知道国内的信号采集处理的 好论坛 …

查看全部问答>

请问如何设计一个类似BTS功能的设备,可以取得无线L3的消息?

  请问如何从空口中提取L3的信号,应该使用何种模块??   TC35系列芯片虽然可以处理GSM协议栈,但不知道是否可以从其端口取得空口的的消息?   现有如下思路如下:      天线 + ??1 + TC ...…

查看全部问答>

如何烧写u-boot和uClinux?

我在linux系统下编译u-boot生成u-boot、u-boot.bin和u-boot.srec三个文件,编译uClinux(2.4.x版)后生成image.ram、image.rom 和 romfs.img。请问用什么工具烧写u-boot和uClinux呢?应该烧哪些文件呢?有没有相关的文档?我之前移植ucos等都是用H- ...…

查看全部问答>

请高手指点---请教并口EPP模式通信的问题

我用电脑并口与51单片机通信的时候,采取的是EPP1.9模式,发现老是nWait=1,不知道什么原因, 有没有这方面的前辈指导一下。感谢不尽。 源码如下: #include /* inp, outp */ #include   /* kbhit() et al  */ #incl ...…

查看全部问答>

请帮忙选一个湿度传感器,最好附价格

最近要开发一个采集室内温度和湿度的模块, 相对来说温度采集的方案挺多的,湿度就相对少了, 据了解湿度采集有电阻式的、电容式的、数字式的多种, 麻烦熟悉的给比较一下各种传感器的优劣, 如果做过这方面的提供些现在使用的型号给我,最好附 ...…

查看全部问答>

51 to ARM

从8位机到32位机过渡的捷径…

查看全部问答>