51单片机学习总结(三)8*8点阵屏,串口通信(内含模块代码)

   日期:2020-06-01     浏览:333    评论:0    
核心提示:写博客的主要目的还是自己需要考试了,写在这里总结一番,如果给大家带来了帮助。鄙人不甚欢喜,如果有错误,欢迎大家指出内容概要主控芯片8*8点阵串口通信主控芯片8*8点阵原理图:(注:在51清翔单片机上面,这8个引脚是引出来,所以88使用的是这个原理图里面的1-6个引脚)(注:清翔的点阵屏把需要使用的74HC595放到了点阵屏模块里面)实物:74HC595因为点阵里面有88个LED灯,所以直接用串口去一个一个控制是不现实的,所以我们需要借助到595芯片。这一种芯片是一种串入并出的芯片,在电嵌入式

写博客的主要目的还是自己需要考试了,写在这里总结一番,如果给大家带来了帮助。鄙人不甚欢喜,如果有错误,欢迎大家指出

内容概要

  • 主控芯片
    • 8*8点阵
      • 串口通信

主控芯片

8*8点阵

原理图:

(注:在51清翔单片机上面,这8个引脚是引出来,所以88使用的是这个原理图里面的1-6个引脚)
(注:清翔的点阵屏把需要使用的74HC595放到了点阵屏模块里面)
实物:
74HC595
因为点阵里面有8
8个LED灯,所以直接用串口去一个一个控制是不现实的,所以我们需要借助到595芯片。这一种芯片是一种串入并出的芯片,在电子显示屏里面被广泛的应用。其实质是串行输入/输出或者并行输出移位寄存器
芯片手册
使用方法

SCLK和RCLK全部拉低到0 将需要输入的数据按照2进制压入一个 拉高SCLK 拉低SCLK

模块化代码


#ifndef __PBDATA_H__
#define __PBDATA_H__
#define uchar unsigned char
#define uint unsigned int

#include <reg52.h>
#include <intrins.h>
#include "Matrix.h"


sbit DIO = P3^4;  //串行数据口
sbit S_CLK = P3^5;//移位寄存器时钟
sbit R_CLK = P3^6;//输出锁存器时钟

#endif

#ifndef __MATRIX_H__
#define __MATRIX_H__


void Send_Byte(unsigned char dat);
void Display_DZ(uchar num);

#endif

#include"pbdata.h"



unsigned char code tabel[2][8]={
0xE0,0xEE,0x01,0x6D,0x01,0x6D,0x01,0xEF,//"电"字符
0xE7,0xF7,0xF7,0xF7,0x80,0xF7,0xFB,0xC3//“子”字符
};


void Send_Byte(unsigned char dat)
{
	unsigned char i; //循环次数变量
	S_CLK = 0;//拉低移位寄存器时钟
	R_CLK = 0;//拉低输出锁存器时钟
	for(i=0; i<8; i++) //循环8次
	{
		if(dat & 0x01)//发送1
			DIO = 1;
		else	  //发送0
			DIO = 0;
		dat >>= 1;//数据右移
		S_CLK = 1;//拉高移位寄存器时钟,数据移位
		S_CLK = 0;//拉低移位寄存器时钟
	}	
}


void Display_DZ(uchar num)
{
	unsigned char j, k, ROW;//j发送8列和8行字形码,k字符数量,ROW行值
	unsigned int z;	//动态扫描延时变量
	while(1)
	{
		for(k=0; k<num; k++)//k 需要显示的字符数量
		{
			for(z=0; z<1000; z++)//z刷新次数
			{
				ROW = 0x80;//行选初值
				for(j=0; j<8; j++) //循环8次发送行和列值
				{
					Send_Byte(tabel[k][j]);//发送列选值
					Send_Byte(ROW);	//发送行选值
					R_CLK = 1; //拉高输出锁存器,把移位寄存器中数据输出
					R_CLK = 0; //拉低输出锁存器
					ROW = _cror_(ROW, 1);//右移,选择下一行 
				}
			}
		}
	}
}

#include "pbdata.h"

void main()
{
	while(1)
	{
		Display_DZ(2);
	}
}

(注:字符字形码根据自己的需要修改,有一个小软件可以直接求出来你需要显示的字形码的字符,可以私聊发)
(注:在更改了显示字符的时候,要注意改tabel喝Display_DZ两个的参数)

串口通信

如果不想看原理 可以直接拉到最下面去看模块化代码,简单直接粗暴,更省时省心省力
波特率
要学习串口通信,就一定要知道波特率,波特率就是每秒钟传输二进制代码的位数,单位是:位/秒(bps)
用一个简单的例子来讲解波特率,比如每秒钟传输240个字符,而每个字符的格式包含10位(1个起始位、1个停止位、8个数据位),这时候的比特率就是10位*240个/秒 = 2400 bsp
波特率的计算

