寫博客的主要目的還是自己需要考試了,寫在這裏總結一番,如果給大家帶來了幫助。鄙人不甚歡喜,如果有錯誤,歡迎大家指出
主控芯片
8*8點陣
原理圖:
(注:在51清翔單片機上面,這8個引腳是引出來,所以88使用的是這個原理圖裏面的1-6個引腳)
(注:清翔的點陣屏把需要使用的74HC595放到了點陣屏模塊裏面)
實物:
74HC595
因爲點陣裏面有88個LED燈,所以直接用串口去一個一個控制是不現實的,所以我們需要藉助到595芯片。這一種芯片是一種串入並出的芯片,在電子顯示屏裏面被廣泛的應用。其實質是串行輸入/輸出或者並行輸出移位寄存器
芯片手冊
使用方法
模塊化代碼
/*pbdata.h*/
#ifndef __PBDATA_H__
#define __PBDATA_H__
#define uchar unsigned char
#define uint unsigned int
#include <reg52.h>
#include <intrins.h>
#include "Matrix.h"
/*8*8點陣*/
sbit DIO = P3^4; //串行數據口
sbit S_CLK = P3^5;//移位寄存器時鐘
sbit R_CLK = P3^6;//輸出鎖存器時鐘
#endif
/*Matrix.h*/
#ifndef __MATRIX_H__
#define __MATRIX_H__
void Send_Byte(unsigned char dat);
void Display_DZ(uchar num);
#endif
/*Matrix.c*/
#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//“子”字符
};
/*595發送一字節*/
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;//拉低移位寄存器時鐘
}
}
/*num表示需要輸出的字符數字數量*/
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);//右移,選擇下一行
}
}
}
}
}
/*main.c*/
#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晶振
寄存器配置
因爲通信需要中斷,示意圖在串行口工作之前必須要對相關寄存器進行配置,設定其工作模式。
數據手冊
模塊化代碼
/*Uart.h*/
#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
/*Uart.c*/
#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);
/* 串口配置函數,baud-通信波特率 */
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;
}
/* 串口數據寫入,即串口發送函數,buf-待發送數據的指針,len-指定的發送長度 */
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; //返回實際讀取長度
}
/* 串口接收監控,由空閒時間判定幀結束,需在定時中斷中調用,ms-定時間隔,一般1ms即可*/
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; //設置字節發送完成標誌
}
}