|
拆了一臺點鈔機,主控板是用STC的12C5A16AD,正好手有塊I2C的LCD1602.無聊就搞搞實驗,用定時器做了個時鐘.
- #include <STC15F104E.H>
- #include <intrins.h>
- sbit SDA=P0^2;
- sbit SCL=P0^1;
- bit ack,blk; //I2C 應答位 LCD背光開關
- #define uchar unsigned char
-
-
- uchar num[]={"0123456789"},sec,min,hou;
- unsigned int us,ms;
- #define WriteAdd 0x7e //寫PCF8574A地址 0111 A2 A2 A0 W
- #define ReadAdd 0x7f //讀PCF8574A地址 0111 A2 A2 A0 R
- // 背光 CS/EN R/W RS
- //P7 P6 P5 P4 P3 P2 P1 P0 PCF8574A引腳
- //#define WriteCom 8 //DB7 DB6 DB5 DB4 1 0 0 0 RW=0寫 RS=0指令 BLK背光
- //#define WriteData 9 //DB7 DB6 DB5 DB4 1 0 0 1 RW=0寫 RS=1數據
- //#define WriteComEn 0x0c //DB7 DB6 DB5 DB4 1 1 0 0 RW=0寫 RS=0
- //#define WriteDataEn 0x0d //DB7 DB6 DB5 DB4 1 1 0 1 RW=0寫 RS=1數據
- /*======================== PCF8574A P3 = 0 關背光 ====================================*/
- //#define WriteCom 0 //DB7 DB6 DB5 DB4 0 0 0 0 RW=0寫 RS=0指令 BLK背光
- //#define WriteData 1 //DB7 DB6 DB5 DB4 0 0 0 1 RW=0寫 RS=1數據
- //#define WriteComEn 4 //DB7 DB6 DB5 DB4 0 1 0 0 RW=0寫 RS=0
- //#define WriteDataEn 5 //DB7 DB6 DB5 DB4 0 1 0 1 RW=0寫 RS=1數據
- uchar WriteCom=8,WriteData=9,WriteComEn=0x0c,WriteDataEn=0x0d;
- void LcdBlk() //LCD背光控制 blk=1亮,blk=0滅
- {
- if (blk) {WriteCom=8,WriteData=9,WriteComEn=0x0c,WriteDataEn=0x0d;}
- else {WriteCom=0,WriteData=1,WriteComEn=4,WriteDataEn=5;}
- }
- void Delayms() //@22.1184MHz 1MS
- {
- unsigned char i, j;
- i = 22;
- j = 128;
- do
- {
- while (--j);
- } while (--i);
- }
- void Timer0Init(void) //10微秒@22.1184MHz 定時器做時鐘
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0x02; //設置定時器模式
- TL0 = 0x23; //設置定時初值
- TH0 = 0x23; //設置定時重載值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- ET0=1;EA=1;
- }
- void Delay5us() //@22.1184MHz
- {
- unsigned char i;
- _nop_();
- _nop_();
- _nop_();
- i = 24;
- while (--i);
- }
- void i2cStart() //I2C 起始信號
- {
- SDA=1; _nop_(); SCL=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SDA=0; _nop_(); _nop_(); _nop_();_nop_(); _nop_();SCL=0;Delay5us();
- }
- void i2cStop() //I2C 停止信號
- {
- SDA=0; _nop_(); SCL=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SDA=1; _nop_(); _nop_(); _nop_(); _nop_();
- }
- void i2cAck(bit a) //I2C應答信號
- {
- if(a==0)SDA=0; //在此發出應答或非應答信號
- else SDA=1;
- _nop_();
- _nop_();
- _nop_();
- SCL=1;
- Delay5us();
- SCL=0; //清時鐘線,鉗住I2C 總線以便繼續接收
- Delay5us();
- }
- void i2cWriteByte(uchar temp) //I2C寫一字節
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SDA=(bit)(temp & 0x80) ;
- temp <<=1; Delay5us();
- SCL=1; Delay5us(); Delay5us();
- SCL=0;//Delay5us();
- }
- _nop_();
- SDA=1; _nop_();Delay5us();
- SCL=1;Delay5us();_nop_();_nop_();
- if(SDA==1)ack=0;
- else ack=1; //判斷是否接收到應答信號
- SCL=0;
-
-
- }
- void LcdCom(uchar com) //LCD1602寫指令
- {
- i2cStart(); //I2C起始信號
- i2cWriteByte(WriteAdd); //PCF8574A寫地址
- i2cWriteByte((com&0xf0)|WriteCom); //先寫LCD1602高4位指令+控制位
- i2cWriteByte((com&0xf0)|WriteComEn); //LCD1602 CS/EN拉高送入
- i2cWriteByte((com&0xf0)|WriteCom); //LCD1602 CS/EN拉低準備寫入
- com<<=4; //指令低4位左移到高4位
- i2cWriteByte((com&0xf0)|WriteCom); //寫入剩下的4位指令+控制位
- i2cWriteByte((com&0xf0)|WriteComEn);
- i2cWriteByte((com&0xf0)|WriteCom);
- i2cStop();Delay5us(); //寫完成,I2C停止信號
- }
- void LcdIni() //1602初始化
- {
- LcdCom(0x33);
- LcdCom(0x32);
- LcdCom(0x28);
- LcdCom(0x0c);
- LcdCom(0x01);
- LcdCom(0x80);
- }
- void LcdData(uchar com) //LCD1602寫數據
- {
- i2cStart(); //I2C起始信號
- i2cWriteByte(WriteAdd); //PCF8574A寫地址
- i2cWriteByte((com&0xf0)|WriteData); //Delay5us();//先寫LCD1602高4位指令+控制位
- i2cWriteByte((com&0xf0)|WriteDataEn); //Delayms();//LCD1602 CS/EN接高送入
- i2cWriteByte((com&0xf0)|WriteData); //LCD1602 CS/EN拉低準備寫入
- com<<=4; //Delay5us();//數據低4位左移到高4位
- i2cWriteByte((com&0xf0)|WriteDataEn); //Delayms();//寫入剩下的4位數據+控制位
- i2cWriteByte((com&0xf0)|WriteData); //寫完成,I2C停止信號
- i2cStop();Delay5us();
- }
- void LcdDisplay(uchar x,uchar *s) //1602顯示字符串 //x=1顯示在第一行,x=2顯示在第二行
- {
- if(x==1) //第一行
- {
- LcdCom(0x80); //第一行起始位置地址
- while(*s)
- {
- LcdData(*s);s++;
- }
- }
- if(x==2) //第二行
- {
- LcdCom(0xc0); //第二行起始位置地址
- while(*s)
- {
- LcdData(*s);s++;
- }
- }
- }
- void main()
- {
- Timer0Init();
- LcdIni();
-
- // LcdDisplay(1," I LOVE YOU!");LcdDisplay(2," Do U Love Me?");
-
- while(1)
-
- {
- LcdCom(0x80);
- if(hou>=24) {hou=0;}
- if(sec>=60) {sec=0;min++;blk=~blk;}
- LcdBlk();
- if(min>=60) {min=0;hou++;}
- LcdData(num[hou/10]);LcdData(num[hou%10]); LcdData(':');
- LcdData(num[min/10]);LcdData(num[min%10]);LcdData(':');
- LcdData(num[sec/10]);LcdData(num[sec%10]);
- }
-
- }
- void InterruptT0 () interrupt 1
- {
- us++;
- if (us>=100)
- {
- us=0;
- ms++;
- }
- if(ms>=1000)
- {
- ms=0;
- sec++;
- }
-
- }
復制代碼
|
評分
-
查看全部評分
|