昨天周五沒有學習,因為中午沒有睡覺,下午和晚上擠不出整塊的時間。周日有考試今天也沒有學很多啊,但以后周末會是學一天,另一天休息和寫周總結。
今天學了串口通信和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; //啟動定時器1EA=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;}}}}
累是必然的。