【蓝桥杯单片机组第九届省赛】— “彩灯控制器”的程序设计与调试

1、试题

一、基本要求

1.1 使用 CT107D 单片机竞赛板,完成“彩灯控制器” 功能的程序设计与调试;
1.2 设计与调试过程中,可参考组委会提供的“资源数据包”;
1.3 Keil 工程文件以准考证号命名,完成设计后,提交完整、可编译的 Keil工程文件到服务器。

二、硬件框图

三、功能描述 

3.1 基本功能描述

       通过单片机控制 8 个 LED 指示灯按照特定的顺序(工作模式) 亮灭; 指示灯的流转间隔可通过按键调整,亮度可由电位器 RB2 进行控制; 各工作模式的流转间隔时间需在 E2PROM 中保存,并可在硬件重新上电后,自动载入。

3.2 设计说明

(1)关闭蜂鸣器、继电器等与本试题程序设计无关的外设资源
(2)设备上电后默认数码管、 LED 指示灯均为熄灭状态;
(3)流转间隔可调整范围为 400ms-1200ms;
(4)设备固定按照模式 1、模式 2、模式 3、 模式 4 的次序循环往复运行。

3.3 LED 指示灯工作模式

(1)模式 1: 按照 L1、 L2…L8 的顺序, 从左到右单循环点亮。

(2)模式 2: 按照 L8、 L7…L1 的顺序, 从右到左单循环点亮。

(3)模式 3:

(4)模式4:

3.4 亮度等级控制

       检测电位器 RB2 的输出电压,控制 8 个 LED 指示灯的亮度,要求在 0V-5V的可调区间内,实现 4 个均匀分布的 LED 指示灯亮度等级。

3.5 按键功能

(1)按键 S7 定义为“启动/停止”按键,按下后启动或停止 LED 的流转。

(2)按键 S6 定义为“设置”按键,按键按下后数码管进入“流转间隔”设置界面,如下图所示:

   通过按键 S6 可切换选择“运行模式” 和“流转间隔” 两个显示单元,当前被选择的显示单元以 0.8 秒为间隔亮灭。

 (3)按键 S5 定义为“加”按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号加 1,若当前选择的是流转间隔,则流转间隔增加 100ms。

(4)按键 S4 定义为“减”按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号减 1,若当前选择的是流转间隔,则流转间隔减少 100ms。

(5)按键功能说明:

     (a)按键 S4、 S5 的“ 加”、 “ 减” 功能只在“设置状态”下有效,数值的调整应注意边界属性。

     (b)在非“设置状态”下,按下 S4 按键可显示指示灯当前的亮度等级, 4 个亮度等级从暗到亮,依次用数字 1、 2、 3、 4 表示; 松开S4 按键,数码管显示关闭, 亮度等级的显示格式如下图所示:

2、试题分析

模拟输入:要掌握PCF8591芯片上的AD转换。

按键控制:S7(P30),S6(P31),S5(P32),S4(P33)。

LED指示灯:初始化、P0端口低电平亮。

IIC总线控制、数码管显示。

E2PROM读取断电后的数据。

最后是PWM脉冲宽度调制技术控制led的亮度。对于PWM的解释可见博客:

 https://blog.csdn.net/fanjufei123456/article/details/105025590

还有一些细节上的连接问题,需要自己动手操作。

蓝桥杯第九届省赛和第八届省赛,赛题还是比较相似的,按键控制方式都基本上一样的模式,第八届有实时时钟、温度传感器等,第九届是AD、IIC总线、EEPROM、PWM控制,另外PWM可能是个问题点。

3、代码

 iic.c

#include "iic.h"

//总线启动条件
void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

unsigned char AD_Read(unsigned char add)
{
		unsigned char 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;
}

//EEPROM读
unsigned char EEPROM_Read(unsigned char add)
{
		unsigned char 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;
}


//EEPROMD写
void EEPROM_Write(unsigned char dat,unsigned char add)
{
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck();
		IIC_SendByte(add);
		IIC_WaitAck();
	
		IIC_SendByte(dat);
		IIC_WaitAck();
	
		IIC_Stop();
	 
}

 iic.h

#ifndef _IIC_H
#define _IIC_H

