基于STC12C5A60S2系列1T 8051單片讀寫掉電保存數據IIC總線器件24C02一字節并顯示在液晶顯示器LCD1602上應用
- STC12C5A60S2系列1T 8051單片機管腳圖
- STC12C5A60S2系列1T 8051單片機I/O口各種不同工作模式及配置
- STC12C5A60S2系列1T 8051單片機I/O口各種不同工作模式介紹
- IIC通信簡單介紹
- 掉電保存數據芯片24C02簡單介紹
- 通過液晶顯示器LCD1602顯示掉電保存數據芯片24C02內存地址上的數據
STC12C5A60S2系列1T 8051單片機管腳圖
STC12C5A60S2系列1T 8051單片機I/O口各種不同工作模式及配置
STC12C5A60S2系列1T 8051單片機I/O口各種不同工作模式介紹
IIC通信簡單介紹
掉電保存數據芯片24C02簡單介紹
通過液晶顯示器LCD1602顯示掉電保存數據芯片24C02內存地址上的數據
#include <stc12c5a60s2.h>
#include <intrins.h>
#define uchar unsigned char//自定義無符號字符型為uchar
#define uint unsigned int//自定義無符號整數型為uint
#define LCD1602PinMode1 0x38//自定義液晶顯示器LCD1602八位數據接口的兩行5*8點陣
#define LCD1602PinMode2 0x28//自定義液晶顯示器LCD1602四位數據接口的兩行5*8點陣
#define LCD1602CleanScreen 0x01//自定義液晶顯示器LCD1602清屏變量
#define LCD1602CursorRst 0x02//自定義液晶顯示器LCD1602光標復位
#define LCD1602DisplayCursorGlint 0x0f//自定義液晶顯示器LCD1602開顯示開光標開光標閃爍
#define LCD1602DisplayCursorNoGlint 0x0e//自定義液晶顯示器LCD1602開顯示開光標不開光標閃爍
#define LCD1602DisplayNoCursorNoGlint 0x0c//自定義液晶顯示器LCD1602開顯示不開光標不開光標閃爍
#define LCD1602NoDisplayCursorNoGlint 0x08//自定義液晶顯示器LCD1602不開顯示不開光標不開光標閃爍
#define LCD1602CursorRightMoveDisplayNoMove 0x06//自定義液晶顯示器LCD1602光標右移 顯示不移動
#define LCD1602CursorLeftMoveDisplayNoMove 0x04//自定義液晶顯示器LCD1602光標左移 顯示不移動
#define LCD1602PictureLeftMove 0x07//自定義液晶顯示器LCD1602畫面左移 AC自增
#define LCD1602PictureRightMove 0x05//自定義液晶顯示器LCD1602畫面右移 AC自減
#define LCD1602CursorRightMove 0x10//自定義液晶顯示器LCD1602光標右移
#define LCD1602CursorLeftMove 0x14//自定義液晶顯示器LCD1602光標左移
#define LCD1602DisplayRightMove 0x18//自定義液晶顯示器LCD1602顯示右移
#define LCD1602DisplayLeftMove 0x1c//自定義液晶顯示器LCD1602顯示左移
#define LCD1602DisplayData P0//自定義液晶顯示器LCD1602顯示數據為單片機P0組引腳
sbit LCD1602RS P2^5;//位定義液晶顯示器LCD1602數據指令變量為單片機P2.5引腳
sbit LCD1602RW P2^6;//位定義液晶顯示器LCD1602讀寫變量為單片機P2.6引腳
sbit LCD1602EN P2^6;//位定義液晶顯示器LCD1602使能變量為單片機P2.7引腳
sbit I2CSCL = P1^0;//位定義I2C時鐘變量為P1.0端口
sbit I2CSDA = P1^1;//位定義I2C數據變量為P1.1端口uchar Read24C02Byte(uchar IcAddress,uchar Address)//讀24C02字節函數
{uchar Data;//聲明數據變量I2CStar();//I2C啟動函數I2CWriteByte(IcAddress << 1);//I2C寫字節函數 單片機通過I2C通信寫匹配通信地址給24C02I2CWriteByte(Address);//I2C寫字節函數 單片機通過I2C通信寫24C02的地址I2CStar();//I2C啟動函數I2CWriteByte((IcAddress << 1) | 0x01);//I2C寫字節函數 單片機通過I2C通信寫入讀24C02Data = I2CReadByte();//I2C讀字節函數含有的數據賦給數據變量SendAck(1);//I2C發送應答函數 單片機作為主機通過I2C通信只讀24C02內存地址上的一個字節 I2CStop();//I2C停止函數return Data;//返回數據變量含有的數據}
/****bit 24C02Address(uchar Address)//24C02地址函數
{bit Ack;//聲明一位應答變量I2CStar();//I2C啟動函數I2CWriteByte(Address << 1);//I2C寫字節函數Ack = I2CReceiveAck();//I2C接收應答函數接收應答賦給應答變量 即24C02作為從機接收單片機作為主機發送來的地址信息 并做出返回應答I2CStop();//I2C停止函數return Ack;//返回應答}****/void I2CDelay()//I2C延時函數
{_nop_();_nop_();_nop_();_nop_();}void I2CStar()//I2C啟動函數
{I2CSCL = 1;//空閑時 I2C時鐘變量置高電平I2CSDA = 1;//空閑時 I2C數據變量置高電平I2CDelay();//I2C延時I2CSDA = 0;//I2C數據變量置低電平I2CDelay();//I2C延時I2CSCL = 0;//I2C時鐘變量置低電平}bit I2CWriteByte(uchar Data)//I2C寫字節函數
{uchar Temp;//聲明臨時變量bit Ack;//聲明一位應答變量for(Temp = 0x80;Temp = !0;Temp >>= 1)//從某八位二進制數的最高位往最低位每次移出一位二進制數 取變化后的八位二進制數進行下一步從最高位往最低位每次右移出一位二進制數 直到寫完某八位二進制數的每一位二進制數{if((Temp & Data) == 0)//判斷臨時變量包含的數據與上寫入某八位二進制數得出八位二進制數最高位是否為0I2CSDA = 0;//I2C數據變量寫0else//否則I2CSDA = 1;//I2C數據變量寫1I2CDelay();//I2C延時I2CSCL = 1;//I2C時鐘變量置高電平I2CDelay();//I2C延時I2CSCL = 0;//I2C時鐘變量置低電平}Ack = I2CReceiveAck();//I2C接收應答函數接收應答賦給應答變量return (Ack);//返回應答}void SendAck(bit Ack)//I2C發送應答函數
{I2CSDA = Ack;//應答變量賦給I2C數據變量I2CDelay();//I2C延時I2CSCL = 1;//I2C時鐘變量置高電平I2CDelay();//I2C延時I2CSCL = 0;//I2C時鐘變量置低電平}bit ReceiveAck()//I2C接收應答函數
{bit Ack;//聲明一位應答變量I2CSDA = 1;//I2C數據變量置高電平I2CDelay();//I2C延時I2CSCL = 1;//I2C時鐘變量置高電平Ack = I2CSDA;//I2C數據變量I2CDelay();//I2C延時I2CSCL = 0;//I2C時鐘變量置低電平return (Ack);//返回應答}uchar I2CReadByte()//I2C讀字節函數
{uchar Data;//聲明數據變量uchar Temp;//聲明臨時變量I2CSDA = 1;//I2C數據變量置高電平for(Temp = 0x80;Temp = !0;Temp >>= 1)//從某八位二進制數的最高位往最低位每次右移出一位二進制數 取變化后的八位二進制數進行下一步從最高位往最低位每次右移出一位二進制數 直到讀完某八位二進制數的每一位二進制數{I2CDelay();//I2C延時I2CSCL = 1;//I2C時鐘變量置高電平if(I2CSDA == 1)//判斷I2C數據變量是否置高電平{Data |= Temp;//臨時變量包含的數據或上某八位二進制數讀出八位二進制數最高位為1}else//否則{Data &= ~Temp;//臨時變量包含的數據與上某八位二進制數讀出八位二進制數最高位為0}I2CDelay();//I2C延時I2CSCL = 0;//I2C時鐘變量置低電平}return Data;//返回數據變量}void I2CStop()//I2C停止函數
{I2CSCL = 0;//I2C時鐘變量置低電平I2CSDA = 0;//I2C數據變量置低電平I2CDelay();//I2C延時I2CSCL = 1;//I2C時鐘變量置高電平I2CDelay();//I2C延時I2CSDA = 1;//I2C數據變量置高電平I2CDelay();//I2C延時}void LCD1602Init()//液晶顯示器初始化函數
{LCD1602WriteCommand(LCD1602PinMode1);//液晶顯示器LCD1602八位數據接口的兩行5*8點陣 LCD1602WriteCommand(LCD1602DisplayNoCursorNoGlint);//液晶顯示器LCD1602開顯示不開光標不開光標閃爍LCD1602WriteCommand(LCD1602CursorRightMove);//液晶顯示器LCD1602光標右移LCD1602WriteCommand(LCD1602CleanScreen);//液晶顯示器LCD1602清屏}void LCD1602ReadBusy()//液晶顯示器讀忙函數
{uchar i;//聲明一個計數變量uchar State;//聲明狀態變量LCD1602DisplayData = 0xff;//液晶顯示器LCD1602顯示數據變量拉高LCD1602RS = 0;//液晶顯示器LCD1602寫入指令LCD1602RW = 1;//讀取液晶顯示器LCD1602do{LCD1602EN = 1;//液晶顯示器LCD1602使能State = LCD1602DisplayData;//液晶顯示器LCD1602顯示數據賦給狀態變量LCD1602EN = 0;//關液晶顯示器LCD1602使能i++;if(i > 200)//防止液晶顯示器LCD1602因損壞陷入do{}while循環中 導致無法執行其他程序break;}while(State & 0x80);//判斷狀態變量是否為1 為1表示液晶顯示器LCD1602在忙 否則不忙}void LCD1602WriteCommand(uchar Command)//液晶顯示器LCD1602寫命令函數
{LCD1602ReadBusy();//液晶顯示器讀忙函數LCD1602RS = 0;//液晶顯示器LCD1602寫入指令LCD1602RW = 0;//寫入液晶顯示器LCD1602LCD1602DisplayData = Command;//指令變量含有的數據賦給液晶顯示器LCD1602顯示數據變量LCD1602EN = 1;//液晶顯示器LCD1602使能LCD1602EN = 0;//關液晶顯示器LCD1602使能} void LCD1602WriteData(uchar Data)//液晶顯示器LCD1602寫數據函數
{LCD1602ReadBusy();//液晶顯示器LCD1602讀忙函數LCD1602RS = 1;//液晶顯示器LCD1602寫入數據LCD1602RW = 0;//寫入液晶顯示器LCD1602LCD1602DisplayData = Data;//數據變量含有的數據賦給液晶顯示器LCD1602顯示數據變量LCD1602EN = 1;//液晶顯示器LCD1602使能LCD1602EN = 0;//關液晶顯示器LCD1602使能} void LCD1602SetDisplayPosition(uchar x,uchar y)//液晶顯示器LCD1602設置顯示位置
{if(0 == y)//液晶顯示器LCD1602第一行顯示{LCD1602WriteCommand(0x80 | x);//液晶顯示器LCD1602第一行第一位開始顯示 0x80為液晶顯示器LCD1602顯示數據儲存地址最高位初始值}else//液晶顯示器LCD1602第二行顯示{LCD1602WriteCommand(0x80 | (0x40 + x));//液晶顯示器LCD1602第二行第一位開始顯示 0x40為液晶顯示器LCD1602第二行顯示位置初始地址}}void LCD1602ShowString(uchar x;uchar y;uchar *String)//液晶顯示器LCD1602顯示字符串函數 x變量為液晶顯示器LCD1602橫向顯示 相當于列 y變量為液晶顯示器LCD1602縱向顯示 相當于行
{LCD1602SetDisplayPosition(x,y);//液晶顯示器LCD1602設置顯示位置while(*String != ' \0 ')//判斷字符串是否全部顯示 {LCD1602WriteData(*String ++)//液晶顯示器LCD1602寫入字符串}}/****void LCD1602WriteCGRAM()//液晶顯示器LCD1602寫入自定義字符儲存器函數
{uchar i;//聲明循環變量LCD1602WriteCommand(0x40);//0x40為液晶顯示器LCD1602自定義字符儲存地址最高位初始值for(i = 0;i < 8;i++)//循環八次 把寫入液晶顯示器LCD1602自定義字符儲存地址上的自定義字符寫出來{LCD1602WriteData(String[i]);//把寫入液晶顯示器LCD1602自定義字符儲存地址上的自定義字符寫出來}LCD1602WriteCommand(0x80 | 0x05);//0x80為液晶顯示器LCD1602顯示數據儲存地址最高位初始值 0x05為液晶顯示器LCD1602顯示位置LCD1602WriteData(0x00);//液晶顯示器LCD1602寫自定義字符到CGROM(即字模存儲用空間)第一個位置顯示出來}****//****void LCD1602UserDefined(uchar x,uchar y,uchar Position,uchar *String)//液晶顯示器LCD1602用戶自定義字符函數
{uchar i;//聲明循環變量for(i = 0;i < 8;i++)//循環八次 把自定義字符寫入液晶顯示器LCD1602自定義字符儲存地址并寫出來{LCD1602WriteCommand(0x40 + Position*8 + i);//0x40為液晶顯示器LCD1602自定義字符儲存地址最高位初始值 循環八次 把自定義字符寫入液晶顯示器LCD1602自定義字符儲存地址LCD1602WriteData(*(String+i));//循環八次 把寫入液晶顯示器LCD1602自定義字符儲存地址上的自定義字符寫出來}LCD1602SetDisplayPosition(x,y);//液晶顯示器LCD1602設置顯示位置LCD1602WriteData(0x00 + Position);//液晶顯示器LCD1602寫自定義字符到CGRAM(即字符生成隨機存儲器)第一個位置到第八個位置顯示出來}****/void main()//主函數
{uchar Data;//聲明數據變量LCD1602Init();//液晶顯示器初始化函數Data = Read24C02Byte(0x50,0x00);//單片機作為主機通過I2C通信從24C02內存地址0x00上讀取一個字節 LCD1602SetDisplayPosition(0,0);//液晶顯示器LCD1602第一行第一個位置顯示字符串LCD1602WriteData(Data/100 + '0');//液晶顯示器LCD1602寫數據函數 顯示百位數據LCD1602WriteData(Data/10%10 + '0');//液晶顯示器LCD1602寫數據函數 顯示十位數據LCD1602WriteData(Data%10 + '0');//液晶顯示器LCD1602寫數據函數 顯示個位數據while(1);//主循環}