<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        單片機I2C通信及LCD1602顯示C程序

        作者:寒竹子   來源:本站原創   點擊數:  更新時間:2014年03月23日   【字體:

        本程序所用的原理圖下載: 點這里 ,單片機芯片使用的stc89c52;找到數碼管的原理圖即可.這是一整個單片機開發板的電路圖其他的忽略.本程序keil工程文件下載: http://www.thefapper.com/f/1602iic.rar

        /*
        *功能: 利用iic發送數據,在數碼管上顯示,并通過串口發生到上位機,
        * 且在lcd1602上顯示"Han Zhu Ying Xue"
        * "1754410821@qq.com";
        *作者: 徐冉
        *日期: 2013-05-29-22:21 2013-5-2919:15 - 22:17
        *備注: 程序已經順利通過調試,耗時3小時。
        */
        /*********51hei開發板***********/
        /********AT89C52-RC MCU***********/
        #include <reg52.h>
        #define write_add 0xa0
        #define read_add  0xa1
        typedef unsigned int uint;
        typedef unsigned char uchar;
        sbit wela = P2^7;
        sbit dula = P2^6;
        //i2c
        sbit SCL = P2^1;
        sbit SDA = P2^0;
        //LCD1602
        sbit RS = P1^0;
        sbit RW = P1^1;
        sbit EN = P2^5;
        sbit BUSY = P0^7;
        uchar num, flag;
        uchar code string_1[] = "Han Zhu Ying Xue";
        uchar code string_2[] = "1754410821@qq.com";
        uchar code table[] = {


                        0x3F,  //"0"
                        0x06,  //"1"
                        0x5B,  //"2"
                        0x4F,  //"3"
                        0x66,  //"4"
                        0x6D,  //"5"
                        0x7D,  //"6"
                        0x07,  //"7"
                        0x7F,  //"8"
                        0x6F  //"9"
             };


        /********************************************************************/
        /**********************LCD1602底層驅動程序***************************/
        /********************************************************************/
        //delay: 延時xms
        void delay(uint xms)
        {
         uchar i, j;
         for(i = 0; i < xms; i++)
          for(j = 0; j < 110; j++);
        }
        //wait: 判忙等待
        void wait()
        {
         P0 = 0xff;
         do
         {
          RS = 0;
          RW = 1;
          EN = 0;
          EN = 1;
         }while(BUSY == 1);
         EN = 0;
        }
        //write:cmd 寫入命令
        void write_cmd(uchar cmd)
        {
         RS = 0;
         RW = 0;
         EN = 0;
         P0 = cmd;
         EN = 1;
         EN = 0; 
        }
        //write:data  寫入數據
        void write_data(uchar datas)
        {
         RS = 1;
         RW = 0;
         EN = 0;
         P0 = datas;
         EN = 1;
         EN = 0;
        }
        //send:string 發送一串字符
        void send_string(uchar* str)
        {
         while(*str != '\0')
         {
          write_data(*str++);
         }
        }
        //lcd1602:init LCD1602 顯示初始化
        void lcd_init()
        {
         delay(15);
         write_cmd(0x38);
         delay(5);
         write_cmd(0x38);
         delay(5);
         write_cmd(0x38);
         wait();
         write_cmd(0x38); //設置16 * 2,5 * 7點陣
         wait();
         write_cmd(0x08);
         wait();
         write_cmd(0x01);//清屏
         wait();
         write_cmd(0x06);
         wait();
         write_cmd(0x0c); //開顯示
        }
        /********************************************************************/
        /*******************I2C模擬通信及AT24C02底層驅動程序****************/
        /********************************************************************/
        //AT24C02
        //delayus: 延時約5us
        void delayus()
        {
         ;;
        }
        //i2c:init I2C總線初始化
        void i2c_init()
        {
         SCL = 1;
         delayus();
         SDA = 1;
         delayus(); 
        }
        //lcd:start  起始信號
        void start()
        {
         SCL = 1;
         SDA = 1;
         delayus();
         SDA = 0;
         delayus();
        }
        //i2c:stop 停止信號
        void stop()
        {
         SCL = 1;
         SDA = 0;
         delayus();
         SDA = 1;
         delayus(); 
        }
        //i2c:ack 從機應答信號
        void ack()
        {
         uchar i = 0;
         //在SCL = 1時,讀取SDA的數據判忙
         SCL = 1;
         delayus();
         while((SDA == 1)&& i < 250)
         i++;
         //判忙之后,等待發送數據/命令
         SCL = 0;
         delayus();
        }
        //nack: 主機非應答信號
        void nack()
        {
         //主機發送非應答信號1
         SCL = 1;
         delayus();
         SDA = 1;
         delayus();
         //等待發送數據/命令
         SCL = 0;
         delayus();
        }
        //write:byte 寫一個字節數據
        void write_byte(uchar date)
        { //從最高位發送
         uchar i, temp;
         temp = date;
         for(i = 0; i < 8; i++)
         {
          temp <<= 1;
          SCL = 0;
          delayus();
          SDA = CY;
          delayus();
          SCL = 1;
          delayus();
          SCL = 0;
          delayus();
         }
         //等待從機應答
         SCL = 0;
         delayus();
         SDA = 1;//置1,等待從機應答0
         delayus();
        }
        //read:byte  讀一個字節數據
        uchar read_byte()
        {
         uchar i, j, k;
         SCL = 0;
         delayus();
         for(i =  0; i < 8; i++)
         {
          SCL = 1;
          delayus();
          j = SDA;
          k = (k << 1) | j;
          delayus();
          SCL = 0;
          delayus();
         }
         delayus();
         return (k);
        }
        //write:AT24C02  寫AT24C02
        void write_c02(uchar address, uchar date)
        {
         start();
         write_byte(write_add);
         ack();
         write_byte(address);
         ack();
         write_byte(date);
         ack();
         stop();
         delay(12); 
        }
        //read:AT24C02 讀AT24C02
        uchar read_c02(uchar add)
        {
         uchar date = 0;
         start();
         write_byte(write_add);
         ack();
         write_byte(add);
         ack();
         start();
         write_byte(read_add);
         ack();
         date = read_byte();
         nack();
         return (date);
        }
        //display: 數碼管顯示程序
        void display(uchar num)
        {
         uchar bai, shi, ge;
         bai = num / 100 % 10;
         shi = num / 10 % 10;
         ge = num % 10;


         dula = 1;
         P0 = table[bai];
         dula = 0;
         P0 = 0xff;
         wela = 1;
         P0 = 0xfe;
         wela = 0;
         P0 = 0x00;
         delay(1);


         dula = 1;
         P0 = table[shi];
         dula = 0;
         P0 = 0xff;
         wela = 1;
         P0 = 0xfd;
         wela = 0;
         P0 = 0x00;
         delay(1);


         dula = 1;
         P0 = table[ge];
         dula = 0;
         P0 = 0xff;
         wela = 1;
         P0 = 0xfb;
         wela = 0;
         P0 = 0x00;
         delay(1);
        }
        /********************************************************************/
        /*************************UART串口通信******************************/
        /********************************************************************/
        //uart:init UART初始化
        void uart_init()
        {
         TMOD = 0x20;
         TH1 = 0xFD; //9600bps/s
         TL1 = 0xFD;
         TR1 = 1;
         SM0 = 0;
         SM1 = 1;
         REN = 1;
         EA = 1;
         ES = 1;
        }
        //main: 主程序
        void main(void)
        {
         i2c_init();
            lcd_init();
         uart_init();
         //LCD1602
         write_cmd(0x80);
         send_string(string_1);
         write_cmd(0x80 + 0x40);
         send_string(string_2);
         //AT24C02
         write_c02(0x0a, 0xaa);
         num = read_c02(0x0a);
         while(1)
         {
          display(num);
          if(flag == 1)
          {
           ES = 0;
           SBUF = num;
           while(!TI);
           TI = 0; 
           flag = 0;
           ES = 1;
          }
         }
        }
        //UART:INT 串口中斷程序
        void uart_int() interrupt 4
        {
         RI = 0;
         num = SBUF;
         flag = 1;
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