在做蓝桥杯第九届省赛题的时候,遇到了这样一个题目:实现4个不同等级的LED亮度分布。

这个要求我们可以联想到第七届的省赛题,控制PWM波的输出,我们在这里也可以应用相同的原理,就是通过定时器来达到LED等不同等级的亮度分布。

目录

原理:

基础程序:

1.问题

2.程序

拓展练习:RB2的电压值控制LED灯的亮暗

原理:

假设PWM波的周期是10毫秒,通过短时间的视觉暂留效应,我们用定时器设置一个10毫秒的短周期。在10毫秒内,分出4个不同的区间(2.5毫秒,5毫秒,7.5毫秒,9.9毫秒),将这4个时间作为占空比,正周期内LED灯点亮,反周期内LED灯关闭。

基础程序:

题目:PWM脉冲信号的频率为100HZ,手动更改占空比的初始值,来控制LED灯的亮暗程度。

1.问题

我在写程序的时候,遇到了这样一个问题:LED灯和数码管产生冲突。

之前把数码管的程序写在了主函数的while循环内,LED灯放在了定时器的中断内,这样运行起来二者之间就会产生冲突。所以我把数码管的程序放在了另一个定时器的中断里,这样冲突问题即可解决。

uchar Digcom=0;
uchar Digbuf[8]={1,2,3,4,5,6,7,8};//数码管显示的初始值void Timer1Init(void)     //1毫秒@11.0592MHz
{AUXR |= 0x40;     //定时器时钟1T模式TMOD &= 0x0F;       //设置定时器模式TL1 = 0xCD;       //设置定时初始值TH1 = 0xD4;       //设置定时初始值TF1 = 0;      //清除TF1标志TR1 = 1;      //定时器1开始计时ET1=1;EA=1;
}void timer1int() interrupt 3
{ P2|=0XC0;P2&=0XDF;P0=(1<<Digcom);//0000 0001P2|=0XE0;P2&=0XFF;P0=tab[Digbuf[Digcom]];if(++Digcom==8)Digcom=0;
}

2.程序

频率为100HZ,周期T=10000微秒 (10毫秒),我们用100微秒的定时器0。

在一开始,我们先对占空比的大小(10毫秒内LED灯亮的时间)进行定义;我们更改这个值就可以控制亮暗。

uchar PWM_duty=20;//占空比为2,亮2毫秒

下面就是总程序:

