3 單片機通訊設計
3.1 C52單片機的串行接口結構
8051串行接口是一個可編程的全雙工串行通訊接口。它可用作異步通訊方式(UART),與串行傳送信息的外部設備相連接,或用于通過標準異步通訊協議進行全雙工的8051多機系統(tǒng)也可以通過同步方式,使用TTL或CMOS移位寄存器來擴充I/O口。8051單片機通過引腳RXD(P3.0,串行數據接收端)和引腳TXD(P3.1,串行數據發(fā)送端)與外界通訊。SBUF是串行口緩沖寄存器,包括發(fā)送寄存器和接收寄存器。它們有相同名字和地址空間,但不會出現沖突,因為它們兩個一個只能被CPU讀出數據,一個只能被CPU寫入數據。
臺達變頻器接受的RS485信號,單片機輸出的是TTL電平。因此要變頻器和單片機通訊要有通訊轉換芯片,目前常用的RS485芯片有MAX485、MAX483,S75176等。在本例子中采用了MAX485和S75176芯片,同時電路圖中預留了RS232電路的接口,方便單片機以RS232通訊方式和其他外設進行通訊。主單片機采用ATMEL公司的AT89C52單片機。
3.2 軟件調試界面
單片機程序通過在KEIL環(huán)境下開發(fā)編譯的,調試界面如下:

3.3通訊源程序
/*********************************************************
* 本程序是AT89C52單片機和臺達B系列、M系列、L系列、F系列通訊例子.
* 通訊協議ASCII格式,幀格式為“1位起始位、7位數據、奇偶位(或無)、結束位”共10位.
* 臺達VFD系列變頻器一幀的通訊格式:第0位:“:”起始位;第1,2位:站號地址.
* 第3,4位:功能號碼;第5,6,7,8位:寫入的地址;第9,10,11,12位:傳輸數據.
* 第13,14位:校驗碼;第15,116位:停止0X0D,0X0A.
* 該程序通過向2000H地址寫入0012H數據來啟動變頻器;向2000H地址寫入0012H數據來停止變頻器.
* 由P1.0來控制MCU發(fā)送數據,P2來控制通訊指示燈.*
* 編譯環(huán)境:KEIL V3.30
* 作者:劉元剛
* 部門:中達電通股份有限公司AMD產品處
* 編寫時間:2008.1.8
* 修改時間:
* 修改內容:
**********************************************************/
#include <reg51.h>
char send[17]={0};
char send1[8]={0x01,0x06,0x01,0x00,0x17,0x70,0x86,0x22};
char count;
int temp;
bit motor_flag=0;
/*********ASCII格式變量定義**********/
char number ; //設備站號
char function ; //功能
char address_h; //地址高
char address_l; //地址低
char data_h ; //數據
char data_l ; //數據
char CRC_H; //校驗
char CRC_L; //校驗
char send_temp;
int sum_temp;
/*
函數ASCII()實現了臺達變頻器通訊協議轉換為ASCII協議格式的功能。
*/
void ASCII(void);
/*
init_serial()函數串行通訊初始化函數
實現了:波特率的設定,定時器的選擇,發(fā)送模式的選擇
*/
void init_serial(void);
//函數ASCII7N2()以數據格式 7,N 2方式發(fā)送數據
void ASCII7N2(void);
//函數ASCII7O1()以數據格式 7,O 1方式發(fā)送數據
void ASCII7O1(void);
//函數ASCII7E1()以數據格式 7,E 1方式發(fā)送數據
void ASCII7E1(void);
main()
{
init_serial();
/***********VFD系列變頻器通訊資料初始化*****/
number=0x01;
function=0x06;
address_h=0x20;
address_l=0x00;
data_h=0X00;
data_l=0x12;
/******************************************/
while(1)
{
if(P1!=0XFF)
{
for(temp=0;temp<3000;temp++)//延時一段時間
{;}
if(P1!=0XFF)
{
P2=0;
TI=0;
ASCII();//發(fā)送數據的處理
ASCII7N2();//以通訊協議為ASCII 9600,7,N,2發(fā)送數據
ASCII7O1();//以通訊協議為ASCII 9600,7,O,1發(fā)送數據
ASCII7E1();//以通訊協議為ASCII 9600,7,E,1發(fā)送數據
for(temp=0;temp<10000;temp++)
//發(fā)送完數據之后延時一段時間
{;}
for(temp=0;temp<10000;temp++)
{;}
motor_flag=~motor_flag; //完成了變頻器啟動和停止之間的切換
if(motor_flag==1){data_l=0x11;}
else{data_l=0x12;}
P1=0XFF;
P2=0XFF;
}
}
}
}
/*******************************************************************************
******
函數nop名稱:void init_serial(void)
函數功能:
參數列表:
返回值 :
影響資源:
實現過程:
********************************************************************************
*****/
void init_serial(void)
{
SCON=0x40;//工作在方式1,
TMOD=0x20;
TH1=0xFD; //波特率為9600,晶振11.0592MHZ
TL1=0xFD;
TR1=1; //啟動定時器1
P1=0XFF;
}
void ASCII7N2(void)
{
for(count=0;count<17;count++)
{
SBUF=send[count]|0X80;
while(TI==0);
TI=0;
}
}
void ASCII7O1(void)
{
for(count=0;count<17;count++)
{
temp=0;
ACC=send[count]&0X7F;
send_temp=ACC;
temp=P;
send_temp=(temp<<7)|send_temp;
SBUF=send_temp;
while(TI==0);
TI=0;
}
}
void ASCII7E1(void)
{
for(count=0;count<17;count++)
{
temp=0;
ACC=send[count]&0X7F;
send_temp=ACC;
temp=~P;
send_temp=(temp<<7)|send_temp;
SBUF=send_temp;
while(TI==0);
TI=0;
}
}
/*******************************************************************************
|