题目![在这里插入图片描述](https://img-blog.csdnimg.cn/08f018b562c549dcb4f4f3429a1d797a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGxrX3NreQ==,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
程序
官方已给出的底层驱动代码就不再陈列,其中iic.c文件的IIC_Delay函数以及iic.h文件需要做一些更改,已经给出。
iic.h
这里由于工程用不到IIC_SendAck函数,就将其注释掉,这样编译器就不会报warning。
#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);
unsigned char adc_pcf(void);
void eeprom_wr(unsigned char adr,unsigned char date);
unsigned char eeprom_re(unsigned char adr);
#endif
iic.c
#include "intrins.h"
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
unsigned char adc_pcf(void)
{
unsigned char date;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
date = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return date;
}
void eeprom_wr(unsigned char adr,unsigned char date)
{
EA = 0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(adr);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
EA = 1;
}
unsigned char eeprom_re(unsigned char adr)
{
unsigned char date;
EA = 0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(adr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
date = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
EA = 1;
return date;
}
other.h
主要存放了关闭外设,数码管驱动,定时器初始化,按键扫描,延时函数。
#ifndef __OTHER_H_
#define __OTHER_H_
#include <stc15f2k60s2.h>
void Delay2ms(void);
unsigned char seg_tran(int number);
void seg_disp(int adr,int number);
void seg_disp_f(int adr,int number);
int key_scan(void);
void close_perl(void);
void Timer0Init(void);
#endif
other.c
#include <other.h>
void Delay2ms(void) //@11.0592MHz
{
unsigned char i, j;
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
unsigned char seg_tran(int number)
{
unsigned char date;
switch(number)
{
case 0 : date = 0xc0 ; break;
case 1 : date = 0xf9 ; break;
case 2 : date = 0xa4 ; break;
case 3 : date = 0xb0 ; break;
case 4 : date = 0x99 ; break;
case 5 : date = 0x92 ; break;
case 6 : date = 0x82 ; break;
case 7 : date = 0xf8 ; break;
case 8 : date = 0x80 ; break;
case 9 : date = 0x90 ; break;
case 10 : date = 0xbf ; break;//-
case 11 : date = 0xc6 ; break;//c
case 12 : date = 0x8c ; break;//p
case 13 : date = 0x86 ; break;//e
case 14 : date = 0xc7 ; break;//L
case 15 : date = 0xc8 ; break;//a
case 16 : date = 0xc1 ; break;//U
}
return date;
}
void seg_disp(int adr,int number)
{
unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
P2 = P2&0x1f|0xe0;
P2 = P2&0x1f;
P0 = seg_adr[adr];
P2 = P2&0x1f|0xc0;
P2 = P2&0x1f;
P0 = seg_tran(number);
P2 = P2&0x1f|0xe0;
P2 = P2&0x1f;
}
void seg_disp_f(int adr,int number)
{
unsigned char seg_adr[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
P2 = P2&0x1f|0xe0;
P2 = P2&0x1f;
P0 = seg_adr[adr];
P2 = P2&0x1f|0xc0;
P2 = P2&0x1f;
P0 = seg_tran(number)&0x7f;
P2 = P2&0x1f|0xe0;
P2 = P2&0x1f;
}
int key_scan(void)
{
int key,key_mark;
P3 = 0x0f;
P44 = 0;P42 = 1;P35 = 1;P34 = 1;
key = P3;
P44 = 1;P42 = 0;
key = (key<<4)|(P3&0x0f);
P42 = 1;P35 = 0;
key = (key<<4)|(P3&0x0f);
P35 = 1;P34 = 0;
key = (key<<4)|(P3&0x0f);
switch(~key)
{
case 0x8000: key_mark = 4;break;
case 0x4000: key_mark = 5;break;
case 0x2000: key_mark = 6;break;
case 0x1000: key_mark = 7;break;
case 0x0800: key_mark = 8;break;
case 0x0400: key_mark = 9;break;
case 0x0200: key_mark = 10;break;
case 0x0100: key_mark = 11;break;
case 0x0080: key_mark = 12;break;
case 0x0040: key_mark = 13;break;
case 0x0020: key_mark = 14;break;
case 0x0010: key_mark = 15;break;
case 0x0008: key_mark = 16;break;
case 0x0004: key_mark = 17;break;
case 0x0002: key_mark = 18;break;
case 0x0001: key_mark = 19;break;
default : key_mark = 0 ;break;//这句很重要,必须有!
}
return key_mark;
}
void close_perl(void)
{
P0 = 0xff;
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
P0 = 0x00;
P2 = P2&0x1f|0xa0;
P2 = P2&0x1f;
}
void Timer0Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
main.c
#include <other.h>
#include <iic.h>
#define Led1 0x01
#define Led2 0x02
#define Led3 0x04
unsigned int key_nosymbol = 0;
unsigned int count;
unsigned int p_bigger_times;
unsigned char key_old;
unsigned char show_mode;
int c_vol_100 = 0;
int c_vol_10;
int vol_100;
float vol_f;
unsigned char adc;
bit count_on;
bit led1_ok;
void key_pro(void)
{
unsigned char key_down,key_vol;
key_vol = key_scan();
key_down = key_vol&(key_vol^key_old);
key_old = key_vol;
switch(key_down)
{
case 12:
show_mode ++;
if(show_mode == 3)
{
show_mode = 0;
eeprom_wr(0x00,c_vol_10);
}
key_nosymbol = 0;
break;
case 13:
if(show_mode == 2)
{
count = 0;
key_nosymbol = 0;
}
else key_nosymbol ++;
break;
case 16:
if(show_mode == 1)
{
c_vol_100 = c_vol_100 + 50;
if(c_vol_100 == 550) c_vol_100 = 0;
key_nosymbol = 0;
}
else
key_nosymbol ++;
break;
case 17:
if(show_mode == 1)
{
c_vol_100 = c_vol_100 - 50;
if(c_vol_100 < 0) c_vol_100 = 500;
key_nosymbol = 0;
}
else
key_nosymbol ++;
break;
}
}
void seg_pro(void)
{
adc = adc_pcf();
vol_f = (float)adc/255*5.00;
vol_100 = vol_f*100;
c_vol_10 = c_vol_100/10;
if((count_on == 1)&&(vol_100 <= c_vol_100))
{
count = count + 1;
count_on = 0;
}
else count_on = 0;
if(vol_100 > c_vol_100)
{
count_on = 1;
}
seg_disp(1,count_on);Delay2ms();
switch(show_mode)
{
case 0:
seg_disp(0,16); Delay2ms();
seg_disp_f(5,vol_100/100); Delay2ms();
seg_disp(6,vol_100%100/10); Delay2ms();
seg_disp(7,vol_100%10); Delay2ms();
break;
case 1:
seg_disp(0,12); Delay2ms();
seg_disp_f(5,c_vol_100/100); Delay2ms();
seg_disp(6,c_vol_100%100/10); Delay2ms();
seg_disp(7,c_vol_100%10); Delay2ms();
break;
case 2:
seg_disp(0,15); Delay2ms();
if(count > 1000) seg_disp(4,count/1000); Delay2ms();
if(count > 100) seg_disp(5,count%1000/100); Delay2ms();
if(count > 10) seg_disp(6,count%100/10); Delay2ms();
seg_disp(7,count%10); Delay2ms();
break;
}
}
void led_pro(void)
{
P0 = 0xff;
if(count%2 != 0) //计数值为奇数时,L2亮
{
P0 = P0&(~Led2);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
}
else
{
P0 = P0|(Led2);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
}
if(led1_ok == 1) //p > can 超过5s led1亮
{
P0 = P0&(~Led1);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
p_bigger_times = 0;
}
else
{
P0 = P0|(Led1);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
}
if(key_nosymbol == 3)
{
P0 = P0&(~Led3);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
}
else
{
P0 = P0|(Led3);
P2 = P2&0x1f|0x80;
P2 = P2&0x1f;
}
}
void main(void)
{
Timer0Init();
close_perl();
c_vol_100 = eeprom_re(0x00)*10;
while(1)
{
key_pro();
seg_pro();
led_pro();
}
}
void timer0(void) interrupt 1
{
if(vol_100 > c_vol_100)
{
p_bigger_times ++;
if(p_bigger_times >= 500)
{
led1_ok = 1;
}
}
else
{
led1_ok = 0;
p_bigger_times = 0;
}
}
由于图快,就没有写注释,有问题或者觉得哪里写的不完美可以在评论区直接提出或私信,本小白csdn常在线。