昨天周五没有学习,因为中午没有睡觉,下午和晚上挤不出整块的时间。周日有考试今天也没有学很多啊,但以后周末会是学一天,另一天休息和写周总结。
今天学了串口通信和LED点阵屏,硬件原理是真的很迷,一但想搞的明白就学的很慢,还怪焦虑的,但是感觉知道那么回事就行,主要还是记住要如何设置就行吧
串口通信
串口初始化的代码可以去软件里面生成,但是注意中间的一些设置,按照视频的设置实现不了,看弹幕还是挺有用的。
串口为UART,四种模式,我们通常使用模式一(SCON控制)
这图是串口的工作原理,一般带t的代表发送为transmit,带r的代表接受为receive
SBUF是串口数据缓存寄存器
数据显示在软件中有两种显示模式:HEX/文本。HEX是原始数据就是二进制,十六进制之类的,文本是asc编码
串口向电脑发送数据
#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
unsigned char Sec;
void UART_Init(void) //4800bps@11.0592MHz
{
PCON &= 0x8F; //波特率不倍速
SCON = 0x40; //8位数据,可变波特率
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
/**
* @brief 串口发送一个字节数据
* @param Byte要发送的字节数据
* @retval
*/
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI=0);
TI=0;
}
void main()
{
UART_Init();
while(1)
{
UART_SendByte(Sec);
Sec++;
Delay(1000);
}
}
电脑通过串口控制LED
因为用到了中断系统,所以在初始化要额外设置
#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
#include <REGX52.H>
/**
* @brief 串口初始化
* @param
* @retval
*/
void UART_Init(void) //4800bps@11.0592MHz
{
PCON &= 0x8F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA=1;
ES=1;
}
/**
* @brief 串口发送一个字节数据
* @param Byte要发送的字节数据
* @retval
*/
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI=0);
TI=0;//TI,RI需要软件置零
}
/*串口中断函数模板
void UART_Routine() interrupt 4
{
if(RI==1)
{
RI=0;
}
}
*/
unsigned char Sec;
void main()
{
UART_Init();
while(1)
{
UART_SendByte(Sec);
Sec++;
Delay(1000);
}
}
void UART_Routine() interrupt 4
{
if(RI==1)
{
P2=SBUF;
UART_SendByte(SBUF);
RI=0;
}
}
LED点阵屏
这是LED点阵屏的工作原理,D端需要通过74H595写入
SER是要写入的数据 SRLCK 置一下沉一位 RCLK 当写满8位输出D端
(SER=Byte&(0x80>>i)用来将Byte的每一位取出)
LED点阵屏显示图形
#include <REGX52.H>
#include "Delay.h"
sbit RCK=P3^5;//RCLK
sbit SCK=P3^6;//SRCLK
sbit SER=P3^4;
#define MATRIX_LED_PORT P0
/**
* @brief 74HC595写入一个字节
* @param
* @retval
*/
void _74HC595_WriteByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SER=Byte&(0x80>>i);
SCK=1;
SCK=0;
}
RCK=1;
RCK=0;
}
/**
* @brief LED点阵屏显示一列数据
* @param Column 0-7 0在最左边
* @param Data 00-FF
* @retval
*/
void MatrixLED_ShowColumn(unsigned char Column,Data)
{
_74HC595_WriteByte(Data);
MATRIX_LED_PORT=~(0x80>>Column);
Delay(1);
MATRIX_LED_PORT=0xFF;
}
void main()
{
SCK=0;
RCK=0;
while(1)
{
MatrixLED_ShowColumn(0,0x00);
MatrixLED_ShowColumn(1,0x00);
MatrixLED_ShowColumn(2,0x01);
MatrixLED_ShowColumn(3,0x02);
MatrixLED_ShowColumn(4,0x1C);
MatrixLED_ShowColumn(5,0x3E);
MatrixLED_ShowColumn(6,0x7B);
MatrixLED_ShowColumn(7,0x58);
}
}
LED点阵屏显示动画
这个就是帧流动,用循环实现,点阵图有软件可以生成,再就是注意边界了
#include <REGX52.H>
#include "Delay.h"
#include "MatrixLED.h"
unsigned char code Animation[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x1F,0x10,0x10,0x00,0x00,0x00,0x04,0x04,0xFC,0x04,0x04,0x00,0x00,
0x10,0x1F,0x11,0x03,0x14,0x18,0x10,0x00,0x04,0xFC,0x04,0x80,0x64,0x1C,0x04,0x00,
0x10,0x1F,0x10,0x00,0x00,0x10,0x1F,0x10,0x00,0xF8,0x04,0x04,0x04,0x04,0xF8,0x00,
0x10,0x1F,0x0C,0x03,0x00,0x10,0x1F,0x10,0x04,0xFC,0x04,0x00,0xE0,0x18,0xFC,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
void main()
{
unsigned char i=0,Offset=0,Count=0;
MatrixLED_Init();
while(1)
{
for(i=0;i<8;i++)
{
MatrixLED_ShowColumn(i,Animation[i+Offset]);
}
Count++;
if(Count>10)
{
Count=0;
Offset++;
if(Offset>40)
{
Offset=0;
}
}
}
}
累是必然的。