#include <STC15F2K60S2.H>#define uchar unsigned char
#define uint unsigned intuchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar one,two,three,four,five,six,seven,eight;
uchar Digcom=0;
uchar Digbuf[8]={1,2,4,3,5,6,7,8};//数码管显示的初始值uint tt;uchar PWM_duty=20;//占空比 范围是0-100  周期10毫秒,定时器100微秒;所以是0-100void Allinit();
void Delayms(uint ms);
void Keyscan();
void Timer0Init(void);      //10微秒@11.0592MHz
void Timer1Init(void);      //1毫秒@11.0592MHzvoid main()
{Allinit();Timer0Init();Timer1Init();EA=1;while(1){Keyscan();}
}void timer0() interrupt 1
{tt++;if(tt==PWM_duty){P2|=0X80;P2&=0X9F;P0=0XFF;//关闭}else if(tt==100){tt=0;P2|=0X80;P2&=0X9F;P0=0XFE;//开启}
}void timer1int() interrupt 3
{ P2|=0XC0;P2&=0XDF;P0=(1<<Digcom);//0000 0001P2|=0XE0;P2&=0XFF;P0=tab[Digbuf[Digcom]];if(++Digcom==8)Digcom=0;
}void Timer0Init(void)      //100微秒@11.0592MHz
{AUXR |= 0x80;     //定时器时钟1T模式TMOD &= 0xF0;       //设置定时器模式TL0 = 0xAE;       //设置定时初始值TH0 = 0xFB;       //设置定时初始值TF0 = 0;      //清除TF0标志TR0 = 1;      //定时器0开始计时
}void Timer1Init(void)      //1毫秒@11.0592MHz
{AUXR |= 0x40;     //定时器时钟1T模式TMOD &= 0x0F;       //设置定时器模式TL1 = 0xCD;       //设置定时初始值TH1 = 0xD4;       //设置定时初始值TF1 = 0;      //清除TF1标志TR1 = 1;      //定时器1开始计时ET1=1;EA=1;
}void Keyscan()
{if(P30==0){Delayms(5);if(P30==0){ET0=1;}while(!P30);}else if(P31==0){Delayms(5);if(P31==0){ET0=0;P2=0X80;P0=0XFF;}while(!P31);}
}void Allinit()
{P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
}void Delayms(uint ms)
{uint i,j;for(i=ms;i>0;i--)for(j=845;j>0;j--);
}

拓展练习:RB2的电压值控制LED灯的亮暗

题目:通过读取RB2电压值,分成四个等级,来控制LED灯的亮暗

值得注意的是,LED点亮的程序不能直接赋值了,否则会引起RB2读取电压和定时器的冲突。

经检验,此种方法不会引起蜂鸣器的冲突。

程序如下:

#include <STC15F2K60S2.H>
#include "iic.h"
#include "intrins.h"#define uchar unsigned char
#define uint unsigned intuchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar Smg_num=0;
uchar Smg[8]={11,11,11,11,11,11,11,11};uchar LED_Bit=0XFF;
uchar light=0;
uchar ad=0;
uint tt=0;void Allinit();
void Delayms(uint ms);
void Timer0Init(void);      //1毫秒@11.0592MHz
void Timer2Init(void);      //1毫秒@11.0592MHzvoid main()
{Allinit();Timer0Init();        Timer2Init();   while(1){ad=AD_read(0X03);if(ad<64)light=1;else if((ad>=64)&&(ad<128))light=2;else if((ad>=128)&&(ad<192))light=3;else if(ad>=192)light=4;Smg[0]=light;}
}void timer0() interrupt 1
{tt++;if(light==1){if(tt==20){P2|=0X80;P2&=0X9F;LED_Bit|=0X01;P0=LED_Bit;}else if(tt==100){tt=0;P2|=0X80;P2&=0X9F;LED_Bit&=0XFE;P0=LED_Bit;}}else if(light==2){if(tt==50){P2|=0X80;P2&=0X9F;LED_Bit|=0X01;P0=LED_Bit;}else if(tt==100){tt=0;P2|=0X80;P2&=0X9F;LED_Bit&=0XFE;P0=LED_Bit;}}else if(light==3){if(tt==75){P2|=0X80;P2&=0X9F;LED_Bit|=0X01;P0=LED_Bit;}else if(tt==100){tt=0;P2|=0X80;P2&=0X9F;LED_Bit&=0XFE;P0=LED_Bit;}}else if(light==4){if(tt==100){tt=0;P2|=0X80;P2&=0X9F;LED_Bit&=0XFE;P0=LED_Bit;}}
}void Timer0Init(void)      //100微秒@11.0592MHz
{AUXR |= 0x80;     //定时器时钟1T模式TMOD &= 0xF0;       //设置定时器模式TL0 = 0xAE;       //设置定时初始值TH0 = 0xFB;       //设置定时初始值TF0 = 0;      //清除TF0标志TR0 = 1;      //定时器0开始计时ET0=1;EA=1;
}void timer2() interrupt 12
{P2|=0XC0;P2&=0XDF;P0=(1<<Smg_num);P2|=0XE0;P2&=0XFF;P0=tab[Smg[Smg_num]];  if(++Smg_num==8)Smg_num=0;
}void Timer2Init(void)      //1毫秒@11.0592MHz
{AUXR |= 0x04;     //定时器时钟1T模式T2L = 0xCD;     //设置定时初始值T2H = 0xD4;       //设置定时初始值AUXR |= 0x10;     //定时器2开始计时IE2|=0X04;EA=1;
}void Allinit()
{P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
}void Delayms(uint ms)
{uint i,j;for(i=ms;i>0;i--)for(j=845;j>0;j--);
}

iic.c的程序如下:

#include "iic.h"
#include <STC15F2K60S2.H>
#include "intrins.h"#define uchar unsigned char
#define DELAY_TIME 40sbit SDA = P2^1;
sbit SCL = P2^0;//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);
}//I2C总线启动信号
void IIC_Start(void)
{SDA = 1;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 0;IIC_Delay(DELAY_TIME);SCL = 0;
}//I2C总线停止信号
void IIC_Stop(void)
{SDA = 0;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 1;IIC_Delay(DELAY_TIME);
}//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{SCL = 0;SDA = ackbit;                    IIC_Delay(DELAY_TIME);SCL = 1;IIC_Delay(DELAY_TIME);SCL = 0; SDA = 1;IIC_Delay(DELAY_TIME);
}//等待应答
bit IIC_WaitAck(void)
{bit ackbit;SCL  = 1;IIC_Delay(DELAY_TIME);ackbit = SDA;SCL = 0;IIC_Delay(DELAY_TIME);return ackbit;
}//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){SCL  = 0;IIC_Delay(DELAY_TIME);if(byt & 0x80) SDA  = 1;else SDA  = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL  = 0;
}//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{unsigned char i, da;for(i=0; i<8; i++){   SCL = 1;IIC_Delay(DELAY_TIME);da <<= 1;if(SDA) da |= 1;SCL = 0;IIC_Delay(DELAY_TIME);}return da;
}uchar AD_read(uchar add)
{uchar temp;IIC_Start();IIC_SendByte(0X90);IIC_WaitAck();IIC_SendByte(add);IIC_WaitAck();IIC_Stop();IIC_Start();IIC_SendByte(0X91);IIC_WaitAck();   temp=IIC_RecByte();IIC_Stop();return temp;
}uchar EEPROM_read(uchar add)
{uchar temp;IIC_Start();IIC_SendByte(0XA0);IIC_WaitAck();IIC_SendByte(add);IIC_WaitAck();IIC_Stop();IIC_Start();IIC_SendByte(0XA1);IIC_WaitAck();   temp=IIC_RecByte();IIC_Stop();return temp;
}void EEPROM_write(uchar add,uchar dat)// EEEPROM 存储
{IIC_Start();IIC_SendByte(0XA0);IIC_WaitAck();IIC_SendByte(add);IIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();
}void DA_write(uchar dat)// DA 输出电压(让板子显示你想让它显示的电压)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x40);IIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();
}

