蓝桥杯-单片机组基础7-存储器映射扩展与PWM脉冲调制(附小蜜蜂课程代码)

本文主要是介绍蓝桥杯-单片机组基础7-存储器映射扩展与PWM脉冲调制(附小蜜蜂课程代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

蓝桥杯单片机组备赛指南请查看这篇文章:戳此跳转蓝桥杯备赛指南文章

本文章针对蓝桥杯-单片机组比赛开发板所写,代码可直接在比赛开发板上使用。

型号:国信天长4T开发板(绿板),芯片:IAP15F2K61S2

(使用国信天长蓝板也可以完美兼容,与绿板几乎无差别)


1.存储器映射拓展

(截取自小蜜蜂单片机课程视频)

   存储器映射拓展方式的地址:

0x8000指示灯
0xa000蜂鸣器与继电器
0xc000数码管位选
0xe000数码管段选

 在比赛当中,建议还是只使用IO口拓展方式,尽量不使用存储器映射拓展方式。

注意:

进行存储器映射拓展时,需要将开发板J13的跳线帽连接到“MM模式”

使用XBYTE关键字,需要引入头文件“ absacc.h ”来操作拓展资源

存储器拓展方式要占用单片机的P3.6引脚,会与矩阵键盘的引脚冲突

1.1 代码参考

        在主函数中进行选择,对state_all赋不同初值,获得不同的效果。

1——蜂鸣器与数码管;2——蜂鸣器单独作用;3——数码管单独作用(默认)

#include < reg52.h >
#include < intrins.h >
#include < absacc.h >//使用定时器1实现延时效果
//使用四个独立按键实现类型选择unsigned char code SMG_duanma [18]={ 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 , 0x88 , 0x80 , 0xc6 , 0xc0 , 0x86 , 0x8e ,0xbf , 0x7f };void Delay ( unsigned char time )
{unsigned char i,j;if ( time%2 == 0 ){time /= 2;}else {time = (time/=2) + 1;}while ( time-- ){_nop_ ();_nop_ ();i=22;j=128;do {while ( --j );}while ( --i );}
}void ledrunning ( unsigned char linspace )
{unsigned char i,state_led;for ( i=0 ; i<8 ; i+=linspace ){state_led = 0xff;state_led &= ~( 1<<i );XBYTE[0x8000] = state_led;Delay (500);}
}void buzzrunning ( unsigned char buzz_state )
{if ( buzz_state == 0 )XBYTE[0xa000] = 0x00;else XBYTE[0xa000] = 0xff;
}void SMG_running ( )
{unsigned char i,j;for ( i=0 ; i<7 ; i++ ){XBYTE[0xc000] = 0x01 << i;for ( j=0 ; j<10 ; j++ ){			XBYTE[0xe000] = SMG_duanma [j];Delay (500);}}}void main ()
{unsigned char state_all = 3;while (1){if ( state_all == 1 ){buzzrunning (0);ledrunning (1);}else if ( state_all == 2 ){buzzrunning (0);Delay ( 400 );buzzrunning (1);Delay ( 400 );}else if ( state_all == 3 ){buzzrunning (0);SMG_running ();}}
}

2.PWM脉冲宽度调制

2.1 pwm脉冲调制的作用效果

        比较通俗的来说,pwm脉冲调制,可以让我们自定义灯光的亮度,使得LED灯可以产生不同的亮度;自定义电机的转速,使得电机可以以不同的速度旋转;自定义蜂鸣器的嗡叫大小,使得蜂鸣器也可以小声歌唱……

        比较专业的来说则是:脉冲宽度调制PWM是通过将有效的电信号分散成离散形式从而来降低电信号所传递的平均功率的一种方式。所以根据面积等效法则,可以通过对改变脉冲的时间宽度,来等效的获得所需要合成的相应幅值和频率的波形,实现模拟电路的数字化控制。PWM信号是通过调节占空比的变化来调节信号、能量等的变化。

2.2 什么是PWM

        PWMPulse-width modulation),中文名脉冲宽度调制。下面我采用功率的思路来理解PWM的作用。

        在我们之前的编程中,单片机的引脚通过赋值1或0,从而输出5v或0v的电压。如下图所示:

        在1个周期中,可以看出单片机引脚的输出电压恒定为5v,假设引脚上接了一个5欧姆的电阻,则该电阻获得的功率是恒定的,W=U^2/R=5^2/5=5瓦特。如果我们希望电阻上的功率低一些怎么办?根据W=Q/t式子,分子Q与电压直接相关,而电压由硬件电路决定无法改变;分母t与我们使单片机引脚为高电平的时间有关,可以通过编程更改。因此,我们可以设置在一个周期中,单片机引脚处于高电平的时长,从而改变输出功率,让电阻的功率降低。

        假设我们要使电阻上的功率为3w,由面积等效规律可得出,在一个周期中高电平应该占据60%的时长,画出电压图像为:

        通过设置在一个周期中,高电平与低电平所占时长的比例,即可实现0~最大功率之间的功率输出。其中,高电平所占的时长我们称为占空比(Duty cycle),通常规定其数值为0~100%,当占空比为100%时即表示最大功率输出。