SMOD没配置的话默认为0
fosc是外部晶振 我们使用的是11.0592MHZ晶振
寄存器配置
因为通信需要中断,示意图在串行口工作之前必须要对相关寄存器进行配置,设定其工作模式。

设置T1工作方式 编辑TMOD寄存器 计算T1初值 装载TH1 TL1 启动T1 编辑TCON中的R1位 确定串行口控制 编辑SCON寄存器 如果需要串行口在中断下工作 在中断设置编程IE寄存器

数据手册
模块化代码


#ifndef __Uart_H__
#define __Uart_H__

void UartAction(unsigned char *buf, unsigned char len);
void ConfigUART(unsigned int baud);
void UartWrite(unsigned char *buf, unsigned char len);
unsigned char UartRead(unsigned char *buf, unsigned char len);
void UartRxMonitor(unsigned char ms);
void UartDriver();

#endif

#include <reg52.h>
#include <stdio.h>
#include <pbdata.h>
//存储数据到bufRxd[]数组里面,buf[]是另外一个存储谁都可以调用
//加上extern之后,不需要声明包含这个文件
#define uchar unsigned char 
#define uint unsigned int

bit flagFrame = 0; //帧接收完成标志,即接收到一帧新数据
bit flagTxd = 0; //单字节发送完成标志,用来替代TXD 中断标志位
unsigned char cntRxd = 0; //接收字节计数器
unsigned char pdata bufRxd[64]; //接收字节缓冲区 ,存储到RAM中

// 串口动作函数,用来添加自己需要的额外函数
void UartAction(unsigned char *buf, unsigned char len);


void ConfigUART(unsigned int baud)
{
	EA = 1;			//打开总中断
	ES = 1; 		//打开串口中断
	SM0 = 0;SM1 = 1;	//串口工作方式1,8位UART波特率可变
	REN = 1;		//串口允许接收
	TR1 = 1;		//启动定时器1
	TMOD |= 0x20;		//定时器1,工作模式2 8位自动重装
	TH1=256-(11059200/12/32)/baud;
	TL1=TH1;
}

void UartWrite(unsigned char *buf, unsigned char len)
{
	while (len--) //循环发送所有字节
	{
		flagTxd = 0; //清零发送标志
		SBUF = *buf++; //发送一个字节数据,发送一个字节,然后指针后移
		while (!flagTxd); //等待该字节发送完成
	}
}

unsigned char UartRead(unsigned char *buf, unsigned char len)
{
	unsigned char i;
	if (len > cntRxd) //指定读取长度大于实际接收到的数据长度时,
	{ //读取长度设置为实际接收到的数据长度
		len = cntRxd;
	}
	for (i=0; i<len; i++) //拷贝接收到的数据到接收指针上
	{
		*buf++ = bufRxd[i];//把发送到bufRxd上的数据存到buf上
	}
	cntRxd = 0; //接收计数器清零
	return len; //返回实际读取长度
}

void UartRxMonitor(unsigned char ms)
{
	static unsigned char cntbkp = 0;
	static unsigned char idletmr = 0;
	if (cntRxd > 0) //接收计数器大于零时,监控总线空闲时间
		{
		if (cntbkp != cntRxd) //接收计数器改变,即刚接收到数据时,清零空闲计时
		{
			cntbkp = cntRxd;//改变接收计数器
			idletmr = 0; //清0空闲计时
		}
		else //接收计数器未改变,即总线空闲时,累积空闲时间,判断是否接受完毕
		{
			if (idletmr < 30) //空闲计时小于30ms 时,持续累加
			{
				idletmr += ms;
				if (idletmr >= 30) //空闲时间达到30ms 时,即判定为一帧接收完毕
				{
					flagFrame = 1; //设置帧接收完成标志
				}
			}
		}
	}
		else
		{
			cntbkp = 0;
		}
}

void UartDriver()
{
	unsigned char len;
	unsigned char pdata buf[40];
	if (flagFrame) //有命令到达时,读取处理该命令
	{
		flagFrame = 0;//改变状态为忙碌
		len = UartRead(buf, sizeof(buf)); //将接收到的命令读取到缓冲区中,并且放入buf中
		UartAction(buf, len); //传递数据帧,调用动作执行函数
	}
}

void InterruptUART() interrupt 4
{
	if (RI) //接收到新字节
	{
		RI = 0; //清零接收中断标志位
		if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
		{ //保存接收字节,并递增计数器
			bufRxd[cntRxd++] = SBUF;
		}
	}
	if (TI) //字节发送完毕
	{
		TI = 0; //清零发送中断标志位
		flagTxd = 1; //设置字节发送完成标志
	}
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服