#include "stc15f2k60s2.h"
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 

unsigned char AD_Read(unsigned char add);
unsigned char EEPROM_Read(unsigned char add);
void EEPROM_Write(unsigned char dat,unsigned char add);

#endif

 text.c

#include<stc15f2k60s2.h>
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

uchar start=0;
uchar moshi=1;
uchar zhuanhua=0;
uint jiange=400;
uint led_t=0;
uint zhuanhua_t=0;
uint ad_t=0;
uint RB2=0;
uchar flag=0;
uchar led_n=0;
uchar led_TT=0,light=0;
uchar f1,f2,f3,f4,f5,f6,f7,f8;

void allinit();
void delayms(uchar ms);
void keyscan();
void Time0_init();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);

void main(){
allinit();
Time0_init();
moshi=EEPROM_Read(0x10);
delayms(5);
jiange=EEPROM_Read(0x20)*100;
delayms(5);
f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=11;f8=11;
while(1){
    if((zhuanhua==0)&&(flag==1))
	{
	   if(RB2<64)
	   {
	     f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=10;f8=1;
	   }
	   else if((RB2>=64)&&(RB2<128))
	   {
	     f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=10;f8=2;
	   }
	   else if((RB2>=128)&&(RB2<192))
	   {
	     f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=10;f8=3; 
	   }
	   else if((RB2>=192)&&(RB2<255))
	   {
	     f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=10;f8=4;
	   }
	}
	else if(zhuanhua==0)
	 {
	   f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=11;f8=11;
	 }
	 keyscan();
	 display12(f1,f2);
	 display34(f3,f4);
	 display56(f5,f6);
	 display78(f7,f8);
}

}
void keyscan(){
if(P30==0)
{
  delayms(5);
  if(P30==0)
  {
    if(start==0)
	{
	  start=1;
	}
	else if(start==1)
	{
	  start=0;
	}
}
while(!P30);
}

else if(P31==0)
{
  delayms(5);
  if(P31==0)
  {
    if(zhuanhua==0)
	{
	  zhuanhua=1;zhuanhua_t=0;
	  if(jiange>=1000)
	  {
	    f1=10;f2=moshi;f3=10;f4=11;f5=jiange/1000;f6=jiange%1000/100;f7=jiange%100/10;f8=jiange%10;
	  }
	  else
	  {
	    f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=jiange/100;f7=jiange%100/10;f8=jiange%10;
	  }
	}
	else if(zhuanhua==1)
	{
	  zhuanhua=2;zhuanhua_t=0;
	  if(jiange>=1000)
	  {
	    f1=10;f2=moshi;f3=10;f4=11;f5=jiange/1000;f6=jiange%1000/100;f7=jiange%100/10;f8=jiange%10;
	  }
	  else
	  {
	    f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=jiange/100;f7=jiange%100/10;f8=jiange%10;
	  }
	}
	else if(zhuanhua==2)
	{
	  zhuanhua=0;zhuanhua_t=0;
	  f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;f7=11;f8=11;
	  EEPROM_Write(moshi,0x10);
	  delayms(5);
	  EEPROM_Write(jiange/100,0x20);
	  delayms(5);
	}
}
while(!P31);
}

else if(P32==0)
{
  delayms(5);
  if(P32==0)
  {
     if(zhuanhua==1)
	 {
	   moshi+=1;
	   if(moshi==5)
	   {
	     moshi=1;
	   }
	 }
	 else if(zhuanhua==2)
	 {
	   jiange+=100;
	   if(jiange==1300)
	   {
	     jiange=400;
	   }
	 }
   }
while(!P32);
}

else if(P33==0)
{
  delayms(5);
  if(P33==0)
  {
    flag=1;
  }
}

if((P33==1)&&(flag==1))
{
  flag=0;
  if(zhuanhua==1)
  {
    moshi-=1;
	if(moshi==0)
	{
	  moshi=4;
	}
  }
  else if(zhuanhua==2)
  {
    jiange-=100;
	if(jiange==300)
	{
	  jiange=1200;
	}
  }
}
}

void Time0_init(){
TMOD=0X01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TR0=1;
EA=1;
ET0=1;
}

