2025年3月31日 星期一 乙巳(蛇)年 正月初一 设为首页 加入收藏
rss
您当前的位置:首页 > 电子 > 单片机

第九届蓝桥杯单片机省赛----程序题

时间:06-17来源:作者:点击数:54

第九届蓝桥杯单片机省赛----程序题

main.c程序

  • #include<stc15f2k60s2.h>
  • #include "iic.h"
  • #define uchar unsigned char //定义无符号字符类型uchar
  • #define uint unsigned int //定义无符号整型类型uint
  • uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
  • uchar yi,er,san,si,wu,liu,qi,ba; //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
  • uchar mode3[]={0x7e,0xbd,0xdb,0xe7};
  • uchar mode4[]={0xe7,0xdb,0xbd,0x7e};
  • uchar AD,mode,i=0,shezhi=0,qidong=0,Dj=0,dengji,LEDtime;
  • uint jiange,tt=0,shezhi_tt=0,LED_TT=0;
  • bit s4=0;
  • void delayms(int ms); //延时函数
  • void allinit(); //初始化函数
  • void keyscan16(); //矩阵按键函数
  • void keyscan(); //独立按键函数
  • void display1(uchar yi,uchar er); //第一、二段数码管函数
  • void display2(uchar san,uchar si); //第三、四段数码管函数
  • void display3(uchar wu,uchar liu); //第五、六段数码管函数
  • void display4(uchar qi,uchar ba); //第七、八段数码管函数
  • void Timer0Init(void); //1毫秒@12.000MHz
  • void main()
  • {
  • allinit();
  • Timer0Init();
  • yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
  • // EEPROM_write(0x00,40);delayms(2);EEPROM_write(0x01,1);delayms(2);
  • jiange=EEPROM_read(0x00)*10;
  • mode=EEPROM_read(0x01);
  • while(1)
  • {
  • AD=AD_read(0x03); //调用IIC驱动里的AD_read函数,利用RB2模拟电压值
  • if(AD<64){dengji=1;LEDtime=2;} //判断AD的值是否小于64,即小于1.25V,亮度等级位1级,PWM占空比设置为10%左右
  • else if((AD>=64)&&(AD<128)){dengji=2;LEDtime=5;} //判断AD的值是否大于等于64且小于128,即大于等于1.25V小于2.5V,亮度等级位2级,PWM占空比设置为25%左右
  • else if((AD>=128)&&(AD<192)){dengji=3;LEDtime=10;} //判断AD的值是否大于等于128且小于192,即大于等于2.5V小于3.75V,亮度等级位3级,PWM占空比设置为50%左右
  • else if(AD>=192){dengji=4;LEDtime=19;} //判断AD的值是否大于等与192,即大于等于3.75V,亮度等级位4级,PWM占空比设置为100%左右
  • if(shezhi==0)
  • {
  • yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;//数码管全灭
  • }
  • else if(shezhi==1) //设置模式编号界面
  • {
  • if(jiange>=1000) //判断流转间隔时间是否大于1000,目的是让流转间隔时间不足4位的让最高位数码管熄灭。
  • {
  • if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
  • else {yi=10;er=11;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
  • }
  • else
  • {
  • if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
  • else {yi=10;er=11;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
  • }
  • }
  • else if(shezhi==2) //设置流转间隔界面
  • {
  • if(jiange>=1000) //判断流转间隔时间是否大于1000,目的是让流转间隔时间不足4位的让最高位数码管熄灭。
  • {
  • if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=jiange/1000;liu=jiange%1000/100;qi=jiange%100/10;ba=jiange%10;}
  • else {yi=10;er=mode;san=10;si=11;wu=11;liu=11;qi=11;ba=11;}
  • }
  • else
  • {
  • if(shezhi_tt<=800){yi=10;er=mode;san=10;si=11;wu=11;liu=jiange/100;qi=jiange%100/10;ba=jiange%10;}
  • else {yi=10;er=mode;san=10;si=11;wu=11;liu=11;qi=11;ba=11;}
  • }
  • }
  • if(Dj==1) //亮度等级显示页面
  • {
  • yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=10;ba=dengji;
  • }
  • keyscan(); //独立按键函数
  • display1(yi,er); //第一、二段数码管函数
  • display2(san,si); //第三、四段数码管函数
  • display3(wu,liu); //第五、六段数码管函数
  • display4(qi,ba); //第七、八段数码管函数
  • }
  • }
  • void keyscan()//独立按键函数
  • {
  • if(P30==0) //判断P30是否等于0
  • {
  • delayms(5); //延时5ms
  • if(P30==0) //再次判断P30是否等于0
  • {
  • if(qidong==0)qidong=1; //判断是否为未启动状态,是的话按键按下后启动
  • else if(qidong==1)qidong=0;//判断是否为启动状态,是的话按键按下后停止
  • }
  • while(!P30); //如果按键不松开,则一直循环
  • }
  • else if(P31==0) //判断P31是否等于0
  • {
  • delayms(5); //延时5ms
  • if(P31==0) //再次判断P31是否等于0
  • {
  • if(shezhi==0)shezhi=1; //判断是否在非设置页面,是的话按键按下后进入到设置模式页面
  • else if(shezhi==1)shezhi=2; //判断是否在设置模式页面,是的话按键按下后进入到设置流转间隔页面
  • else if(shezhi==2)
  • {
  • shezhi=0;
  • EEPROM_write(0x00,jiange/10);delayms(2);
  • EEPROM_write(0x01,mode);delayms(2);
  • }//判断是否在设置流转间隔页面,是的话按键按下后进入到非设置页面,保存模式和流转间隔到EEPROM中
  • }
  • while(!P31); //如果按键不松开,则一直循环
  • }
  • else if(P32==0) //判断P32是否等于0
  • {
  • delayms(5); //延时5ms
  • if(P32==0) //再次判断P32是否等于0
  • {
  • if(shezhi==1) //设置模式页面下按键
  • {
  • if(mode==4)mode=4;//判断模式是否等于4,是的话模式还等于4
  • else mode=mode+1; //不是的话模式+1
  • }
  • else if(shezhi==2) //设置流转间隔页面下按键
  • {
  • if(jiange==1200)jiange=1200;//判断流转间隔是否等于1200,是的话模式还等于1200
  • else jiange=jiange+100; //不是的话流转间隔+100
  • }
  • }
  • while(!P32); //如果按键不松开,则一直循环
  • }
  • else if(P33==0) //判断P33是否等于0
  • {
  • delayms(5); //延时5ms
  • if(P33==0) //再次判断P33是否等于0
  • {
  • s4=1; //s4标志位置1
  • if(shezhi==0)Dj=1;//非设置状态下,按键按下进入到等级显示页面
  • }
  • }
  • else if((s4==1)&&(P30==1))
  • {
  • s4=0;Dj=0; //s4标志位清零,Dj标志位清零
  • if(shezhi==1) //设置模式页面下按键
  • {
  • if(mode==1)mode=1;//判断模式是否等于1,是的话模式还等于1
  • else mode=mode-1; //不是的话模式-1
  • }
  • else if(shezhi==2) //设置流转间隔页面下按键
  • {
  • if(jiange==400)jiange=400;//判断流转间隔是否等于400,是的话模式还等于400
  • else jiange=jiange-100; //不是的话流转间隔-100
  • }
  • }
  • }
  • void Timer0Init(void) //1毫秒@12.000MHz
  • {
  • AUXR |= 0x80; //定时器时钟1T模式
  • TMOD &= 0xF0; //设置定时器模式
  • TL0 = 0x20; //设置定时初值
  • TH0 = 0xD1; //设置定时初值
  • TF0 = 0; //清除TF0标志
  • TR0 = 1; //定时器0开始计时
  • EA=1;ET0=1;
  • }
  • void time0() interrupt 1
  • {
  • if(qidong==1) //启动状态下
  • {
  • if(++tt==1) //tt等于1时流水灯亮,但不开始流水
  • {
  • if(mode==1){P2=0X00;P0=0XFF;P2=0X80;P0=~(0x01<<i);P2=0X00;} //模式一
  • else if(mode==2){P2=0X00;P0=0XFF;P2=0X80;P0=~(0x80>>i);P2=0X00;} //模式二
  • else if(mode==3){P2=0X00;P0=0XFF;P2=0X80;P0=mode3[i];P2=0X00;} //模式三
  • else if(mode==4){P2=0X00;P0=0XFF;P2=0X80;P0=mode4[i];P2=0X00;} //模式四
  • }
  • else if(tt==LEDtime) //到达LEDtime时流水灯熄灭
  • {
  • P2=0X00;P0=0XFF;P2=0X80;P0=0XFF;P2=0X00;
  • }
  • else if(tt==20) //20ms一个周期
  • {
  • tt=0;LED_TT++; //tt清零,LED_TT++;
  • if(LED_TT*20>=jiange) //因为20ms一个周期,所以LED_TT要乘以20到达流转间隔时间,LED灯开始流水
  • {
  • LED_TT=0; //LED_TT清零
  • if(mode==1){i++;if(i>=8)i=0;} //模式一开始流水
  • else if(mode==2){i++;if(i>=8)i=0;} //模式二开始流水
  • else if(mode==3){i++;if(i>=4)i=0;} //模式三开始流水
  • else if(mode==4){i++;if(i>=4)i=0;} //模式四开始流水
  • }
  • }
  • }
  • if(++shezhi_tt==1600) //定义一个以1600ms为周期的时间,为了实现设置状态下数码管闪烁
  • {
  • shezhi_tt=0; //shezhi_tt清零
  • }
  • }
  • void delayms(int ms)//延时函数
  • {
  • uint i,j;
  • for(i=ms;i>0;i--)
  • for(j=845;j>0;j--);
  • }
  • void allinit()//初始化函数
  • {
  • P2=0XA0;P0=0X00; //关闭蜂鸣器继电器
  • P2=0X80;P0=0XFF; //关闭所有LED灯
  • P2=0XC0;P0=0XFF; //选中所有数码管段选
  • P2=0XFF;P0=0XFF; //关闭所有数码管
  • }
  • void display1(uchar yi,uchar er)//第一、二段数码管函数
  • {
  • P2=0XC0;P0=0X01; //选中第一个数码管位选
  • P2=0XFF;P0=tab[yi]; //让第一个数码管显示yi指向的值
  • delayms(1); //延时1ms
  • P2=0XC0;P0=0X02; //选中第二个数码管位选
  • P2=0XFF;P0=tab[er]; //让第一个数码管显示er指向的值
  • delayms(1); //延时1ms
  • }
  • void display2(uchar san,uchar si)//第三、四段数码管函数
  • {
  • P2=0XC0;P0=0X04; //选中第s三个数码管位选
  • P2=0XFF;P0=tab[san]; //让第一个数码管显示san指向的值
  • delayms(1); //延时1ms
  • P2=0XC0;P0=0X08; //选中第四个数码管位选
  • P2=0XFF;P0=tab[si]; //让第一个数码管显示si指向的值
  • delayms(1); //延时1ms
  • }
  • void display3(uchar wu,uchar liu)//第五、六段数码管函数
  • {
  • P2=0XC0;P0=0X10; //选中第五个数码管位选
  • P2=0XFF;P0=tab[wu]; //让第一个数码管显示wu指向的值
  • delayms(1); //延时1ms
  • P2=0XC0;P0=0X20; //选中第六个数码管位选
  • P2=0XFF;P0=tab[liu]; //让第一个数码管显示liu指向的值
  • delayms(1); //延时1ms
  • }
  • void display4(uchar qi,uchar ba)//第七、八段数码管函数
  • {
  • P2=0XC0;P0=0X40; //选中第七个数码管位选
  • P2=0XFF;P0=tab[qi]; //让第一个数码管显示qi指向的值
  • delayms(1); //延时1ms
  • P2=0XC0;P0=0X80; //选中第八个数码管位选
  • P2=0XFF;P0=tab[ba]; //让第一个数码管显示ba指向的值
  • delayms(1); //延时1ms
  • P2=0XC0;P0=0X80; //选中第八个数码管位选
  • P2=0XFF;P0=0XFF; //让第八个数码管熄灭
  • }

iic.c程序

  • #include<stc15f2k60s2.h>
  • #include "iic.h"
  • #include "intrins.h"
  • #define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
  • #define SlaveAddrW 0xA0
  • #define SlaveAddrR 0xA1
  • //总线引脚定义
  • sbit SDA = P2^1; /* 数据线 */
  • sbit SCL = P2^0; /* 时钟线 */
  • //总线启动条件
  • 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;
  • }
  • 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;
  • }
  • void EEPROM_write(unsigned char add,unsigned char dat)
  • {
  • 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
  • //函数声明
  • void IIC_Start(void);
  • void IIC_Stop(void);
  • 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 add,unsigned char dat);
  • #endif

第九届蓝桥杯单片机作品演示

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门