【藍橋杯-微控制器省賽】第三屆自動售水機
阿新 • • 發佈:2022-01-04
自己做的答案,疏漏之處在所難免,程式碼僅供參考
mian.c
#include "stc15f2k60s2.h" #include "hc138.h" #include "display.h" #include "key.h" #include "pcf8591.h" void S6_display(); void S7_display(); void main(){ unsigned char ad; init0(); Timer2Init(); while(1){ Key_Scan(); ad=AD(); if(_ope==1){//S7 ->L8亮 S7_display(); if(ad>64){ hc138(4); P0=~0x80; P2&=0x1f; } else { hc138(4); P0=~0x81; P2&=0x1f; } } else if(_clo==1){//S6 ->L8滅 S6_display(); if(ad>64){ hc138(4); P0=0xff; P2&=0x1f; } else { hc138(4); P0=~0x01; P2&=0x1f; } } } } void S7_display(){ smgdat[0]=21; smgdat[1]=10; smgdat[2]=5; smgdat[3]=0; smgdat[4]=water/1000; smgdat[5]=(water%1000/100)+10; smgdat[6]=water%100/10; smgdat[7]=water%10; } void S6_display(){ smgdat[0]=21; smgdat[1]=10; smgdat[2]=5; smgdat[3]=0; smgdat[4]=(int)water1/1000; smgdat[5]=((int)water1%1000/100)+10; smgdat[6]=(int)water1%100/10; smgdat[7]=(int)water1%10;/**/ }
hc138.c
#include "stc15f2k60s2.h" void hc138(unsigned char 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; } } void init0(){ hc138(4);P0=0xff; hc138(5);P0=0x00; hc138(6);P0=0x00; hc138(7);P0=0xff; }
display.c
#include "stc15f2k60s2.h" #include "hc138.h" #include "key.h" unsigned char POS=0; unsigned int water=0; float water1; unsigned int second=0; unsigned char smgdat[8]={21,21,21,21,21,21,21,21}; unsigned char code SMG[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10, 0xbf,0xff}; void Timer2Init(void) //2毫秒@12.000MHz { AUXR |= 0x04; //定時器時鐘1T模式 T2L = 0x40; //設定定時初值 T2H = 0xA2; //設定定時初值 AUXR |= 0x10; //定時器2開始計時 /*後加的部分*/ EA=1; IE2|=0x04; } void display(unsigned char pos,dat){ hc138(6);P0=0x01<<pos;P2&=0x1f; hc138(7);P0=dat; P2&=0x1f; } void T2_Display()interrupt 12 { hc138(6);P0=0x00; display(POS,SMG[smgdat[POS]]); if(++POS==8)POS=0; if(_ope==1&&_clo==0) if(++second==500) { water+=1; second=0; if(water==9999){ _ope=0; _clo=1; water1=water*0.5; water=0; hc138(5);P0=0x00;P2&=0x1f; } } }
key.c
#include "stc15f2k60s2.h"
#include "hc138.h"
#include "display.h"
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
/* 1使能 */
bit _ope=0;
bit _clo=0;
void Delay5ms();
void Key_Scan(){
if(S4==0){
Delay5ms();
if(S4==0){
smgdat[0]=0;
}
while(!S4);
}
else if(S5==0){
Delay5ms();
if(S5==0){
smgdat[2]=2;
}
while(!S5);
}
else if(S6==0){ //close
Delay5ms();
if(S6==0){
_ope=0;
_clo=1;
water1=water*0.5;
water=0;
hc138(5);P0=0x00;P2&=0x1f;
}
while(!S6);
}
else if(S7==0){ //open
Delay5ms();
if(S7==0){
_ope=1;
_clo=0;
hc138(5);P0=0x10;P2&=0x1f;
}
while(!S7);
}
}
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 59;
j = 90;
do
{
while (--j);
} while (--i);
}
pcf8591.c
#include "stc15f2k60s2.h"
#include "iic.h"
unsigned char AD(){
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(1); //1 光敏電阻 3滑動變阻器
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
EA=1;
return temp;
}
#### iic.c
````c
#include "reg52.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;
}
//應答位控制
//void IIC_Ack(bit ackbit)
//{
// if(ackbit)
// {
// SDA = 0;
// }
// else
// {
// SDA = 1;
// }
// somenop;
// SCL = 1;
// somenop;
// SCL = 0;
// SDA = 1;
// somenop;
//}
//等待應答
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;
}