void Time0_service() interrupt 1
{
 TH0=(65536-1000)/256;
 TL0=(65536-1000)%256;
 zhuanhua_t++;
 led_t++;
 ad_t++;
 if((led_t==1)&&(start==1))
 {
   if(moshi==1)
   {
    P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	P0=~(0X01<<led_n);
   }
   else if(moshi==2)
   {
    P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	P0=~(0X80>>led_n);
   }
   else if(moshi==3)
   {
     P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	 if(led_n==0) P0=0X7E;
	 else if(led_n==1) P0=0XBD;
	 else if(led_n==2) P0=0XDB;
	 else if(led_n==3) P0=0XE7;
   }
   else if(moshi==4)
   {
     P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	 if(led_n==0) P0=0XE7;
	 else if(led_n==1) P0=0XDB;
	 else if(led_n==2) P0=0XBD;
	 else if(led_n==3) P0=0X7E;
   }
 }
 else if(led_t==light)
 {
   	P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
 }
 else if(led_t==20)
 {
    led_t=0;led_TT++;
	if(20*led_TT>=jiange)
	{
	  led_TT=0;
	  if(moshi==1)
	  {
	     led_n++;
		 if(led_n>=8)
		 {
		   led_n=0;
		 }
	  }
	  else if(moshi==2)
	  {
	     led_n++;
		 if(led_n>=8)
		 {
		   led_n=0;
		 }
	  }
	  else if(moshi==3)
	  {
	     led_n++;
		 if(led_n>=4)
		 {
		   led_n=0;
		 }
	  }
	  else if(moshi==4)
	  {
	    led_n++;
		if(led_n>=4)
		{
		  led_n=0;
		}
	  }
	}
  }
  if(ad_t==200)
  {
    ad_t=0;
	RB2=AD_Read(0x03);
	if(RB2<64) light=2;
	else if((RB2>=64)&&(RB2<128)) light=5;
	else if((RB2>=128)&&(RB2<192)) light=10;
	else if((RB2>=192)&&(RB2<255)) light=19;
  }

  if(zhuanhua_t==800)
  {
     if(zhuanhua==1)
	 {
	   if(jiange>=1000)
	   {
	      f1=11;f2=11;f3=11;f4=11;f5=jiange/1000;f6=jiange%1000/100;f7=jiange%100/10;f8=jiange%10;
	   }
	   else
	   {
	      f1=11;f2=11;f3=11;f4=11;f5=11;f6=jiange/100;f7=jiange%100/10;f8=jiange%10;
	   }
	 }
	 else if(zhuanhua==2)
	 {
	   if(jiange>=1000)
	   {
	      f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=11;f7=11;f8=11;
	   }
	   else
	   {
	      f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=11;f7=11;f8=11;
	   }
	 }
  }

  if(zhuanhua_t==1600)
  {
    zhuanhua_t=0;
	if(zhuanhua==1)
	{
	   if(jiange>=1000)
	   {
	     f1=10;f2=moshi;f3=10;f4=11;f5=jiange/1000;f6=jiange%1000/100;f7=jiange%100/10;f8=jiange%10;
	   }
	   else
	   {
	      f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=jiange/100;f7=jiange%100/10;f8=jiange%10;
	   }
	}
	else if(zhuanhua==2)
	{
	   if(jiange>=1000)
	   {
	     f1=10;f2=moshi;f3=10;f4=11;f5=jiange/1000;f6=jiange%1000/100;f7=jiange%100/10;f8=jiange%10;
	   }
	   else
	   {
	      f1=10;f2=moshi;f3=10;f4=11;f5=11;f6=jiange/100;f7=jiange%100/10;f8=jiange%10;
	   }
	} 
 }
} 
 
void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void delayms(uchar ms){
uchar i,j,k;
for(k=ms;k>0;k--){
   i=12;
   j=169;
   do
   {
      while(j--);
   }
   while(i--);
 }
}

void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delayms(1);
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delayms(1);
}

void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delayms(1);
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delayms(1);
}

void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delayms(1);
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delayms(1);
}

void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delayms(1);
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delayms(1);
}

发布了64 篇原创文章 · 获赞 70 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/fanjufei123456/article/details/105008801