• LCD1602显示单片机与PC机间串口收发数据


           因为要在linux内核中加入一个新模块的驱动,所以先用单片机来看看该模块是如何工作的,同时也回顾了以前所学的C51的知识,都快忘得差不多了,同时也是记录学习的旅程。

        1602与串口都是新模块在单片机测试中会用到的知识点,所以先拿来看看效果。

        源代码编译链接环境keil2.0

    先看看lcd1602与串口的电路图



    lcd1602的控制线(RS/RW/EN)分别于单片机的P2^4/P2^5/P2^6相连

    对于lcd1602在编写的时候,如果没有判断LCD的忙标志的话,很多时候如果不注意延时的话,很有可能无法显示数据,所以一般在写完指令或者数据后,加一点延时,即可

    单片机的RX(P3.0)与max232的R2O相连,即接收从PC过来的数据    TX(P3.1)与max232的T2I相连,即发送单片机的数据

    对于DB9 通常我们只有三条线 分别是2(RXD) 3(TXD) 5(GND) 就可以了


       main.c

       

    //晶振为11.0592MHz
    
    #include <reg52.h>
    
    //lcd 1602控制位
    sbit RS=P2^4;	// 寄存器选择位  1--数据寄存器 0--指令寄存器
    sbit RW=P2^5;   //读写选择为  1---读 0--写
    sbit EN=P2^6;   //使能位 高电平有效
    
    #define RS_SET RS=1  //数据寄存器
    #define RS_CLR RS=0  //指令寄存器
    #define RW_SET RW=1  //读
    #define RW_CLR RW=0  //写
    #define EN_SET EN=1   //使能有效
    #define EN_CLR EN=0   //使能无效
    
    
    void delay_us(unsigned char n)  //微秒级别的延时
    {
    	while(n--);
    }
    
    void delay1ms(void)  //延时1ms
    {
    	unsigned int i,j;
    	for(i=4;i>0;i--)
    	 for(j=113;j>0;j--);
    }
    
    void delay(unsigned int n)  //任意的延时程序
    {
    	while(n--) delay1ms();
    }
    
    
    
    void lcd_write_ins(unsigned char ins)  //写指令
    {
    	RS_CLR;  //根据时序图操作
    	RW_CLR;
    	EN_SET;
    	P0=ins;
    	delay_us(5);
    	EN_CLR;
    }
    
    
    void lcd_write_data(unsigned char dat) //写数据
    {
    	RS_SET;
    	RW_CLR;
    	EN_SET;
    	P0=dat;
    	delay_us(5);
    	EN_CLR;
    }
    
    void lcd_write_str(unsigned char x,unsigned char y,unsigned char *p)  //写一串数据
    {
    	if(y==0) lcd_write_ins(0x80+x);  //写数据寄存器的地址  写在第一行
    	else lcd_write_ins(0xC0+x);  //写在第二行
    	while(*p)
    	{
    	lcd_write_data(*p);
    	p++;
    	}
    
    }
    
    void lcd_init()  //lcd初始化函数
    {
    	lcd_write_ins(0x38); //设置4为总线 双行显示 5*7点阵字符
    	delay(5);
    	lcd_write_ins(0x38); //设置4为总线 双行显示 5*7点阵字符
    	delay(5);
    	lcd_write_ins(0x38); //设置4为总线 双行显示 5*7点阵字符
    	delay(5);
    	lcd_write_ins(0x38); //设置4为总线 双行显示 5*7点阵字符
    	lcd_write_ins(0x08); //关显示/关光标/关闪烁
    	lcd_write_ins(0x01);  //清屏
    	lcd_write_ins(0x06); //设置输入模式为光标右移
    	delay(5);  //不可少
    	lcd_write_ins(0x0F); //开显示
    }
    
    void serial_init()  //串口初始化函数 
    {
    	SCON=0x50; //设置串口工作方式为1 10位异步收发 并使能接收
    	//因为设置波特率为9600 晶振11.0592MHz
    	TMOD=0x20; // 设置定时器1的工作方式为2 自动8位重装
    	TH1=0xFD;  //设置定时器1的初值
    	TL1=0xFD;
    	TR1=1;  //启动定时器1
    	EA=1; //开所有中断
    	ES=1;  //开串行中断
    }
    
    void main(void)
    {
    	unsigned char *p="data:";
    	delay(50); //延时50ms
    	lcd_init();
    	serial_init();
    	while(1)
    	{
    	lcd_write_ins(0x01); //清屏
    	delay(5);  //延时5ms 不可少
    	lcd_write_str(2,0,p); //写数据在第一行
    	delay(1000); //延时1s
    	}
    }
    
    
    void serial(void) interrupt 4  //串行中断
    {
    	unsigned char temp;  //用于存储临时值
    	if(RI)
    	{
    	RI=0; //清除RI
    	temp=SBUF;//读取缓冲区数据
    	lcd_write_ins(0xC5); //显示在第二行
    	lcd_write_data(temp);  //将获取到的数据显示在lcd上
    	delay(1000);
    	SBUF=temp;  //发送给电脑
    	}
    	if(TI) TI=0;  //清除TI
    }

    对于C51的中断服务程序,是不能进行参数传递,没有返回值的

            对于中断服务程序 interrupt 0 对应的入口地址为0x03 对应的中断为外部中断0

     interrupt 1 对应的入口地址为0x0B 对应的中断为定时器中断0

     interrupt 2对应的入口地址为0x13 对应的中断为外部中断1

      interrupt 3 对应的入口地址为0x1B 对应的中断为定时器中断1

     interrupt 4 对应的入口地址为0x23 串行口中断

  • 相关阅读:
    自控力和专注力是执行力的保证
    今宵又除夕
    买了小米盒子三代
    电容相位滞后?电感超前
    lcr电桥浅谈
    ad 线束和网络
    浅谈 R_S触发器
    NTSC PAL 介绍
    verilog 之流水灯
    io 口方向调整 stm32
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275619.html
Copyright © 2020-2023  润新知