专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

单片机I2C通信及LCD1602显示C程序

作者:寒竹子   来源:本站原创   点击数:  更新时间:2014年03月23日   【字体:

本程序所用的原理图下载: 点这里 ,单片机芯片使用的stc89c52;找到数码管的原理图即可.这是一整个单片机开发板的电路图其他的忽略.本程序keil工程文件下载: http://www.51hei.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;
}

关闭窗口

相关文章