第九届“蓝桥杯”单片机省赛——程序设计题
个人编写,代码仅供参考
如有不足,多多指教
1.题目
(感谢大科电子工作室的赛题图片)
2.代码
main.c程序
#include "reg52.h"
#include "iic.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0XFF};
// 0 1 2 3 4 5 6 7 8 9 - mie
sfr AUXR = 0x8e;
//=================================================参数定义
uchar flag_ing = 0;// on 1 off 0
uchar flag_shezhi = 0;// off(0)-------->模式设置(1)---------->间隔设置(2)---->
uchar liangdudengji = 0;//off 0 on 1
uint jiange;
uchar mode;
uchar pwm;
uchar i =0;
uint led_time = 0;
uint tt = 0;
uint smg_shanshuo = 0;
uchar mode3[]={0x7e,0xbd,0xdb,0xe7};
uchar mode4[]={0xe7,0xdb,0xbd,0x7e};
float ad_val;
uchar level;
uchar count = 0;
sbit S4 = P3^3;
sbit S5 = P3^2;
sbit S6 = P3^1;
sbit S7 = P3^0;
//====================================初始化一些函数
void delay(uint t)
{
while(t--);
}
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
void select(uchar channel)
{
switch(channel)
{
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;
case 0:
P2 = (P2 & 0X1F) | 0X00;
break;
}
}
void cls_relay_buz_led()
{
select(5);
P0 &= 0xaf;
select(4);
P0 = 0xff;
P2 &= 0X1F;
}
//====================================数码管
void smg_dis_all(uchar val)
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0xff;
select(7);
P0 = smg[val];
select(0);
}
void smg_dis(uchar pos , uchar val)
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0x01 << pos;
select(7);
P0 = smg[val];
select(0);
delay(500);
}
void smg_show()
{
if(flag_shezhi == 0 && liangdudengji == 0)
{
smg_dis(0,11);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,11);
smg_dis(7,11);
smg_dis_all(11);
}
else if(flag_shezhi == 1)//模式设置
{
if(jiange >= 1000)
{
if(smg_shanshuo <= 800)
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,jiange/1000);
smg_dis(5,(jiange/100)%10);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
else
{
smg_dis(0,10);
smg_dis(1,11);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,jiange/1000);
smg_dis(5,(jiange/100)%10);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
}
else
{
if(smg_shanshuo <= 800)
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,jiange/100);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
else
{
smg_dis(0,10);
smg_dis(1,11);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,jiange/100);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
}
}
else if(flag_shezhi == 2)//间隔设置
{
if(jiange >= 1000)
{
if(smg_shanshuo <= 800)
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,jiange/1000);
smg_dis(5,(jiange/100)%10);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
else
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,11);
smg_dis(7,11);
smg_dis_all(11);
}
}
else
{
if(smg_shanshuo <= 800)
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,jiange/100);
smg_dis(6,0);
smg_dis(7,0);
smg_dis_all(11);
}
else
{
smg_dis(0,10);
smg_dis(1,mode);
smg_dis(2,10);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,11);
smg_dis(7,11);
smg_dis_all(11);
}
}
}
else if(flag_shezhi == 0 && liangdudengji == 1)
{
smg_dis(0,11);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,10);
smg_dis(7,level);
smg_dis_all(11);
}
}
//====================================亮度等级设置
void level_set()
{
ad_val = ((float)read_pcf_ain3()/255.0)*5.0;
if(ad_val <= 1.25) {level = 1; pwm = 2;}
else if(ad_val >1.25 && ad_val <= 2.5) {level = 2; pwm = 5;}
else if(ad_val > 2.5 && ad_val <= 3.75) {level = 3; pwm = 10;}
else if(ad_val >3.75 && ad_val <= 5) {level = 4; pwm = 19;}
}
//====================================定时器相关函数
void Timer0Init(void) //1??@11.0592MHz
{
AUXR |= 0x80; //?????1T??
TMOD &= 0xF0; //???????
TL0 = 0xCD; //???????
TH0 = 0xD4; //???????
TF0 = 0; //??TF0??
ET0 = EA = 1;
TR0 = 1; //???0????
}
void timer0_ser() interrupt 1
{
if(flag_ing == 1)
{
if(++tt == 1)
{
switch(mode)
{
case 1 : select(4);P0 = ~(0X01 << i);select(0);break;
case 2 : select(4);P0 = ~(0X80 >> i);select(0);break;
case 3 : select(4);P0 = mode3[i] ;select(0);break;
case 4 : select(4);P0 = mode4[i] ;select(0);break;
}
}
else if(tt == pwm)
{
select(4);P0 = 0xff;select(0);
}
else if(tt == 20)
{
tt = 0;
led_time++;
if(led_time * 20 >= jiange)
{
led_time = 0;
switch(mode)
{
case 1 : i++; if(i >= 8) i = 0;break;
case 2 : i++; if(i >= 8) i = 0;break;
case 3 : i++; if(i >= 4) i = 0;break;
case 4 : i++; if(i >= 4) i = 0;break;
}
}
}
}
if(++smg_shanshuo >= 1600)
{
smg_shanshuo = 0;
}
}
//==================================按键扫描
void key_scan()
{
if(S7 == 0)
{
smg_show();
if(S7 == 0)
{
while(S7 == 0)
{
smg_show();
}
switch(flag_ing)
{
case 1 : flag_ing = 0;
break;
case 0 : flag_ing = 1;
break;
}
}
}
if(S6 == 0)
{
smg_show();
if(S6 == 0)
{
while(S6 == 0)
{
smg_show();
}
switch(flag_shezhi)
{
case 0 : flag_shezhi = 1;break;//模式设置
case 1 : flag_shezhi = 2;break;//间隔设置
case 2 : flag_shezhi = 0;write_24c02(0x00,jiange/100);Delay2ms();write_24c02(0x01,mode);Delay2ms();break;
}
}
}
if(S5 == 0)
{
smg_show();
if(S5 == 0)
{
while(S5 == 0)
{
smg_show();
}
switch(flag_shezhi)
{
case 1 : if(mode != 4){mode++;}else if(mode == 4){mode = 4;}break;
case 2 : if(jiange + 100 <= 1200){jiange += 100;}else if(jiange +100 == 1200){jiange = 1200;}break;
}
}
}
if(S4 == 0)
{
smg_show();
if(S4 == 0 && flag_shezhi != 0)
{
while(S4 == 0)
{
smg_show();
}
if(flag_shezhi != 0)
{
switch(flag_shezhi)
{
case 1 : if(mode != 1){mode--;}else if(mode == 1){mode = 1;}break;
case 2 : if(jiange -100 >= 400){jiange -= 100;}else if(jiange -100 == 400){jiange = 400;}break;
}
}
}
else if(S4 == 0 && flag_shezhi == 0)
{
while(S4 == 0)
{
liangdudengji = 1;
level_set();
smg_show();
}
liangdudengji = 0;
}
}
}
//======================================主函数
void main()
{
cls_relay_buz_led();
// write_24c02(0x00,4);//0x00 存间隔 0x01 存模式
// Delay2ms();
// write_24c02(0x01,1);
// Delay2ms();
jiange = (uint)read_24c02(0x00)*100;
Delay2ms();
mode = read_24c02(0x01);
Delay2ms();
Timer0Init();
while(1)
{
level_set();
key_scan();
smg_show();
}
}
iic.c程序
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
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; // 0:应答,1:非应答
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;
}
//=====================================
void write_24c02(uchar addr,uchar dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
uchar read_24c02(uchar addr)
{
uchar temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
//====================================
uchar read_pcf_ain3()//resistor
{
uchar ain3;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ain3 = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return ain3;
}
uchar read_pcf_ain1()//light resisitor
{
uchar ain1;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ain1 = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return ain1;
}
iic.h程序
#ifndef _IIC_H
#define _IIC_H
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 read_24c02(uchar addr);
void write_24c02(uchar addr,uchar dat);
uchar read_pcf_ain1();//light resisitor
uchar read_pcf_ain3();//resistor
#endif