iic.h的程序如下:

#ifndef _IIC_H
#define _IIC_H#include <STC15F2K60S2.H>
#include "intrins.h"#define uchar unsigned char//sbit SDA = P2^1;
//sbit SCL = P2^0;void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
uchar AD_read(uchar add);
uchar EEPROM_read(uchar add);
void EEPROM_write(uchar add,uchar dat);
void DA_write(uchar dat);#endif

PWM波控制LED灯的亮暗相关推荐

  1. 红外控制LED灯的亮灭———Arduino

    Arduino的中文社区:https://www.arduino.cn/ \黑脸,今天烧坏一个二极管. 原因:正负极没反,没接电阻. 把自己头打烂了- 1. 所需硬件 开发板,led灯(多个),遥控器 ...

  2. c语言程序小灯从右向左闪烁,单片机控制LED灯点亮(C语言).PPT

    <单片机控制LED灯点亮(C语言).PPT>由会员分享,可在线阅读,更多相关<单片机控制LED灯点亮(C语言).PPT(45页珍藏版)>请在人人文库网上搜索. 1.1,单片机控 ...

  3. 单片机基础:开关控制LED灯的亮灭

    (一) 单片机的初级运用.通过两个开关来控制LED灯的亮灭.首先要使用Proteus来绘制电路原理图.图中的LED灯为共阴接法.如图: (二)当单片机P3口做输入时,首要让其端口输出1.如图中的P3^ ...

  4. Java 通过GPIO控制LED灯的亮灭(一)

    Java 通过GPIO控制LED灯的亮灭(Firefly-RK3399)(一) Note: 为Android 开发,开发工具AndroidStudio 什么是 GPIO ,(General-purpo ...

  5. cc2530 按键中断实验——按键控制LED灯的亮灭

    在本次学习中,主要通过外部中断来控制LED的亮灭. 首先,先查看相关电路图.由图可知,当CC2530端口1的1号引脚输出低电平时,LED3将被点亮,当按键31按下时,端口1的1号引脚将为低电平,抬起时 ...

  6. 串口接收字符/字符串/定向printf串口发送/用串口控制led灯的亮灭

    ##usart.h//串口头文件 #include "stm32f10x.h" #include <stdio.h> void usart_init(); void U ...

  7. 【补作业】msp430单片机(一)控制LED灯的亮灭

    硬件描述 两个LED灯: P1.0接LED1(红),P4.7接LED2(绿). IO口输出高电平时,LED亮 IO口输出低电平时,LED灭 点亮红灯 (ccs中的c语言代码,用430进行调试) P1口 ...

  8. 嵌入式开发控制LED灯的亮灭

    目录 一.创建项目 背景: 1.选好自己需要的开发板(这里使用的STM32F103C8T6的开发板) 2.引脚配置 3.EXIT配置 4.配置SYS 5.配置GPIO 6.项目配置 二.Keil配置 ...

  9. 按钮控制LED灯的亮灭

    实验通过主板自带的小灯泡和按钮实现通过按钮来控制小灯泡的亮灭. 对按钮的输入次数进行判断从而进行控制灯的亮灭. volatile int b1; volatile int b2; volatile i ...

最新文章

  1. 分布式事物-2pc和3pc区别
  2. smtplib python教程_python使用smtplib模块发送邮件
  3. REdis AOF文件结构分析
  4. 通过修改注册表,实现网页链接中的私有协议启用本地exe进程
  5. COOKIE伪造登录网站后台
  6. Nagios 使用 NSClient++ 监控Windows Server
  7. Zookeeper基本概念
  8. go java websocket_java的连接wss的websocket服务器代码如何转成go代码
  9. python 编码报错问题 'ascii' codec can't encode characters 解决方法
  10. php里面什么是u函数,ThinkPHP内置函数----U方法
  11. android listview 行高度自适应,Android ListView 长度自适应item的内容 计算listview的高度...
  12. 分享一篇去年的项目总结
  13. access笔试答案_ACCESS数据库考试试题及答案
  14. selenium打开浏览器报错问题
  15. PLC通讯实现-C#实现欧姆龙以太网通讯FINS UDP(三)
  16. android 功能防抖,Android RxJava 实际应用讲解:功能防抖
  17. 【数论】扩展欧几里得算法(EXTENDED-EUCLID)
  18. 0x3f3f3f3f_《羊卓的杨的算法笔记》_Quentin
  19. 滚动轴承特征频率计算推导过程
  20. 深圳租房数据可视化分析【Plotly库绘图】

热门文章

  1. 《离散数学及其应用》读书笔记【三】计数
  2. ln lg,log在c语言中的表示-----转载自yam_killer的专栏
  3. TensorFlow实现Pix2Pix
  4. 解决windws 2003系统上网站不能访问, IIS 403 404问题
  5. MATLAB中散点图的绘制方法
  6. 【Joy of Cryptography 读书笔记】Chapter 1 一次性密码本(one-time pad)Kerckhoffs原则
  7. 佳博58系列小票机 android 打开钱箱
  8. windows下安装ubuntu20.04双系统
  9. STM32F207VET+DP83848PHY驱动移植的笔记
  10. python脚本教程-总算懂得python脚本快速入门教程