2.3 pwm的编程原理

        在编程时,我们可以利用定时/计数器生成一个100个时钟序列的周期,在时钟序列累加值低于占空比数值时输出高电平,时钟序列累加值高于占空比数值时输出低电平,从而实现一个周期中的脉冲宽度调制。

        我们定义两个变量,pwm_count和pwm_duty:

        pwm_count 变量用于计数一个周期中的时钟序列个数。采用定时/计数器中断设置时钟序列间隔,通常可以设置为0.1ms,每经历一次0.1ms,通过中断使该变量自增1 。因为占空比在0~100之间变化,为了方便我们也设置该变量在计数值达到100时清零。

        pwm_duty变量用于定义占空比。在编写函数时,当pwm_count<pwm_duty时,我们令引脚输出高电平,反之输出低电平。在调用函数时,通过向函数中传递0~100以内的数值,从而设置引脚输出功率在最大功率的0~100%之间变化。

2.4 pwm的代码参考

        代码效果://按键S7通过控制pwm来控制LED1的亮度

//按键S7通过控制pwm来控制LED1的亮度
#include < REGX52.h >
#include < INTRINS.h >sbit S7 = P3^0;
sbit L1 = P0^0;void select_HC573 ( unsigned char channal )
{switch ( channal ){case 4:P2 = ( P2 & 0x1f ) | 0x80;break;case 5:P2 = ( P2 & 0x1f ) | 0xa0;break;case 6:P2 = ( P2 & 0x1f ) | 0xc0;break;case 7:P2 = ( P2 & 0x1f ) | 0xe0;break;}
}void Delay ( unsigned char value_delay )
{while ( value_delay -- ){unsigned char i,j;		_nop_ ();_nop_ ();i = 22;j = 128;do{while ( --j );}while ( --i );}
}unsigned char key_value = 1;
void scan_key ()
{if ( S7 == 0 ){Delay ( 3 );if ( S7 == 0 ){while ( S7 == 0 );key_value ++ ;if ( key_value == 5 ){key_value = 1;}}}
}//=============================================
void Init_Timer0 ()
{TMOD = 0x01;TH0 = ( 65535 - 100 ) / 256;TL0 = ( 65535 - 100 ) % 256;ET0 = 1;EA = 1;TR0 = 1;
}unsigned char pwm_count = 0;
void Service_Timer0 () interrupt 1
{TH0 = ( 65535 - 100 ) / 256;TL0 = ( 65535 - 100 ) % 256;pwm_count++;
}//===============================================void set_pwm ( unsigned char duty_pwm )
{if ( pwm_count <= duty_pwm ){L1 = 0;}else if ( pwm_count < 100 ){L1 = 1;}else if ( pwm_count == 100 ){pwm_count = 0;}	
}void L1_pwmrunning ()
{switch ( key_value ){case 1:TR0 = 0;L1 = 1;		break;case 2:TR0 = 1;set_pwm ( 10 );break;			case 3:
//			TR0 = 1;set_pwm ( 50 );break;			case 4:
//			TR0 = 1;set_pwm ( 90 );break;}
}void main ()
{select_HC573 ( 4 );Init_Timer0 ();while ( 1 ){scan_key ();L1_pwmrunning ();}
}

3.PWM脉冲宽度调制编程思路重述

        通过定时/计数器设置100个时钟序列,通过计数时钟序列,并于占空比进行比较确定输出高电平或者低电平。到计数值小于占空比时输出高电平,大于占空比时输出低电平。

这篇关于蓝桥杯-单片机组基础7-存储器映射扩展与PWM脉冲调制(附小蜜蜂课程代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/766581

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

Spring的基础事务注解@Transactional作用解读

《Spring的基础事务注解@Transactional作用解读》文章介绍了Spring框架中的事务管理,核心注解@Transactional用于声明事务,支持传播机制、隔离级别等配置,结合@Tran... 目录一、事务管理基础1.1 Spring事务的核心注解1.2 注解属性详解1.3 实现原理二、事务事

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill